github.com/developest/gtm-core@v1.0.4-0.20220111132249-cc80a3372c3f/report/timeline.go (about)

     1  // Copyright 2016 Michael Schenk. All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package report
     6  
     7  import (
     8  	"sort"
     9  	"strconv"
    10  	"time"
    11  
    12  	"github.com/DEVELOPEST/gtm-core/util"
    13  )
    14  
    15  type timelineCommitEntries []timelineCommitEntry
    16  
    17  type timelineCommitEntry struct {
    18  	Day     string
    19  	Total   int
    20  	Commits [24]int
    21  }
    22  
    23  func (t *timelineCommitEntry) inc(hour int) {
    24  	t.Total++
    25  	t.Commits[hour]++
    26  }
    27  
    28  func (t timelineCommitEntries) HourMaxCommits() int {
    29  	max := 0
    30  	for _, entry := range t {
    31  		for _, commits := range entry.Commits {
    32  			if commits > max {
    33  				max = commits
    34  			}
    35  		}
    36  	}
    37  	return max
    38  }
    39  
    40  func (t timelineCommitEntries) Total() int {
    41  	total := 0
    42  	for _, e := range t {
    43  		total += e.Total
    44  	}
    45  	return total
    46  }
    47  
    48  func (c commitNoteDetails) timelineCommits() (timelineCommitEntries, error) {
    49  	timelineMap := map[string]timelineCommitEntry{}
    50  	timeline := []timelineCommitEntry{}
    51  	for _, n := range c {
    52  		t := n.When
    53  		day := t.Format("2006-01-02")
    54  		hour, err := strconv.Atoi(t.Format("15"))
    55  		if err != nil {
    56  			return timelineCommitEntries{}, err
    57  		}
    58  		if entry, ok := timelineMap[day]; !ok {
    59  			var commits [24]int
    60  			commits[hour] = 1
    61  			timelineMap[day] = timelineCommitEntry{Day: t.Format("Mon Jan 02"), Commits: commits, Total: 1}
    62  		} else {
    63  			entry.inc(hour)
    64  			timelineMap[day] = entry
    65  		}
    66  	}
    67  
    68  	keys := make([]string, 0, len(timelineMap))
    69  	for key := range timelineMap {
    70  		keys = append(keys, key)
    71  	}
    72  	sort.Sort(sort.StringSlice(keys))
    73  	for _, k := range keys {
    74  		timeline = append(timeline, timelineMap[k])
    75  	}
    76  
    77  	return timeline, nil
    78  }
    79  
    80  func (c commitNoteDetails) timeline() (timelineEntries, error) {
    81  	timelineMap := map[string]timelineEntry{}
    82  	timeline := []timelineEntry{}
    83  	for _, n := range c {
    84  		for _, f := range n.Note.Files {
    85  			for epoch, secs := range f.Timeline {
    86  				t := time.Unix(epoch, 0)
    87  				day := t.Format("2006-01-02")
    88  				hour, err := strconv.Atoi(t.Format("15"))
    89  				if err != nil {
    90  					return timelineEntries{}, err
    91  				}
    92  				if entry, ok := timelineMap[day]; !ok {
    93  					var hours [24]int
    94  					hours[hour] = secs
    95  					timelineMap[day] = timelineEntry{Day: t.Format("Mon Jan 02"), Hours: hours, Seconds: secs}
    96  				} else {
    97  					entry.add(secs, hour)
    98  					timelineMap[day] = entry
    99  				}
   100  			}
   101  		}
   102  	}
   103  
   104  	keys := make([]string, 0, len(timelineMap))
   105  	for key := range timelineMap {
   106  		keys = append(keys, key)
   107  	}
   108  	sort.Sort(sort.StringSlice(keys))
   109  	for _, k := range keys {
   110  		timeline = append(timeline, timelineMap[k])
   111  	}
   112  
   113  	return timeline, nil
   114  }
   115  
   116  type timelineEntries []timelineEntry
   117  
   118  func (t timelineEntries) Duration() string {
   119  	total := 0
   120  	for _, entry := range t {
   121  		total += entry.Seconds
   122  	}
   123  	return util.FormatDuration(total)
   124  }
   125  
   126  func (t timelineEntries) HourMaxSeconds() int {
   127  	// Default to number of seconds in a hour
   128  	// Actual max can be much higher when reporting
   129  	// across multiple projects and users
   130  	max := 3600
   131  	for _, entry := range t {
   132  		for _, secs := range entry.Hours {
   133  			if secs > max {
   134  				max = secs
   135  			}
   136  		}
   137  	}
   138  	return max
   139  }
   140  
   141  type timelineEntry struct {
   142  	Day     string
   143  	Seconds int
   144  	Hours   [24]int
   145  }
   146  
   147  func (t *timelineEntry) add(s int, hour int) {
   148  	t.Seconds += s
   149  	t.Hours[hour] += s
   150  }
   151  
   152  func (t *timelineEntry) Duration() string {
   153  	return util.FormatDuration(t.Seconds)
   154  }