category.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package controller
  5. import (
  6. "errors"
  7. "github.com/miniflux/miniflux/logger"
  8. "github.com/miniflux/miniflux/model"
  9. "github.com/miniflux/miniflux/server/core"
  10. "github.com/miniflux/miniflux/server/ui/form"
  11. )
  12. // ShowCategories shows the page with all categories.
  13. func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, response *core.Response) {
  14. args, err := c.getCommonTemplateArgs(ctx)
  15. if err != nil {
  16. response.HTML().ServerError(err)
  17. return
  18. }
  19. user := ctx.LoggedUser()
  20. categories, err := c.store.CategoriesWithFeedCount(user.ID)
  21. if err != nil {
  22. response.HTML().ServerError(err)
  23. return
  24. }
  25. response.HTML().Render("categories", args.Merge(tplParams{
  26. "categories": categories,
  27. "total": len(categories),
  28. "menu": "categories",
  29. }))
  30. }
  31. // ShowCategoryEntries shows all entries for the given category.
  32. func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Request, response *core.Response) {
  33. user := ctx.LoggedUser()
  34. offset := request.QueryIntegerParam("offset", 0)
  35. args, err := c.getCommonTemplateArgs(ctx)
  36. if err != nil {
  37. response.HTML().ServerError(err)
  38. return
  39. }
  40. category, err := c.getCategoryFromURL(ctx, request, response)
  41. if err != nil {
  42. return
  43. }
  44. builder := c.store.NewEntryQueryBuilder(user.ID)
  45. builder.WithCategoryID(category.ID)
  46. builder.WithOrder(model.DefaultSortingOrder)
  47. builder.WithDirection(user.EntryDirection)
  48. builder.WithoutStatus(model.EntryStatusRemoved)
  49. builder.WithOffset(offset)
  50. builder.WithLimit(nbItemsPerPage)
  51. entries, err := builder.GetEntries()
  52. if err != nil {
  53. response.HTML().ServerError(err)
  54. return
  55. }
  56. count, err := builder.CountEntries()
  57. if err != nil {
  58. response.HTML().ServerError(err)
  59. return
  60. }
  61. response.HTML().Render("category_entries", args.Merge(tplParams{
  62. "category": category,
  63. "entries": entries,
  64. "total": count,
  65. "pagination": c.getPagination(ctx.Route("categoryEntries", "categoryID", category.ID), count, offset),
  66. "menu": "categories",
  67. }))
  68. }
  69. // CreateCategory shows the form to create a new category.
  70. func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
  71. args, err := c.getCommonTemplateArgs(ctx)
  72. if err != nil {
  73. response.HTML().ServerError(err)
  74. return
  75. }
  76. response.HTML().Render("create_category", args.Merge(tplParams{
  77. "menu": "categories",
  78. }))
  79. }
  80. // SaveCategory validate and save the new category into the database.
  81. func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
  82. user := ctx.LoggedUser()
  83. args, err := c.getCommonTemplateArgs(ctx)
  84. if err != nil {
  85. response.HTML().ServerError(err)
  86. return
  87. }
  88. categoryForm := form.NewCategoryForm(request.Request())
  89. if err := categoryForm.Validate(); err != nil {
  90. response.HTML().Render("create_category", args.Merge(tplParams{
  91. "errorMessage": err.Error(),
  92. }))
  93. return
  94. }
  95. duplicateCategory, err := c.store.CategoryByTitle(user.ID, categoryForm.Title)
  96. if err != nil {
  97. response.HTML().ServerError(err)
  98. return
  99. }
  100. if duplicateCategory != nil {
  101. response.HTML().Render("create_category", args.Merge(tplParams{
  102. "errorMessage": "This category already exists.",
  103. }))
  104. return
  105. }
  106. category := model.Category{Title: categoryForm.Title, UserID: user.ID}
  107. err = c.store.CreateCategory(&category)
  108. if err != nil {
  109. logger.Info("[Controller:CreateCategory] %v", err)
  110. response.HTML().Render("create_category", args.Merge(tplParams{
  111. "errorMessage": "Unable to create this category.",
  112. }))
  113. return
  114. }
  115. response.Redirect(ctx.Route("categories"))
  116. }
  117. // EditCategory shows the form to modify a category.
  118. func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, response *core.Response) {
  119. user := ctx.LoggedUser()
  120. category, err := c.getCategoryFromURL(ctx, request, response)
  121. if err != nil {
  122. logger.Error("[Controller:EditCategory] %v", err)
  123. return
  124. }
  125. args, err := c.getCategoryFormTemplateArgs(ctx, user, category, nil)
  126. if err != nil {
  127. response.HTML().ServerError(err)
  128. return
  129. }
  130. response.HTML().Render("edit_category", args)
  131. }
  132. // UpdateCategory validate and update a category.
  133. func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
  134. user := ctx.LoggedUser()
  135. category, err := c.getCategoryFromURL(ctx, request, response)
  136. if err != nil {
  137. logger.Error("[Controller:UpdateCategory] %v", err)
  138. return
  139. }
  140. categoryForm := form.NewCategoryForm(request.Request())
  141. args, err := c.getCategoryFormTemplateArgs(ctx, user, category, categoryForm)
  142. if err != nil {
  143. response.HTML().ServerError(err)
  144. return
  145. }
  146. if err := categoryForm.Validate(); err != nil {
  147. response.HTML().Render("edit_category", args.Merge(tplParams{
  148. "errorMessage": err.Error(),
  149. }))
  150. return
  151. }
  152. if c.store.AnotherCategoryExists(user.ID, category.ID, categoryForm.Title) {
  153. response.HTML().Render("edit_category", args.Merge(tplParams{
  154. "errorMessage": "This category already exists.",
  155. }))
  156. return
  157. }
  158. err = c.store.UpdateCategory(categoryForm.Merge(category))
  159. if err != nil {
  160. logger.Error("[Controller:UpdateCategory] %v", err)
  161. response.HTML().Render("edit_category", args.Merge(tplParams{
  162. "errorMessage": "Unable to update this category.",
  163. }))
  164. return
  165. }
  166. response.Redirect(ctx.Route("categories"))
  167. }
  168. // RemoveCategory delete a category from the database.
  169. func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
  170. user := ctx.LoggedUser()
  171. category, err := c.getCategoryFromURL(ctx, request, response)
  172. if err != nil {
  173. return
  174. }
  175. if err := c.store.RemoveCategory(user.ID, category.ID); err != nil {
  176. response.HTML().ServerError(err)
  177. return
  178. }
  179. response.Redirect(ctx.Route("categories"))
  180. }
  181. func (c *Controller) getCategoryFromURL(ctx *core.Context, request *core.Request, response *core.Response) (*model.Category, error) {
  182. categoryID, err := request.IntegerParam("categoryID")
  183. if err != nil {
  184. response.HTML().BadRequest(err)
  185. return nil, err
  186. }
  187. user := ctx.LoggedUser()
  188. category, err := c.store.Category(user.ID, categoryID)
  189. if err != nil {
  190. response.HTML().ServerError(err)
  191. return nil, err
  192. }
  193. if category == nil {
  194. response.HTML().NotFound()
  195. return nil, errors.New("Category not found")
  196. }
  197. return category, nil
  198. }
  199. func (c *Controller) getCategoryFormTemplateArgs(ctx *core.Context, user *model.User, category *model.Category, categoryForm *form.CategoryForm) (tplParams, error) {
  200. args, err := c.getCommonTemplateArgs(ctx)
  201. if err != nil {
  202. return nil, err
  203. }
  204. if categoryForm == nil {
  205. args["form"] = form.CategoryForm{
  206. Title: category.Title,
  207. }
  208. } else {
  209. args["form"] = categoryForm
  210. }
  211. args["category"] = category
  212. args["menu"] = "categories"
  213. return args, nil
  214. }