tt

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2023 License: Apache-2.0 Imports: 15 Imported by: 0

README

tt

Go Reference Go Report Card

tt is a cli application that can be used to track time. This README will be expanded when I have more time.

Configuration

The environment variable TT_HOME_DIR specifies where the application should look for a configuration file and store any information it collects. If TT_HOME_DIR is not set $HOME/.tt is used. If a file named config.json is present in the directory the config is read from it, otherwise defaults are used.

Installation

We are currently lacking automated tests therefore install this application is at your own risk. To get the most recent version (that is somewhat manually tested) set a valid version instead of latest, i.e. v0.1.1.

$ go install moehl.dev/tt/tt@latest

If you already installed a version, you can check with the --version flag which version you have installed.

$ tt --version
tt version v0.1.1

Usage

Documentation is available as part of the cli. Only calling tt prints out a help section from which you can explore the different commands.

Integrations

SwiftBar

tt can be run from SwiftBar. A flexible example is provided in swiftbar.sh and a more static one on swiftbar-static.sh. See the comments in each script for details.

Documentation

Index

Constants

View Source
const (
	FieldStart   = "start"
	FieldProject = "project"
	FieldTask    = "task"
	FieldDay     = "day"

	OrderAsc Order = "ASC"
	OrderDsc Order = "DESC"
)
View Source
const (
	DateFormat = "2006-01-02"
)
View Source
const (
	// HomeDirEnv stores the name of the environment variable that contains the
	// path to the home directory of this cli.
	HomeDirEnv = "TT_HOME_DIR"
)
View Source
const TimeFormat = "2006-01-02 15:04"

Variables

View Source
var (
	ErrInvalidData = fmt.Errorf("invalid data")
	// ErrInternal indicates an error with the database
	ErrInternal              = fmt.Errorf("internal error")
	ErrNotFound              = fmt.Errorf("not found")
	ErrInvalidFormat         = fmt.Errorf("invalid format")
	ErrNotImplemented        = fmt.Errorf("not implemented")
	ErrInvalidTimer          = fmt.Errorf("invalid timer")
	ErrInvalidParameter      = fmt.Errorf("invalid parameter supplied")
	ErrInvalidParameters     = fmt.Errorf("invalid parameters supplied")
	ErrOperationNotPermitted = fmt.Errorf("operation not permitted")
)
View Source
var EmptyDbFilter emptyDbFilter
View Source
var EmptyFilter *filter

Functions

func FormatDuration

func FormatDuration(d time.Duration) string

FormatDuration formats a duration in the given precision specified by the config.

func FormatDurationCustom

func FormatDurationCustom(d time.Duration, precision time.Duration) string

func IsWorkDay

func IsWorkDay(d time.Time) bool

IsWorkDay checks if the day should have been worked on. It does not take into account vacation days, but only the configured weekdays.

func LoadConfig

func LoadConfig() error

LoadConfig allows to manually load the configuration file.

func ParseDate

func ParseDate(in string) (time.Time, error)

func ParseDayString

func ParseDayString(dayStr string) (time.Time, error)

ParseDayString parses the given day string and expects the format YYYY-MM-DD. The returned time is always in timezone UTC to avoid daylight-saving-time issues when adding/subtracting days.

func ParseTime

func ParseTime(in string) (time.Time, error)

ParseTime will take in a string that contains a time in some format and try to guess the missing parts. Currently, the following cases are supported: - 15:04 - 15:04:05 - 2006/01/02 15:04 - 2006/01/02 15:04:05 valid date separators: dash, dot, slash valid time separators: colon valid separators between date and time: space, upper-case t

more general information will be taken from time.Now() (e.g. day or year) and more specific information (e.g. seconds) will be set to zero.

func PlannedTime

func PlannedTime(date time.Time) (time.Duration, error)

PlannedTime returns the duration that was planned for the given date.

Types

type Config

type Config struct {
	// Precision sets how precise the stats should be evaluated. Available
	// values are: [s second m minute h hour]
	// Default: second
	Precision string `json:"precision"`
	AutoStop  bool   `json:"autoStop"`
	// RoundStartTime will take the start time and round by the factor given.
	// Example:
	//   60s: 13:45:23 -> 13:45:00
	//   60s: 09:01:59 -> 09:02:00
	//   5m : 23:32:29 -> 23:30:00
	// Refer to time.Time.Round on how it works
	RoundStartTime string `json:"roundStartTime"`
	Timeclock      struct {
		HoursPerDay int `json:"hoursPerDay"`
		DaysPerWeek struct {
			Monday    bool `json:"monday"`
			Tuesday   bool `json:"tuesday"`
			Wednesday bool `json:"wednesday"`
			Thursday  bool `json:"thursday"`
			Friday    bool `json:"friday"`
			Saturday  bool `json:"saturday"`
			Sunday    bool `json:"sunday"`
		} `json:"daysPerWeek"`
	} `json:"timeclock"`
}

Config holds all available configuration values.

func GetConfig

func GetConfig() Config

GetConfig returns the current Config and lazy loads it if necessary.

func (Config) DBFile

func (c Config) DBFile() string

func (Config) GetPrecision

func (c Config) GetPrecision() time.Duration

