<commit_before>package main

import (
	"fmt"
	"sort"
	"time"

	"github.com/funkygao/golib/bjtime"
	"github.com/funkygao/termui"
	"github.com/mattn/go-runewidth"
	"github.com/nsf/termbox-go"
	"github.com/pmylund/sortutil"
)

var (
	w, h               int
	page               int
	pageSize           int
	selectedRow        = 0
	selectedCommit     = 0
	currentWebHook     *Webhook
	detailView         = false
	dashboardView      = false
	userSummaryView    = false
	projectSummaryView = false
)

const (
	coldef = termbox.ColorDefault
)

func refreshSize() {
	w, h = termbox.Size()
	pageSize = h - 1 // footer=1
}

func redrawAll() {
	termbox.Clear(coldef, coldef)
	refreshSize()

	x, y := 0, 0
	lock.Lock()
	evts := reorderEvents()
	for i := page * pageSize; i < len(evts) && i < (page+1)*pageSize; i++ {
		evt := evts[i]
		drawEvent(x, y, evt)
		y++
	}

	drawFooter()
	lock.Unlock()

	termbox.Flush()
}

func drawDashboardByUser() {
	lock.Lock()
	commitByUsers := make(map[string]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			for _, c := range hook.Commits {
				if _, present := commitByUsers[c.Author.Email]; !present {
					commitByUsers[c.Author.Email] = 1
				} else {
					commitByUsers[c.Author.Email] += 1
				}
			}
		}
	}
	lock.Unlock()

	type user struct {
		name    string
		commits int
	}
	users := make([]user, 0, len(commitByUsers))
	for name, n := range commitByUsers {
		users = append(users, user{name: name, commits: n})
	}
	sortutil.DescByField(users, "commits")

	termbox.Clear(coldef, coldef)
	y := 0
	for _, p := range users {
		row := fmt.Sprintf("%40s: %3d", p.name, p.commits)
		drawRow(row, y, coldef, coldef)
		y++
	}

	termbox.Flush()
}

func drawDashboardByProject() {
	lock.Lock()
	commitByProjects := make(map[string]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			if _, present := commitByProjects[hook.Repository.Homepage]; !present {
				commitByProjects[hook.Repository.Homepage] = hook.Total_commits_count
			} else {
				commitByProjects[hook.Repository.Homepage] += hook.Total_commits_count
			}
		}
	}
	lock.Unlock()

	type project struct {
		name    string
		commits int
	}
	projects := make([]project, 0, len(commitByProjects))
	for name, n := range commitByProjects {
		projects = append(projects, project{name: name, commits: n})
	}
	sortutil.DescByField(projects, "commits")

	termbox.Clear(coldef, coldef)
	y := 0
	for _, p := range projects {
		row := fmt.Sprintf("%80s: %3d", p.name, p.commits)
		drawRow(row, y, coldef, coldef)
		y++
	}

	termbox.Flush()
}

func drawDashboardByHour() {
	lock.Lock()
	commitByHours := make(map[int]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			for _, cmt := range hook.Commits {
				t, _ := time.Parse(time.RFC3339, cmt.Timestamp)
				if _, present := commitByHours[t.Hour()]; present {
					commitByHours[t.Hour()]++
				} else {
					commitByHours[t.Hour()] = 1
				}
			}
		}
	}
	lock.Unlock()

	sortedHours := make([]int, 0, len(commitByHours))
	for hour, _ := range commitByHours {
		sortedHours = append(sortedHours, hour)
	}
	sort.Ints(sortedHours)

	termbox.Clear(coldef, coldef)<commit_msg>display both username and email<commit_after>package main

import (
	"fmt"
	"sort"
	"time"

	"github.com/funkygao/golib/bjtime"
	"github.com/funkygao/termui"
	"github.com/mattn/go-runewidth"
	"github.com/nsf/termbox-go"
	"github.com/pmylund/sortutil"
)

var (
	w, h               int
	page               int
	pageSize           int
	selectedRow        = 0
	selectedCommit     = 0
	currentWebHook     *Webhook
	mainView           bool
	detailView         = false
	dashboardView      = false
	userSummaryView    = false
	projectSummaryView = false
)

const (
	coldef = termbox.ColorDefault
)

func refreshSize() {
	w, h = termbox.Size()
	pageSize = h - 1 // footer=1
}

func redrawAll() {
	mainView = true

	termbox.Clear(coldef, coldef)
	refreshSize()

	x, y := 0, 0
	lock.Lock()
	evts := reorderEvents()
	for i := page * pageSize; i < len(evts) && i < (page+1)*pageSize; i++ {
		evt := evts[i]
		drawEvent(x, y, evt)
		y++
	}

	drawFooter()
	lock.Unlock()

	termbox.Flush()
}

func drawDashboardByUser() {
	lock.Lock()
	commitByUsers := make(map[string]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			for _, c := range hook.Commits {
				key := fmt.Sprintf("%s %s", c.Author.Name, c.Author.Email)
				if _, present := commitByUsers[key]; !present {
					commitByUsers[key] = 1
				} else {
					commitByUsers[key] += 1
				}
			}
		}
	}
	lock.Unlock()

	type user struct {
		name    string
		commits int
	}
	users := make([]user, 0, len(commitByUsers))
	for name, n := range commitByUsers {
		users = append(users, user{name: name, commits: n})
	}
	sortutil.DescByField(users, "commits")

	termbox.Clear(coldef, coldef)
	y := 0
	for i, u := range users {
		row := fmt.Sprintf("%s: %5d", wideStr(u.name, 60), u.commits)
		drawRow(row, y, coldef, coldef)
		y++

		if i >= h {
			break
		}
	}

	termbox.Flush()
}

func drawDashboardByProject() {
	lock.Lock()
	commitByProjects := make(map[string]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			if _, present := commitByProjects[hook.Repository.Homepage]; !present {
				commitByProjects[hook.Repository.Homepage] = hook.Total_commits_count
			} else {
				commitByProjects[hook.Repository.Homepage] += hook.Total_commits_count
			}
		}
	}
	lock.Unlock()

	type project struct {
		name    string
		commits int
	}
	projects := make([]project, 0, len(commitByProjects))
	for name, n := range commitByProjects {
		projects = append(projects, project{name: name, commits: n})
	}
	sortutil.DescByField(projects, "commits")

	termbox.Clear(coldef, coldef)
	y := 0
	for i, p := range projects {
		row := fmt.Sprintf("%80s: %5d", p.name, p.commits)
		drawRow(row, y, coldef, coldef)
		y++

		if i >= h {
			break
		}
	}

	termbox.Flush()
}

func drawDashboardByHour() {
	lock.Lock()
	commitByHours := make(map[int]int)
	for _, evt := range events {
		if hook, ok := evt.(*Webhook); ok {
			for _, cmt := range hook.Commits {
				t, _ := time.Parse(time.RFC3339, cmt.Timestamp)
				if _, present := commitByHours[t.Hour()]; present {
					commitByHours[t.Hour()]++
				} else {
					commitByHours[t.Hour()] = 1
				}
			}
		}
	}
	lock.Unlock()

	sortedHours := make([]int, 0, len(commitByHours))
	for hour, _ := range commitByHours {
		sortedHours = append(sortedHours, hour)
	}
	sort.Ints(sortedHours)

	termbox.Clear(coldef, coldef)
{'fraction_non_alphanumeric': 0.14916871921182265, 'fraction_numerical': 0.00769704433497537, 'mean_word_length': 3.199741435035553, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4123475', 'n_tokens_mistral': 2730, 'n_tokens_neox': 2517, 'n_words': 537}