Calorie counting web application written in the Go language

profile.go 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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) getGoal(account *models.Account) (goal int64) {
  34. goal = 2000
  35. if account == nil {
  36. return goal
  37. }
  38. results := models.Goal{}
  39. err := c.Transaction.SelectOne(
  40. &results,
  41. `select * from Goal where AccountId = ? order by Date desc limit 1`,
  42. account.Id)
  43. if err != nil {
  44. return goal
  45. }
  46. goal = results.Calories
  47. return goal
  48. }
  49. func (c Profile) setGoal(account *models.Account, calories int64) {
  50. goals, err := c.Transaction.Select(
  51. models.Goal{},
  52. `select * from Goal where AccountId = ? order by Date desc limit 1`,
  53. account.Id)
  54. if err != nil {
  55. revel.INFO.Println(err)
  56. return
  57. }
  58. now := time.Now().Local()
  59. if len(goals) > 0 {
  60. goal := goals[0].(*models.Goal)
  61. local := goal.Date.Local()
  62. if now.Day() == local.Day() && now.Month() == local.Month() && now.Year() == local.Year() {
  63. goal.Calories = calories
  64. c.Transaction.Update(goal)
  65. } else {
  66. newGoal := models.Goal{ AccountId: account.Id, Calories: calories, Date: now }
  67. c.Transaction.Insert(&newGoal)
  68. }
  69. } else {
  70. newGoal := models.Goal{ AccountId: account.Id, Calories: calories, Date: now }
  71. c.Transaction.Insert(&newGoal)
  72. }
  73. }
  74. func (c Profile) getCaloriesForDate(history []*models.History, date time.Time) (current int64) {
  75. current = 0
  76. if history != nil {
  77. for _, moment := range history {
  78. if moment != nil {
  79. local := moment.Date.Local()
  80. if local.Day() == date.Day() && local.Month() == date.Month() && local.Year() == date.Year() {
  81. current += moment.Calories
  82. }
  83. }
  84. }
  85. }
  86. return current
  87. }
  88. func (c Profile) getStreak(history []*models.History, ceiling int64) (streak int64) {
  89. now := time.Now()
  90. streak = 0
  91. if history != nil && len(history) > 0 {
  92. interval := 1
  93. for {
  94. s := fmt.Sprintf("-%dh", interval * 24)
  95. duration, _ := time.ParseDuration(s)
  96. count := c.getCaloriesForDate(history, now.Add(duration))
  97. if count > 0 && ceiling > count {
  98. streak += 1
  99. interval += 1
  100. } else {
  101. break
  102. }
  103. }
  104. }
  105. return streak
  106. }
  107. func (c Profile) getMoment(id int64) *models.History {
  108. history, err := c.Transaction.Select(models.History{}, `select * from History where Id = ?`, id)
  109. if err != nil {
  110. panic(err)
  111. }
  112. if len(history) == 0 {
  113. return nil
  114. }
  115. return history[0].(*models.History)
  116. }
  117. func (c Profile) Index() revel.Result {
  118. account := c.Connected()
  119. return c.Render(account)
  120. }
  121. func (c Profile) Logon(id string) revel.Result {
  122. c.Response.ContentType = "application/json"
  123. c.Validation.Required(id).Message("You must be logged on.")
  124. if c.Validation.HasErrors() {
  125. revel.INFO.Println("Validation errors found.")
  126. c.Validation.Keep()
  127. c.FlashParams()
  128. return c.RenderJson(nil)
  129. }
  130. revel.INFO.Println("Setting up the variables for storage.")
  131. now := time.Now()
  132. account := c.getAccount(id)
  133. if account == nil {
  134. revel.INFO.Println("Creating account.")
  135. account = &models.Account{}
  136. account.Profile = id
  137. account.Created = now
  138. account.LastVisit = now
  139. c.Transaction.Insert(account)
  140. } else {
  141. revel.INFO.Println("Updating account.")
  142. account.LastVisit = now
  143. c.Transaction.Update(account)
  144. }
  145. c.Session["account"] = id
  146. c.Session.SetDefaultExpiration()
  147. return c.RenderJson(true)
  148. }
  149. func (c Profile) History() revel.Result {
  150. account := c.Connected()
  151. if account == nil {
  152. return c.RenderJson(nil)
  153. }
  154. history := c.getHistory(account)
  155. return c.RenderJson(history)
  156. }
  157. func (c Profile) Stats() revel.Result {
  158. account := c.Connected()
  159. if account == nil {
  160. return c.RenderJson(nil)
  161. }
  162. goal := c.getGoal(account)
  163. history := c.getHistory(account)
  164. response := models.ResponseStatistics {
  165. Goal: goal,
  166. Current: c.getCaloriesForDate(history, time.Now()),
  167. Streak: c.getStreak(history, goal),
  168. }
  169. return c.RenderJson(response)
  170. }
  171. func (c Profile) Add(product string, calories int64) revel.Result {
  172. account := c.Connected()
  173. if account == nil || strings.TrimSpace(product) == "" {
  174. return c.RenderJson(nil)
  175. }
  176. c.Validation.Required(product).Message("You must include a product.")
  177. c.Validation.Required(calories).Message("You must provide the amount of calories")
  178. if c.Validation.HasErrors() {
  179. c.Validation.Keep()
  180. c.FlashParams()
  181. return c.RenderJson(nil)
  182. }
  183. moment := models.History {
  184. AccountId: account.Id,
  185. Product: product,
  186. Calories: calories,
  187. Date: time.Now(),
  188. }
  189. c.Transaction.Insert(&moment)
  190. return c.RenderJson(moment)
  191. }
  192. func (c Profile) Delete(id int64) revel.Result {
  193. account := c.Connected()
  194. if account == nil {
  195. return c.RenderJson(nil)
  196. }
  197. moment := c.getMoment(id)
  198. if moment == nil {
  199. return c.RenderJson(nil)
  200. }
  201. c.Transaction.Delete(moment)
  202. return c.RenderJson(true)
  203. }
  204. func (c Profile) Goal(calories int64) revel.Result {
  205. account := c.Connected()
  206. if account == nil {
  207. return c.RenderJson(nil)
  208. }
  209. c.setGoal(account, calories)
  210. return c.RenderJson(true)
  211. }