GetPrecision returns the precision as a duration.

func (Config) GetRoundStartTime

func (c Config) GetRoundStartTime() time.Duration

func (Config) HomeDir

func (Config) HomeDir() string

HomeDir returns the path to the directory that contains storage and configuration files.

func (Config) Validate

func (c Config) Validate() error

type DB

type DB interface {
	// SaveTimer will write a single timer to the database.
	SaveTimer(Timer) error
	// GetTimer reads a single timer from the database by appending `LIMIT 1` to
	// the query. Will return ErrNotFound if no timer matching the filter exists.
	GetTimer(Filter, OrderBy, *Timer) error
	GetTimerById(string, *Timer) error
	// GetTimers returns multiple timers from the database that match the filter.
	// Will never return ErrNotFound but rather just an empty list.
	GetTimers(Filter, OrderBy, *Timers) error
	// UpdateTimer updates existing timers in the db based on the id. If the timer
	// does not exist an ErrNotFound is returned.
	UpdateTimer(Timer) error
	// RemoveTimer removes the timer from the database.
	RemoveTimer(string) error

	SaveVacationDay(VacationDay) error
	GetVacationDay(VacationFilter, *VacationDay) error
	GetVacationDays(OrderBy, *[]VacationDay) error
	RemoveVacationDay(string) error
}

func GetDB

func GetDB() DB

func NewSQLite

func NewSQLite(dbFile string) (DB, error)

NewSQLite creates and initializes a new SQLite storage interface. The connection is tested using DB.Ping() and the needed tables are created if they do not exist.

type DatabaseFilter

type DatabaseFilter interface {
	SQL() string
}

type Day

type Day struct {
	Time     time.Time
	Timers   Timers
	Vacation *VacationDay
}

func (Day) String

func (d Day) String() string

type Filter

type Filter interface {
	DatabaseFilter
	Match(Timer) bool
	Timers(Timers) Timers
}

func NewFilter

func NewFilter(projects, tasks, tags []string, since, until time.Time) Filter

NewFilter allows to create a filter that is not parsed from a filter string.

func ParseFilterString

func ParseFilterString(filterString string) (Filter, error)

ParseFilterString takes a string and creates a filter from it. The filter string has to be in the following format:

filterName=values;filterName=values;...

each filterName consists of a string, values contains the filter value. Some filters only accept a single value, others accept multiple values separated by commas.

Example:

project=work,school;since=2020-01-01;until=2020-02-01

Available filters are:

project: accepts multiple string values
task   : accepts multiple string values
since  : accepts a single string int the format of yyyy-MM-dd
until  : accepts a single string int the format of yyyy-MM-dd
tags   : accepts multiple string values

since and until are inclusive, both dates will be included in filtered data.

type GroupByOption

type GroupByOption string

type Month

type Month struct {
	// Days contains the days of the month but starts at 0
	Days []Day
}

func (Month) String

func (m Month) String() string

type Order

type Order string

type OrderBy

type OrderBy struct {
	Field string
	Order Order
}

func (OrderBy) SQL

func (o OrderBy) SQL() string

type Timer

type Timer struct {
	ID      string     `json:"id" validate:"required,uuid4"`
	Start   time.Time  `json:"start" validate:"required"`
	Stop    *time.Time `json:"stop,omitempty" validate:"omitempty,gtfield=Start"`
	Project string     `json:"project" validate:"required"`
	Task    string     `json:"task,omitempty"`
	Tags    []string   `json:"tags,omitempty"`
}

Timer is the central type that stores a timer and all its relevant values.

func Start

func Start(project, task string, tags []string, timestamp time.Time, copy int) (Timer, error)

func Stop

func Stop(timestamp time.Time) (Timer, error)

func (Timer) Duration

func (t Timer) Duration() time.Duration

Duration returns the duration that the timer has been running. If the timer is still running it will return the time it has run until now.

func (Timer) Running

func (t Timer) Running() bool

Running indicates whether the timer is still running.

func (Timer) String

func (t Timer) String() string

func (Timer) Validate

func (t Timer) Validate() error

type Timers

type Timers []Timer

Timers stores a list of timers to attach functions to it.

func List

func List(filter Filter, orderBy OrderBy) (Timers, error)

func (Timers) CSV

func (timers Timers) CSV() (string, error)

CSV exports all timers as a csv string

func (Timers) Duration

func (timers Timers) Duration() (d time.Duration)

func (Timers) GroupByDay

func (timers Timers) GroupByDay() map[string]Timers

func (Timers) GroupByProject

func (timers Timers) GroupByProject() map[string]Timers

func (Timers) GroupByTask

func (timers Timers) GroupByTask() map[string]map[string]Timers

GroupByTask groups all timers by project and task.

type VacationDay

type VacationDay struct {
	ID   string    `json:"id"`
	Day  time.Time `json:"day"`
	Half bool      `json:"half"`
}

func (VacationDay) String

func (v VacationDay) String() string

type VacationFilter

type VacationFilter time.Time

func (VacationFilter) SQL

func (f VacationFilter) SQL() string

type Year

type Year struct {
	Year   int
	Months [12]Month
}

func BuildCalendar

func BuildCalendar() ([]Year, error)

func (Year) String

func (y Year) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL