8000 98 break by rknizzle · Pull Request #100 · dominikbraun/timetrace · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cli/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@ func statusCommand(t *core.Timetrace) *cobra.Command {
trackedTimeCurrent := defaultString

if report.TrackedTimeCurrent != nil {
trackedTimeCurrent = report.FormatCurrentTime()
trackedTimeCurrent = t.Formatter().FormatCurrentTime(report)
}

rows := [][]string{
{
project,
trackedTimeCurrent,
report.FormatTodayTime(),
t.Formatter().FormatTodayTime(report),
t.Formatter().FormatBreakTime(report),
},
}
out.Table([]string{"Current project", "Worked since start", "Worked today"}, rows, nil)
out.Table([]string{"Current project", "Worked since start", "Worked today", "Breaks"}, rows, nil)
},
}

Expand Down
36 changes: 36 additions & 0 deletions core/formatter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core

import (
"fmt"
"time"
)

Expand Down Expand Up @@ -67,3 +68,38 @@ func (f *Formatter) ParseRecordKey(key string) (time.Time, error) {
func (f *Formatter) RecordKey(record *Record) string {
return record.Start.Format(f.RecordKeyLayout())
}

// FormatTodayTime returns the formated string of the total
// time of today follwoing the format convention
func (f *Formatter) FormatTodayTime(report *Report) string {
return f.formatDuration(report.TrackedTimeToday)
}

// FormatCurrentTime returns the formated string of the current
// report time follwoing the format convention
func (f *Formatter) FormatCurrentTime(report *Report) string {
return f.formatDuration(*report.TrackedTimeCurrent)
}

// FormatBreakTime returns the formated string of the total time
// taking breaks today following the format convention
func (f *Formatter) FormatBreakTime(report *Report) string {
return f.formatDuration(report.BreakTimeToday)
}

// formatDuration formats the passed duration into a string.
// The format will be "8h 24min". If the duration is less then 60 secods
// the format will be "0h 0min 12sec".
func (f *Formatter) formatDuration(duration time.Duration) string {

hours := int64(duration.Hours()) % 60
minutes := int64(duration.Minutes()) % 60
secods := int64(duration.Seconds()) % 60

// as by convention if the duarion is < then 60 secods
// return "0h 0min Xsec"
if hours == 0 && minutes == 0 {
return fmt.Sprintf("0h 0min %dsec", secods)
}
return fmt.Sprintf("%dh %dmin", hours, minutes)
}
25 changes: 25 additions & 0 deletions core/record.go
8000
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,31 @@ func (t *Timetrace) loadAllRecords(date time.Time) ([]*Record, error) {
return records, nil
}

func (t *Timetrace) loadAllRecordsSortedAscending(date time.Time) ([]*Record, error) {
Comment thread
rknizzle marked this conversation as resolved.
Resolved
dir := t.fs.RecordDirFromDate(date)

recordFilepaths, err := t.fs.RecordFilepaths(dir, func(a, b string) bool {
timeA, _ := time.Parse(recordLayout, a)
timeB, _ := time.Parse(recordLayout, b)
return timeA.Before(timeB)
})
if err != nil {
return nil, err
}

var records []*Record

for _, recordFilepath := range recordFilepaths {
record, err := t.loadRecord(recordFilepath)
if err != nil {
return nil, err
}
records = append(records, record)
}

return records, nil
}

// LoadLatestRecord loads the youngest record. This may also be a record from
// another day. If there is no latest record, nil and no error will be returned.
func (t *Timetrace) LoadLatestRecord() (*Record, error) {
Expand Down
52 changes: 22 additions & 30 deletions core/timetrace.go
< 8000 td class="blob-code blob-code-context js-file-line">
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package core

import (
"errors"
"fmt"
"io"
"os"
"time"
Expand All @@ -20,6 +19,7 @@ type Report struct {
Current *Record
TrackedTimeCurrent *time.Duration
TrackedTimeToday time.Duration
BreakTimeToday time.Duration
}

// Filesystem represents a filesystem used for storing and loading resources.
Expand Down Expand Up @@ -111,8 +111,14 @@ func (t *Timetrace) Status() (*Report, error) {
return nil, err
}

breakTimeToday, err := t.breakTime(now)
if err != nil {
return nil, err
}

report := &Report{
TrackedTimeToday: trackedTimeToday,
BreakTimeToday: breakTimeToday,
}

// If the latest record has been stopped, there is no active time tracking.
Expand All @@ -131,6 +137,21 @@ func (t *Timetrace) Status() (*Report, error) {
return report, nil
}

func (t *Timetrace) breakTime(date time.Time) (time.Duration, error) {
records, err := t.loadAllRecordsSortedAscending(date)
if err != nil {
return 0, err
}

// add up the time between records
var breakTime time.Duration
for i := 0; i < len(records)-1; i++ {
breakTime += records[i+1].Start.Sub(*records[i].End)
}

return breakTime, nil
}

// Stop stops the time tracking and marks the current record as ended.
func (t *Timetrace) Stop() error {
latestRecord, err := t.LoadLatestRecord()
Expand Down Expand Up @@ -182,35 +203,6 @@ func (t *Timetrace) trackedTime(date time.Time) (time.Duration, error) {
return trackedTime, nil
}
// FormatTodayTime returns the formated string of the total
// time of today follwoing the format convention
func (report *Report) FormatTodayTime() string {
return formatDuration(report.TrackedTimeToday)
}

// FormatCurrentTime returns the formated string of the current
// report time follwoing the format convention
func (report *Report) FormatCurrentTime() string {
return formatDuration(*report.TrackedTimeCurrent)
}

// formatDuration formats the passed duration into a string.
// The format will be "8h 24min". If the duration is less then 60 secods
// the format will be "0h 0min 12sec".
func formatDuration(duration time.Duration) string {

hours := int64(duration.Hours()) % 60
minutes := int64(duration.Minutes()) % 60
secods := int64(duration.Seconds()) % 60

// as by convention if the duarion is < then 60 secods
// return "0h 0min Xsec"
if hours == 0 && minutes == 0 {
return fmt.Sprintf("0h 0min %dsec", secods)
}
return fmt.Sprintf("%dh %dmin", hours, minutes)
}

func (t *Timetrace) isDirEmpty(dir string) (bool, error) {
openedDir, err := os.Open(dir)
if err != nil {
Expand Down
0