You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
3.5 KiB

  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "strconv"
  9. "time"
  10. "github.com/fatih/color"
  11. )
  12. type Project struct {
  13. Name string `json:"name"`
  14. Streaks []Streak `json:"streaks"`
  15. }
  16. type Streak struct {
  17. Start time.Time `json:"start"`
  18. End time.Time `json:"end"`
  19. Duration time.Duration `json:"duration"`
  20. Description string `json:"description"`
  21. }
  22. type Work struct {
  23. Projects []Project `json:"projects"`
  24. CurrentProjectName string `json:"currentProjectName"`
  25. }
  26. var work Work
  27. func readProjects() {
  28. file, err := ioutil.ReadFile(filePath)
  29. if err != nil {
  30. //file not exists, create directory and file
  31. color.Yellow(directoryPath + " not exists, creating directory")
  32. _ = os.Mkdir(directoryPath, os.ModePerm)
  33. saveWork()
  34. }
  35. content := string(file)
  36. json.Unmarshal([]byte(content), &work)
  37. }
  38. func saveWork() {
  39. jsonProjects, err := json.Marshal(work)
  40. check(err)
  41. err = ioutil.WriteFile(filePath, jsonProjects, 0644)
  42. check(err)
  43. }
  44. func getProjectIByName(name string) int {
  45. for i, project := range work.Projects {
  46. if project.Name == name {
  47. return i
  48. }
  49. }
  50. return -1
  51. }
  52. func projectExist(name string) bool {
  53. for _, project := range work.Projects {
  54. if project.Name == name {
  55. return true
  56. }
  57. }
  58. return false
  59. }
  60. func newProject(name string) error {
  61. //first, check if the project name is not taken yet
  62. if projectExist(name) {
  63. color.Red("Project name: " + name + ", already exists")
  64. return errors.New("project name already exist")
  65. }
  66. var newProject Project
  67. newProject.Name = name
  68. work.Projects = append(work.Projects, newProject)
  69. return nil
  70. }
  71. func listProjectsDetails() {
  72. fmt.Println("")
  73. fmt.Println("")
  74. fmt.Println("Listing projects")
  75. fmt.Println("")
  76. for k, project := range work.Projects {
  77. fmt.Println("project " + strconv.Itoa(k))
  78. fmt.Print("name: ")
  79. color.Blue(project.Name)
  80. for k2, streak := range project.Streaks {
  81. fmt.Println(" streak: " + strconv.Itoa(k2))
  82. fmt.Print(" Start:")
  83. fmt.Println(streak.Start)
  84. fmt.Print(" End:")
  85. fmt.Println(streak.End)
  86. fmt.Print(" Duration:")
  87. fmt.Println(streak.Duration)
  88. }
  89. fmt.Println("")
  90. showHoursByDays(project.Name)
  91. fmt.Println("")
  92. }
  93. if work.CurrentProjectName != "" {
  94. fmt.Print("Current working project: ")
  95. color.Blue(work.CurrentProjectName)
  96. }
  97. }
  98. func listProjects() {
  99. fmt.Println("")
  100. fmt.Println("")
  101. fmt.Println("Listing projects")
  102. fmt.Println("")
  103. for k, project := range work.Projects {
  104. fmt.Println("project " + strconv.Itoa(k))
  105. fmt.Print("name: ")
  106. color.Blue(project.Name)
  107. showHoursByDays(project.Name)
  108. fmt.Println("")
  109. }
  110. if work.CurrentProjectName != "" {
  111. fmt.Print("Current working project: ")
  112. color.Blue(work.CurrentProjectName)
  113. }
  114. }
  115. func deleteProject(name string) {
  116. i := getProjectIByName(name)
  117. if i < 0 {
  118. color.Red("Project name: " + name + ", no exists")
  119. return
  120. }
  121. work.Projects = append(work.Projects[:i], work.Projects[i+1:]...)
  122. }
  123. func showHoursByDays(name string) {
  124. timeFormat := "Mon, 01/02/06"
  125. i := getProjectIByName(name)
  126. if i < 0 {
  127. color.Red("Project name: " + name + ", no exists")
  128. return
  129. }
  130. p := work.Projects[i]
  131. days := make(map[string]time.Duration)
  132. for _, streak := range p.Streaks {
  133. days[streak.Start.Format(timeFormat)] = addDurations(days[streak.Start.Format(timeFormat)], streak.Duration)
  134. }
  135. for day, hours := range days {
  136. fmt.Print(" Day: " + day)
  137. fmt.Print(", total time: ")
  138. fmt.Println(hours)
  139. }
  140. }
  141. func addDurations(d1 time.Duration, d2 time.Duration) time.Duration {
  142. s := d1.Seconds() + d2.Seconds()
  143. r := time.Duration(s) * time.Second
  144. return r
  145. }