finish merging

This commit is contained in:
2023-01-30 23:03:08 -08:00
parent 38bc9bcf94
commit aa28e5b264
10 changed files with 49 additions and 197 deletions

View File

@@ -9,13 +9,16 @@ import (
) )
func main() { func main() {
wfreq := []int{} n := time.Now()
yd := time.Now().YearDay()
repoPaths, err := commits.GetMRRepos() repoPaths, err := commits.GetMRRepos()
if err != nil { if err != nil {
panic(err) panic(err)
} }
freq, err := repoPaths.GlobalFrequency(time.Now().Year(), []string{""}) freq, err := repoPaths.Frequency(n.Year(), []string{""})
if err != nil {
panic(err)
}
wfreq, err := repoPaths.GetWeekFreq([]string{""})
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -14,7 +14,7 @@ type Repo git.Repository
func main() { func main() {
year := time.Now().Year() - 1 year := time.Now().Year() - 1
authors := []string{"Groot"} authors := []string{"Groot"}
gfreq, err := commits.GlobalFrequencyChan(year, authors) gfreq, err := commits.FrequencyChan(year, authors)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"net/http" "net/http"
"strconv" "strconv"
"time" "time"
@@ -19,33 +18,14 @@ func main() {
r.HandleFunc("/weekly.svg", func(w http.ResponseWriter, r *http.Request) { r.HandleFunc("/weekly.svg", func(w http.ResponseWriter, r *http.Request) {
author := r.URL.Query().Get("author") author := r.URL.Query().Get("author")
w.Header().Add("Content-Type", "text/html") w.Header().Add("Content-Type", "text/html")
now := time.Now()
year := now.Year()
repoPaths, err := commits.GetMRRepos() repoPaths, err := commits.GetMRRepos()
if err != nil { if err != nil {
panic(err) panic(err)
} }
freq, err := repoPaths.FrequencyChan(year, []string{author}) week, err := repoPaths.GetWeekFreq([]string{author})
if err != nil { if err != nil {
panic(err) panic(err)
} }
today := now.YearDay() - 1
fmt.Println(today)
if today < 6 {
curYear := year - 1
curFreq, err := repoPaths.FrequencyChan(curYear, []string{author})
if err != nil {
panic(err)
}
freq = append(curFreq, freq...)
today += 365
if curYear%4 == 0 {
today++
}
}
fmt.Println(freq)
week := freq[today-6 : today+1]
svg := svg.GetWeekSVG(week) svg := svg.GetWeekSVG(week)
svg.WriteTo(w) svg.WriteTo(w)
}) })

View File

@@ -13,11 +13,11 @@ import (
var ( var (
mapTex sync.RWMutex mapTex sync.RWMutex
hashCache map[int]map[string]map[string]types.ExpYearFreq hashCache map[int]map[string]map[string]types.ExpFreq
) )
func init() { func init() {
hashCache = make(map[int]map[string]map[string]types.ExpYearFreq) hashCache = make(map[int]map[string]map[string]types.ExpFreq)
} }
func hashSlice(in []string) string { func hashSlice(in []string) string {
@@ -32,22 +32,22 @@ func hashSlice(in []string) string {
return fmt.Sprintf("%x\n", b) return fmt.Sprintf("%x\n", b)
} }
func GetCachedGraph(year int, authors []string, repoPaths []string) (types.YearFreq, bool) { func GetCachedGraph(year int, authors []string, repoPaths []string) (types.Freq, bool) {
a := hashSlice(authors) a := hashSlice(authors)
r := hashSlice(repoPaths) r := hashSlice(repoPaths)
mapTex.RLock() mapTex.RLock()
defer mapTex.RUnlock() defer mapTex.RUnlock()
if m1, ok := hashCache[year]; !ok { if m1, ok := hashCache[year]; !ok {
return types.YearFreq{}, false return types.Freq{}, false
} else { } else {
if m2, ok := m1[a]; !ok { if m2, ok := m1[a]; !ok {
return types.YearFreq{}, false return types.Freq{}, false
} else { } else {
if freq, ok := m2[r]; !ok { if freq, ok := m2[r]; !ok {
return types.YearFreq{}, false return types.Freq{}, false
} else { } else {
if freq.Created.Before(time.Now().Add(-15 * time.Minute)) { if freq.Created.Before(time.Now().Add(-15 * time.Minute)) {
return types.YearFreq{}, false return types.Freq{}, false
} else { } else {
return freq.YearFreq, true return freq.YearFreq, true
} }
@@ -56,18 +56,18 @@ func GetCachedGraph(year int, authors []string, repoPaths []string) (types.YearF
} }
} }
func CacheGraph(year int, authors, repoPaths []string, freq types.YearFreq) { func CacheGraph(year int, authors, repoPaths []string, freq types.Freq) {
a := hashSlice(authors) a := hashSlice(authors)
r := hashSlice(repoPaths) r := hashSlice(repoPaths)
mapTex.Lock() mapTex.Lock()
defer mapTex.Unlock() defer mapTex.Unlock()
if _, ok := hashCache[year]; !ok { if _, ok := hashCache[year]; !ok {
hashCache[year] = make(map[string]map[string]types.ExpYearFreq) hashCache[year] = make(map[string]map[string]types.ExpFreq)
} }
if _, ok := hashCache[year][a]; !ok { if _, ok := hashCache[year][a]; !ok {
hashCache[year][a] = make(map[string]types.ExpYearFreq) hashCache[year][a] = make(map[string]types.ExpFreq)
} }
hashCache[year][a][r] = types.ExpYearFreq{YearFreq: freq, Created: time.Now()} hashCache[year][a][r] = types.ExpFreq{YearFreq: freq, Created: time.Now()}
go func() { go func() {
time.Sleep(time.Minute * 15) time.Sleep(time.Minute * 15)
mapTex.Lock() mapTex.Lock()

View File

@@ -8,19 +8,13 @@ import (
"github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/object"
"github.com/taigrr/gico/types" "github.com/taigrr/gico/types"
"github.com/taigrr/mg/parse"
) )
func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) { func (paths RepoSet) FrequencyChan(year int, authors []string) (types.Freq, error) {
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {
yearLength++ yearLength++
} }
mrconf, err := parse.LoadMRConfig()
if err != nil {
return types.YearFreq{}, err
}
paths := mrconf.GetRepoPaths()
cache, ok := GetCachedGraph(year, authors, paths) cache, ok := GetCachedGraph(year, authors, paths)
if ok { if ok {
return cache, nil return cache, nil
@@ -58,6 +52,21 @@ func GlobalFrequencyChan(year int, authors []string) (types.YearFreq, error) {
return freq, nil return freq, nil
} }
func YearFreqFromChan(cc chan types.Commit, year int) types.Freq {
yearLength := 365
if year%4 == 0 {
yearLength++
}
freq := make([]int, yearLength)
for commit := range cc {
if commit.TimeStamp.Year() != year {
continue
}
freq[commit.TimeStamp.YearDay()-1]++
}
return freq
}
func (repo Repo) GetCommitChan() (chan types.Commit, error) { func (repo Repo) GetCommitChan() (chan types.Commit, error) {
cc := make(chan types.Commit, 30) cc := make(chan types.Commit, 30)
r := git.Repository(repo) r := git.Repository(repo)
@@ -81,7 +90,7 @@ func (repo Repo) GetCommitChan() (chan types.Commit, error) {
return cc, nil return cc, nil
} }
func YearFreqFromChan(cc chan types.Commit, year int) types.YearFreq { func FreqFromChan(cc chan types.Commit, year int) types.Freq {
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {
yearLength++ yearLength++

View File

@@ -1,99 +1,15 @@
package commits package commits
import ( import (
"crypto/md5"
"fmt"
"regexp" "regexp"
"sort"
"strings"
"sync"
"time" "time"
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/object"
"github.com/taigrr/gico/types" "github.com/taigrr/gico/types"
"github.com/taigrr/mg/parse"
) )
type Repo git.Repository
type RepoSet []string
var (
mapTex sync.RWMutex
hashCache map[int]map[string]map[string]types.ExpFreq
)
func init() {
hashCache = make(map[int]map[string]map[string]types.ExpFreq)
}
func hashSlice(in []string) string {
sort.Strings(in)
sb := strings.Builder{}
for _, s := range in {
sb.WriteString(s)
}
h := md5.New()
h.Write([]byte(sb.String()))
b := h.Sum(nil)
return fmt.Sprintf("%x\n", b)
}
func GetCachedGraph(year int, authors []string, repoPaths []string) (types.Freq, bool) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.RLock()
defer mapTex.RUnlock()
if m1, ok := hashCache[year]; !ok {
return types.Freq{}, false
} else {
if m2, ok := m1[a]; !ok {
return types.Freq{}, false
} else {
if freq, ok := m2[r]; !ok {
return types.Freq{}, false
} else {
if freq.Created.Before(time.Now().Add(-15 * time.Minute)) {
return types.Freq{}, false
} else {
return freq.YearFreq, true
}
}
}
}
}
func CacheGraph(year int, authors, repoPaths []string, freq types.Freq) {
a := hashSlice(authors)
r := hashSlice(repoPaths)
mapTex.Lock()
defer mapTex.Unlock()
if _, ok := hashCache[year]; !ok {
hashCache[year] = make(map[string]map[string]types.ExpFreq)
}
if _, ok := hashCache[year][a]; !ok {
hashCache[year][a] = make(map[string]types.ExpFreq)
}
hashCache[year][a][r] = types.ExpFreq{YearFreq: freq, Created: time.Now()}
go func() {
time.Sleep(time.Minute * 15)
mapTex.Lock()
defer mapTex.Unlock()
delete(hashCache[year][a], r)
}()
}
func GetMRRepos() (RepoSet, error) {
mrconf, err := parse.LoadMRConfig()
if err != nil {
return RepoSet{}, err
}
paths := mrconf.GetRepoPaths()
return RepoSet(paths), nil
}
func (paths RepoSet) GetWeekFreq(authors []string) (types.Freq, error) { func (paths RepoSet) GetWeekFreq(authors []string) (types.Freq, error) {
now := time.Now() now := time.Now()
year := now.Year() year := now.Year()
@@ -119,64 +35,7 @@ func (paths RepoSet) GetWeekFreq(authors []string) (types.Freq, error) {
return week, nil return week, nil
} }
func (paths RepoSet) FrequencyChan(year int, authors []string) (types.Freq, error) { func (paths RepoSet) Frequency(year int, authors []string) (types.Freq, error) {
yearLength := 365
if year%4 == 0 {
yearLength++
}
cache, ok := GetCachedGraph(year, authors, paths)
if ok {
return cache, nil
}
outChan := make(chan types.Commit, 10)
var wg sync.WaitGroup
for _, p := range paths {
wg.Add(1)
go func(path string) {
repo, err := OpenRepo(path)
if err != nil {
return
}
cc, err := repo.GetCommitChan()
if err != nil {
return
}
cc = FilterCChanByYear(cc, year)
cc, err = FilterCChanByAuthor(cc, authors)
if err != nil {
return
}
for c := range cc {
outChan <- c
}
wg.Done()
}(p)
}
go func() {
wg.Wait()
close(outChan)
}()
freq := YearFreqFromChan(outChan, year)
CacheGraph(year, authors, paths, freq)
return freq, nil
}
func YearFreqFromChan(cc chan types.Commit, year int) types.Freq {
yearLength := 365
if year%4 == 0 {
yearLength++
}
freq := make([]int, yearLength)
for commit := range cc {
if commit.TimeStamp.Year() != year {
continue
}
freq[commit.TimeStamp.YearDay()-1]++
}
return freq
}
func (paths RepoSet) GlobalFrequency(year int, authors []string) (types.Freq, error) {
yearLength := 365 yearLength := 365
if year%4 == 0 { if year%4 == 0 {
yearLength++ yearLength++

View File

@@ -16,6 +16,7 @@ type (
Commits []types.Commit Commits []types.Commit
Year int Year int
} }
RepoSet []string
) )
func OpenRepo(directory string) (Repo, error) { func OpenRepo(directory string) (Repo, error) {

View File

@@ -54,10 +54,10 @@ func GetYearSVG(frequencies []int) bytes.Buffer {
for _, f := range frequencies { for _, f := range frequencies {
squareColors = append(squareColors, common.ColorForFrequency(f, min, max)) squareColors = append(squareColors, common.ColorForFrequency(f, min, max))
} }
return drawYearImage(squareColors) return drawYearImage(squareColors, frequencies)
} }
func drawYearImage(c []sc.SimpleColor) bytes.Buffer { func drawYearImage(c []sc.SimpleColor, freq []int) bytes.Buffer {
var sb bytes.Buffer var sb bytes.Buffer
sbw := bufio.NewWriter(&sb) sbw := bufio.NewWriter(&sb)
squareLength := 10 squareLength := 10
@@ -66,7 +66,7 @@ func drawYearImage(c []sc.SimpleColor) bytes.Buffer {
canvas := svg.New(sbw) canvas := svg.New(sbw)
canvas.Start(width, height) canvas.Start(width, height)
for i, s := range c { for i, s := range c {
canvas.Square(2*squareLength+width/(len(c)/7+1)*(i/7)+squareLength*2, squareLength/2+height/7*(i%7), squareLength, fmt.Sprintf("fill:%s", s.ToHex())) canvas.Square(2*squareLength+width/(len(c)/7+1)*(i/7)+squareLength*2, squareLength/2+height/7*(i%7), squareLength, fmt.Sprintf("fill:%s; value:%d", s.ToHex(), freq[i]))
} }
// canvas.Text(2*squareLength, squareLength*3, "Mon", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength)) // canvas.Text(2*squareLength, squareLength*3, "Mon", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength))
// canvas.Text(2*squareLength, int(float64(squareLength)*6.5), "Wed", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength)) // canvas.Text(2*squareLength, int(float64(squareLength)*6.5), "Wed", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength))

View File

@@ -55,14 +55,14 @@ func drawYearUnicode(c []sc.SimpleColor) string {
// o := termenv.NewOutput(os.Stdout) // o := termenv.NewOutput(os.Stdout)
var s strings.Builder var s strings.Builder
o := termenv.NewOutputWithProfile(os.Stdout, termenv.TrueColor) o := termenv.NewOutputWithProfile(os.Stdout, termenv.TrueColor)
weeks := [7][]sc.SimpleColor{{}} weekRows := [7][]sc.SimpleColor{{}}
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
weeks[i] = []sc.SimpleColor{} weekRows[i] = []sc.SimpleColor{}
} }
for i := range c { for i := 0; i < len(c); i++ {
weeks[i%7] = append(weeks[i%7], c[i]) weekRows[i%7] = append(weekRows[i%7], c[i])
} }
for _, row := range weeks { for _, row := range weekRows {
for w, d := range row { for w, d := range row {
style := o.String(block).Foreground(termenv.TrueColor.Color(d.ToHex())) style := o.String(block).Foreground(termenv.TrueColor.Color(d.ToHex()))
s.WriteString(style.String()) s.WriteString(style.String())

View File

@@ -18,17 +18,17 @@ func NewCommit(Author, Message, Repo, Path string, LOC int) Commit {
} }
} }
func (yf YearFreq) String() string { func (yf Freq) String() string {
return gterm.GetYearUnicode(yf) return gterm.GetYearUnicode(yf)
} }
func (a YearFreq) Merge(b YearFreq) YearFreq { func (a Freq) Merge(b Freq) Freq {
x := len(a) x := len(a)
y := len(b) y := len(b)
if x < y { if x < y {
x = y x = y
} }
c := make(YearFreq, x) c := make(Freq, x)
copy(c, a) copy(c, a)
for i := 0; i < y; i++ { for i := 0; i < y; i++ {
c[i] += b[i] c[i] += b[i]