mirror of
https://github.com/arnaucube/wtt.git
synced 2026-02-28 05:56:40 +01:00
working: new, start, stop, list
This commit is contained in:
23
README.md
23
README.md
@@ -1,2 +1,25 @@
|
|||||||
# wtt
|
# wtt
|
||||||
Work Time Tracker - console time tracking app
|
Work Time Tracker - console time tracking app
|
||||||
|
|
||||||
|
|
||||||
|
### Use
|
||||||
|
Create new project
|
||||||
|
```
|
||||||
|
./wtt new ProjectName
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Start working on a project
|
||||||
|
```
|
||||||
|
./wtt start ProjectName
|
||||||
|
```
|
||||||
|
|
||||||
|
Stop working on the current project
|
||||||
|
```
|
||||||
|
./wtt stop
|
||||||
|
```
|
||||||
|
|
||||||
|
List projects
|
||||||
|
```
|
||||||
|
./wtt list
|
||||||
|
```
|
||||||
|
|||||||
9
errors.go
Executable file
9
errors.go
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
func check(err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
97
main.go
Normal file
97
main.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
var directoryPath string
|
||||||
|
var filePath string
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
usr, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
directoryPath = usr.HomeDir + "/.wtt"
|
||||||
|
filePath = directoryPath + "/work.json"
|
||||||
|
readProjects()
|
||||||
|
|
||||||
|
//get the command line parameters
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
switch os.Args[1] {
|
||||||
|
case "new":
|
||||||
|
//create project os.Args[2]
|
||||||
|
if len(os.Args) > 2 {
|
||||||
|
projectName := os.Args[2]
|
||||||
|
color.Green("creating new project: " + projectName)
|
||||||
|
err := newProject(projectName)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
saveWork()
|
||||||
|
} else {
|
||||||
|
color.Red("No project name specified")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "list":
|
||||||
|
//list projects
|
||||||
|
listProjects()
|
||||||
|
break
|
||||||
|
case "start":
|
||||||
|
//check if already there is any project started
|
||||||
|
if work.CurrentProjectName != "" {
|
||||||
|
color.Red("Can not start project, already project " + work.CurrentProjectName + " running")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
//start project os.Args[2]
|
||||||
|
if len(os.Args) > 2 {
|
||||||
|
projectName := os.Args[2]
|
||||||
|
i := getProjectIByName(projectName)
|
||||||
|
if i < 0 {
|
||||||
|
color.Red("Project name: " + projectName + ", no exists")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var newStreak Streak
|
||||||
|
newStreak.Start = time.Now()
|
||||||
|
work.Projects[i].Streaks = append(work.Projects[i].Streaks, newStreak)
|
||||||
|
work.CurrentProjectName = projectName
|
||||||
|
saveWork()
|
||||||
|
fmt.Println("starting to work in project " + work.Projects[i].Name)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "stop":
|
||||||
|
if work.CurrentProjectName == "" {
|
||||||
|
color.Red("no project started to stop")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i := getProjectIByName(work.CurrentProjectName)
|
||||||
|
if i < 0 {
|
||||||
|
color.Red("Project name: " + work.CurrentProjectName + ", no exists")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
j := len(work.Projects[i].Streaks) - 1
|
||||||
|
work.Projects[i].Streaks[j].End = time.Now()
|
||||||
|
work.Projects[i].Streaks[j].Duration = time.Now().Sub(work.Projects[i].Streaks[j].Start)
|
||||||
|
work.CurrentProjectName = ""
|
||||||
|
saveWork()
|
||||||
|
fmt.Print("Worked ")
|
||||||
|
fmt.Print(work.Projects[i].Streaks[j].Duration)
|
||||||
|
fmt.Println(" in the project " + work.Projects[i].Name)
|
||||||
|
|
||||||
|
//stop project os.Args[2]
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
color.Red("no option selected")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
color.Red("no option selected")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
98
work.go
Normal file
98
work.go
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Streaks []Streak `json:"streaks"`
|
||||||
|
}
|
||||||
|
type Streak struct {
|
||||||
|
Start time.Time `json:"start"`
|
||||||
|
End time.Time `json:"end"`
|
||||||
|
Duration time.Duration `json:"duration"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
type Work struct {
|
||||||
|
Projects []Project `json:"projects"`
|
||||||
|
CurrentProjectName string `json:"currentProjectName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var work Work
|
||||||
|
|
||||||
|
func readProjects() {
|
||||||
|
file, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
//file not exists, create directory and file
|
||||||
|
color.Yellow(directoryPath + " not exists, creating directory")
|
||||||
|
_ = os.Mkdir(directoryPath, os.ModePerm)
|
||||||
|
saveWork()
|
||||||
|
}
|
||||||
|
content := string(file)
|
||||||
|
json.Unmarshal([]byte(content), &work)
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveWork() {
|
||||||
|
|
||||||
|
jsonProjects, err := json.Marshal(work)
|
||||||
|
check(err)
|
||||||
|
err = ioutil.WriteFile(filePath, jsonProjects, 0644)
|
||||||
|
check(err)
|
||||||
|
}
|
||||||
|
func getProjectIByName(name string) int {
|
||||||
|
for i, project := range work.Projects {
|
||||||
|
if project.Name == name {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
func projectExist(name string) bool {
|
||||||
|
for _, project := range work.Projects {
|
||||||
|
if project.Name == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func newProject(name string) error {
|
||||||
|
//first, check if the project name is not taken yet
|
||||||
|
if projectExist(name) {
|
||||||
|
color.Red("Project name: " + name + ", already exists")
|
||||||
|
return errors.New("project name already exist")
|
||||||
|
}
|
||||||
|
var newProject Project
|
||||||
|
newProject.Name = name
|
||||||
|
work.Projects = append(work.Projects, newProject)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func listProjects() {
|
||||||
|
fmt.Println("")
|
||||||
|
fmt.Println("")
|
||||||
|
fmt.Println("Listing projects")
|
||||||
|
fmt.Println("")
|
||||||
|
for k, project := range work.Projects {
|
||||||
|
fmt.Println("project " + strconv.Itoa(k))
|
||||||
|
fmt.Print("name: ")
|
||||||
|
color.Blue(project.Name)
|
||||||
|
for k2, streak := range project.Streaks {
|
||||||
|
fmt.Println(" streak: " + strconv.Itoa(k2))
|
||||||
|
fmt.Print(" Start:")
|
||||||
|
fmt.Println(streak.Start)
|
||||||
|
fmt.Print(" End:")
|
||||||
|
fmt.Println(streak.End)
|
||||||
|
fmt.Print(" Duration:")
|
||||||
|
fmt.Println(streak.Duration)
|
||||||
|
}
|
||||||
|
fmt.Println("")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user