Plan stuff. Log stuff.
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.

137 lines
3.2 KiB

4 years ago
  1. package api
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "github.com/gisle/stufflog/database"
  5. "github.com/gisle/stufflog/models"
  6. "github.com/gisle/stufflog/services"
  7. "github.com/gisle/stufflog/slerrors"
  8. "sort"
  9. )
  10. func Activity(g *gin.RouterGroup, db database.Database, auth *services.AuthService) {
  11. type resObj struct {
  12. Activity *models.Activity `json:"activity,omitempty"`
  13. Activities []*models.Activity `json:"activities,omitempty"`
  14. }
  15. g.Use(auth.GinSessionMiddleware(true))
  16. // GET / – List own activities.
  17. g.GET("/", func(c *gin.Context) {
  18. user := auth.UserFromContext(c)
  19. activities, err := db.Activities().ListUser(c.Request.Context(), *user)
  20. if err != nil {
  21. slerrors.GinRespond(c, err)
  22. return
  23. }
  24. sort.Sort(models.ActivitiesByName(activities))
  25. c.JSON(200, resObj{Activities: activities})
  26. })
  27. // GET / — Find an activity
  28. g.GET("/:id", func(c *gin.Context) {
  29. user := auth.UserFromContext(c)
  30. activity, err := db.Activities().FindID(c.Request.Context(), c.Param("id"))
  31. if err != nil {
  32. slerrors.GinRespond(c, err)
  33. return
  34. }
  35. if activity.UserID != user.ID {
  36. slerrors.GinRespond(c, slerrors.NotFound("Activity"))
  37. return
  38. }
  39. c.JSON(200, resObj{Activity: activity})
  40. })
  41. // POST / – Create an activity
  42. g.POST("/", func(c *gin.Context) {
  43. user := auth.UserFromContext(c)
  44. activity := models.Activity{}
  45. err := c.BindJSON(&activity)
  46. if err != nil {
  47. slerrors.GinRespond(c, &slerrors.SLError{Code: 400, Text: err.Error()})
  48. return
  49. }
  50. activity.UserID = user.ID
  51. activity.GenerateIDs()
  52. err = db.Activities().Insert(c.Request.Context(), activity)
  53. if err != nil {
  54. slerrors.GinRespond(c, err)
  55. return
  56. }
  57. c.JSON(200, resObj{Activity: &activity})
  58. })
  59. // PATCH /:id – Update one activity
  60. g.PATCH("/:id", func(c *gin.Context) {
  61. user := auth.UserFromContext(c)
  62. updates := make([]*models.ActivityUpdate, 0, 8)
  63. err := c.BindJSON(&updates)
  64. if err != nil {
  65. slerrors.GinRespond(c, &slerrors.SLError{Code: 400, Text: err.Error()})
  66. return
  67. }
  68. activity, err := db.Activities().FindID(c.Request.Context(), c.Param("id"))
  69. if err != nil {
  70. slerrors.GinRespond(c, err)
  71. return
  72. }
  73. if activity.UserID != user.ID {
  74. slerrors.GinRespond(c, slerrors.NotFound("Activity"))
  75. return
  76. }
  77. activity, err = db.Activities().Update(c.Request.Context(), *activity, updates)
  78. if err != nil {
  79. slerrors.GinRespond(c, err)
  80. return
  81. }
  82. c.JSON(200, resObj{Activity: activity})
  83. })
  84. // DELETE /:id – Delete an activity
  85. g.DELETE("/:id", func(c *gin.Context) {
  86. user := auth.UserFromContext(c)
  87. activity, err := db.Activities().FindID(c.Request.Context(), c.Param("id"))
  88. if err != nil {
  89. slerrors.GinRespond(c, err)
  90. return
  91. }
  92. if activity.UserID != user.ID {
  93. slerrors.GinRespond(c, slerrors.NotFound("Activity"))
  94. return
  95. }
  96. periods, err := db.Periods().ListActivity(c.Request.Context(), *activity)
  97. if err != nil {
  98. slerrors.GinRespond(c, slerrors.Wrap(err))
  99. return
  100. }
  101. if len(periods) > 0 {
  102. slerrors.GinRespond(c, slerrors.PreconditionFailed("You cannot delete an activity that's in use."))
  103. return
  104. }
  105. err = db.Activities().Remove(c.Request.Context(), *activity)
  106. if err != nil {
  107. slerrors.GinRespond(c, err)
  108. return
  109. }
  110. c.JSON(200, resObj{Activity: activity})
  111. })
  112. }