229 lines
4.8 KiB
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
|
|
}
|