gime-flat/timer.go

229 lines
4.8 KiB
Go

package main
import (
"time"
"github.com/pborman/uuid"
)
type Timer struct {
Uuid string `json:"uuid"`
Start time.Time `json:"start"`
End time.Time `json:"end"`
Tags []string `json:"tags"`
Notes string `json:"notes"`
Billed bool `json:"billed"`
}
// NewTimer returns a new timer with the given start and end
func NewTimer(st, end time.Time) *Timer {
ret := Timer{
Uuid: uuid.New(),
Start: st,
End: end,
}
return &ret
}
// GetUUID returns the uuid of the timer
func (t *Timer) GetUUID() string {
return t.Uuid
}
// GetStart returns the start time of the timer
func (t *Timer) GetStart() time.Time {
return t.Start
}
// SetStart sets the starting time of the timer
func (t *Timer) SetStart(st time.Time) {
t.Start = st
}
// GetEnd returns the end time of the timer
func (t *Timer) GetEnd() time.Time {
return t.End
}
// SetEnd sets the ending time of the timer
func (t *Timer) SetEnd(end time.Time) {
t.End = end
}
// IsActive returns if the timer is still active
func (t *Timer) IsActive() bool {
return time.Now().After(t.Start) && t.End.IsZero()
}
// SetTags sets the timer's tags
func (t *Timer) SetTags(tags []string) {
t.Tags = tags
}
// GetTags returns all of the tags for the timer
func (t *Timer) GetTags() []string {
return t.Tags
}
// AddTag adds the given tag to the timer
func (t *Timer) AddTag(tg string) {
for _, v := range t.Tags {
if v == tg {
return
}
}
t.Tags = append(t.Tags, tg)
}
// HasTag returns if the timer has the given tag
func (t *Timer) HasTag(s string) bool {
for _, v := range t.Tags {
if v == s {
return true
}
}
return false
}
// RemoveTag will remove the given tag from the timer
func (t *Timer) RemoveTag(tg string) {
var tgs []string
for _, v := range t.Tags {
if v != tg {
tgs = append(tgs, v)
}
}
t.Tags = tgs
}
// SetNotes sets the timer's notes to the given string
func (t *Timer) SetNotes(nt string) {
t.Notes = nt
}
// StartsToday returns if the timer's end time is today
func (t *Timer) StartsToday() bool {
currTime := time.Now()
dur := int64(currTime.Hour())*int64(time.Hour) + int64(currTime.Minute())*int64(time.Minute)
return int64(time.Since(t.GetStart())) < dur
}
// EndsToday returns if the timer's end time is today
func (t *Timer) EndsToday() bool {
currTime := time.Now()
dur := int64(currTime.Hour())*int64(time.Hour) + int64(currTime.Minute())*int64(time.Minute)
return int64(time.Since(t.GetEnd())) < dur
}
// IsRunning returns if the timer is still running
func (t *Timer) IsRunning() bool {
return t.GetEnd().IsZero()
}
// IsBillable checks if any of the tags on the timer are flagged as billable
func (t *Timer) IsBillable() bool {
m, err := LoadMetadata()
if err != nil {
return false
}
for _, v := range m.GetTags(t.Tags) {
if v.Billable {
return true
}
}
return false
}
// String formats a string of the time entry
func (t *Timer) String() string {
var ret string
ret = t.GetStart().Format(time.RFC3339)
if !t.GetEnd().IsZero() {
ret += " - " + t.GetEnd().Format(time.RFC3339)
}
if len(t.GetTags()) > 0 {
ret += " [ "
for _, v := range t.GetTags() {
ret += v + " "
}
ret += "]"
}
if t.GetEnd().IsZero() {
ret += " Running"
}
return ret
}
func (t *Timer) FriendlyString() string {
var ret string
var end string
if t.StartsToday() {
ret = t.GetStart().Format("15:04 - ")
end = "**:**"
} else {
ret = t.GetStart().Format("2006/01/02 15:04:05 - ")
end = "**:**:**"
}
if !t.GetEnd().IsZero() {
if t.EndsToday() {
end = t.GetEnd().Format("15:04")
} else {
end = t.GetEnd().Format("2006/01/02 15:04:05")
}
}
ret += end
if len(t.GetTags()) > 0 {
ret += " [ "
for _, v := range t.GetTags() {
ret += v + " "
}
ret += "]"
}
return ret
}
func (t *Timer) InferDetailString() string {
diffEnd := time.Now()
if !t.GetEnd().IsZero() {
diffEnd = t.GetEnd()
}
if int(diffEnd.Sub(t.GetStart())) >= (int(time.Hour) * diffEnd.Hour()) {
return t.LongDetailString()
}
return t.DetailString()
}
func (t *Timer) DetailString() string {
ret := t.GetStart().Format("15:04") + " - "
if t.GetEnd().IsZero() {
ret += "**:** (" + padLeft(sinceToString(t.GetStart()), len("00h 00m 00s")) + ") "
} else {
ret += t.GetEnd().Format("15:04") + " (" + padLeft(diffToString(t.GetStart(), t.GetEnd()), len("00h 00m 00s")) + ") "
}
if len(t.GetTags()) > 0 {
ret += " [ "
for _, v := range t.GetTags() {
ret += v + " "
}
ret += "] "
}
return ret
}
func (t *Timer) LongDetailString() string {
ret := t.GetStart().Format(time.Stamp)
if t.GetEnd().IsZero() {
ret += " (" + padLeft(sinceToString(t.GetStart()), len("0000y 00m 00d 00h 00m 00s")) + ") "
} else {
ret += " (" + padLeft(diffToString(t.GetStart(), t.GetEnd()), len("0000y 00m 00d 00h 00m 00s")) + ") "
}
if len(t.GetTags()) > 0 {
ret += " [ "
for _, v := range t.GetTags() {
ret += v + " "
}
ret += "] "
}
return ret
}