Calorie counting web application written in the Go language

profile.go 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. package controllers
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. "github.com/revel/revel"
  7. "github.com/revolvingcow/grassfed/app/models"
  8. )
  9. type Profile struct {
  10. Application
  11. }
  12. func (c Profile) getHistory(account *models.Account) []*models.History {
  13. if account == nil {
  14. return nil
  15. }
  16. results, err := c.Transaction.Select(
  17. models.History{},
  18. `select * from History where AccountId = ? order by Date desc`,
  19. account.Id)
  20. if err != nil {
  21. return nil
  22. }
  23. rows := len(results)
  24. if rows == 0 {
  25. return nil
  26. }
  27. history := make([]*models.History, rows)
  28. for i := 0; i < rows; i++ {
  29. history = append(history, results[i].(*models.History))
  30. }
  31. return history
  32. }
  33. func (c Profile) getCaloriesForDate(history []*models.History, date time.Time) (current int64) {
  34. current = 0
  35. if history != nil {
  36. for _, moment := range history {
  37. if moment != nil {
  38. local := moment.Date.Local()
  39. if local.Day() == date.Day() && local.Month() == date.Month() && local.Year() == date.Year() {
  40. current += moment.Calories
  41. }
  42. }
  43. }
  44. }
  45. return current
  46. }
  47. func (c Profile) getStreak(history []*models.History, ceiling int64) (streak int64) {
  48. now := time.Now()
  49. streak = 0
  50. if history != nil && len(history) > 0 {
  51. interval := 1
  52. for {
  53. s := fmt.Sprintf("-%dh", interval * 24)
  54. duration, _ := time.ParseDuration(s)
  55. count := c.getCaloriesForDate(history, now.Add(duration))
  56. if count > 0 && ceiling > count {
  57. streak += 1
  58. interval += 1
  59. } else {
  60. break
  61. }
  62. }
  63. }
  64. return streak
  65. }
  66. func (c Profile) getMoment(id int64) *models.History {
  67. history, err := c.Transaction.Select(models.History{}, `select * from History where Id = ?`, id)
  68. if err != nil {
  69. panic(err)
  70. }
  71. if len(history) == 0 {
  72. return nil
  73. }
  74. return history[0].(*models.History)
  75. }
  76. func (c Profile) Index() revel.Result {
  77. return c.Render()
  78. }
  79. func (c Profile) Logon(id string) revel.Result {
  80. c.Response.ContentType = "application/json"
  81. c.Validation.Required(id).Message("You must be logged on.")
  82. if c.Validation.HasErrors() {
  83. revel.INFO.Println("Validation errors found.")
  84. c.Validation.Keep()
  85. c.FlashParams()
  86. return c.RenderJson(nil)
  87. }
  88. revel.INFO.Println("Setting up the variables for storage.")
  89. now := time.Now()
  90. account := c.getAccount(id)
  91. if account == nil {
  92. revel.INFO.Println("Creating account.")
  93. account = &models.Account{}
  94. account.Profile = id
  95. account.Goal = 2000
  96. account.Created = now
  97. account.LastVisit = now
  98. c.Transaction.Insert(account)
  99. } else {
  100. revel.INFO.Println("Updating account.")
  101. account.LastVisit = now
  102. c.Transaction.Update(account)
  103. }
  104. c.Session["account"] = id
  105. c.Session.SetDefaultExpiration()
  106. return c.RenderJson(true)
  107. }
  108. func (c Profile) History() revel.Result {
  109. account := c.Connected()
  110. if account == nil {
  111. return c.RenderJson(nil)
  112. }
  113. history := c.getHistory(account)
  114. return c.RenderJson(history)
  115. }
  116. func (c Profile) Stats() revel.Result {
  117. account := c.Connected()
  118. if account == nil {
  119. return c.RenderJson(nil)
  120. }
  121. history := c.getHistory(account)
  122. response := models.ResponseStatistics {
  123. Goal: account.Goal,
  124. Current: c.getCaloriesForDate(history, time.Now()),
  125. Streak: c.getStreak(history, account.Goal),
  126. }
  127. return c.RenderJson(response)
  128. }
  129. func (c Profile) Add(product string, calories int64) revel.Result {
  130. account := c.Connected()
  131. if account == nil || strings.TrimSpace(product) == "" {
  132. return c.RenderJson(nil)
  133. }
  134. c.Validation.Required(product).Message("You must include a product.")
  135. c.Validation.Required(calories).Message("You must provide the amount of calories")
  136. if c.Validation.HasErrors() {
  137. c.Validation.Keep()
  138. c.FlashParams()
  139. return c.RenderJson(nil)
  140. }
  141. moment := models.History {
  142. AccountId: account.Id,
  143. Product: product,
  144. Calories: calories,
  145. Date: time.Now(),
  146. }
  147. c.Transaction.Insert(&moment)
  148. return c.RenderJson(moment)
  149. }
  150. func (c Profile) Delete(id int64) revel.Result {
  151. account := c.Connected()
  152. if account == nil {
  153. return c.RenderJson(nil)
  154. }
  155. moment := c.getMoment(id)
  156. if moment == nil {
  157. return c.RenderJson(nil)
  158. }
  159. c.Transaction.Delete(moment)
  160. return c.RenderJson(true)
  161. }
  162. func (c Profile) Goal(calories int64) revel.Result {
  163. account := c.Connected()
  164. if account == nil {
  165. return c.RenderJson(nil)
  166. }
  167. account.Goal = calories
  168. c.Transaction.Update(account)
  169. return c.RenderJson(true)
  170. }