diff --git a/README.md b/README.md index 50776aa..71d335e 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ The following formats are supported as of right now: #### Tyme 3 JSON -It's possible to import JSON exports from [Tyme 3](https://www.tyme-app.com). +It is possible to import JSON exports from [Tyme 3](https://www.tyme-app.com). It is important that the JSON is exported with the following options set/unset: ![Tyme 3 JSON export](documentation/tyme3json.png) @@ -194,3 +194,25 @@ Import a Tyme 3 JSON export: ```sh zeit import --tyme ./tyme.export.json ``` + +### Export tracked activities + +```sh +zeit export --help +``` + +The following formats are supported as of right now: + +#### Tyme 3 JSON + +It is possible to export JSON compatible to the Tyme 3 JSON format. Fields that +are not available in *zeit* will be filled with dummy values, e.g. +`Billing: "UNBILLED"`. + +#### Examples: + +Export a Tyme 3 JSON: + +```sh +zeit export --tyme --project "my project" --since "2020-04-01T15:04:05+07:00" --until "2020-04-04T15:04:05+07:00" +``` diff --git a/z/entry.go b/z/entry.go index 0648e5a..dfb6b45 100644 --- a/z/entry.go +++ b/z/entry.go @@ -153,3 +153,29 @@ func (entry *Entry) GetOutput() (string) { return fmt.Sprintf("%s %s on %s from %s to %s (%sh)", color.FgGray.Render(entry.ID), color.FgLightWhite.Render(entry.Task), color.FgLightWhite.Render(entry.Project), color.FgLightWhite.Render(entry.Begin.Format("2006-01-02 15:04 -0700")), color.FgLightWhite.Render(entry.Finish.Format("2006-01-02 15:04 -0700")), color.FgLightWhite.Render(trackDiffOut.Format("15:04"))) } + +func GetFilteredEntries(entries *[]Entry, project string, task string, since time.Time, until time.Time) ([]*Entry, error) { + var filteredEntries []*Entry + + for _, entry := range *entries { + if project != "" && GetIdFromName(entry.Project) != GetIdFromName(project) { + continue + } + + if task != "" && GetIdFromName(entry.Task) != GetIdFromName(task) { + continue + } + + if since.IsZero() == false && since.Before(entry.Begin) == false && since.Equal(entry.Begin) == false { + continue + } + + if until.IsZero() == false && until.After(entry.Finish) == false && until.Equal(entry.Finish) == false { + continue + } + + filteredEntries = append(filteredEntries, &entry) + } + + return filteredEntries, nil +} diff --git a/z/export.go b/z/export.go index e1df5fc..c5066c3 100644 --- a/z/export.go +++ b/z/export.go @@ -3,11 +3,14 @@ package z import ( "os" "fmt" - // "time" + "time" "github.com/spf13/cobra" ) -func exportTymeJson(user string, entries []Entry) (string, error) { +var exportSince string +var exportUntil string + +func exportTymeJson(user string, entries []*Entry) (string, error) { tyme := Tyme{} err := tyme.FromEntries(entries) @@ -35,9 +38,35 @@ var exportCmd = &cobra.Command{ os.Exit(1) } + var since time.Time + var until time.Time + + if exportSince != "" { + since, err = time.Parse(time.RFC3339, exportSince) + if err != nil { + fmt.Printf("%s %+v\n", CharError, err) + os.Exit(1) + } + } + + if exportUntil != "" { + until, err = time.Parse(time.RFC3339, exportUntil) + if err != nil { + fmt.Printf("%s %+v\n", CharError, err) + os.Exit(1) + } + } + + var filteredEntries []*Entry + filteredEntries, err = GetFilteredEntries(&entries, project, task, since, until) + if err != nil { + fmt.Printf("%s %+v\n", CharError, err) + os.Exit(1) + } + var output string = "" if formatTymeJson == true { - output, err = exportTymeJson(user, entries) + output, err = exportTymeJson(user, filteredEntries) if err != nil { fmt.Printf("%s %+v\n", CharError, err) os.Exit(1) @@ -56,6 +85,10 @@ var exportCmd = &cobra.Command{ func init() { rootCmd.AddCommand(exportCmd) exportCmd.Flags().BoolVar(&formatTymeJson, "tyme", false, "Export to Tyme 3 JSON") + exportCmd.Flags().StringVar(&exportSince, "since", "", "Date/time to start the export from") + exportCmd.Flags().StringVar(&exportUntil, "until", "", "Date/time to export until") + exportCmd.Flags().StringVarP(&project, "project", "p", "", "Project to be exported") + exportCmd.Flags().StringVarP(&task, "task", "t", "", "Task to be exported") var err error database, err = InitDatabase() diff --git a/z/tyme.go b/z/tyme.go index e0881cc..02d359d 100644 --- a/z/tyme.go +++ b/z/tyme.go @@ -5,7 +5,7 @@ import ( // "fmt" "os" "github.com/shopspring/decimal" - // "time" + "time" ) var formatTymeJson bool @@ -50,7 +50,7 @@ func (tyme *Tyme) Load(filename string) error { return nil } -func (tyme *Tyme) FromEntries(entries []Entry) error { +func (tyme *Tyme) FromEntries(entries []*Entry) error { for _, entry := range entries { duration := decimal.NewFromFloat(entry.Finish.Sub(entry.Begin).Minutes())