A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
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.
 
 
 
 
 

176 regels
5.0 KiB

  1. /*
  2. * Copyright © 2018-2019 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. package writefreely
  11. import (
  12. "github.com/gorilla/mux"
  13. "github.com/writeas/impart"
  14. "github.com/writeas/web-core/log"
  15. "github.com/writeas/writefreely/page"
  16. "net/http"
  17. "strings"
  18. )
  19. func handleViewPad(app *App, w http.ResponseWriter, r *http.Request) error {
  20. vars := mux.Vars(r)
  21. action := vars["action"]
  22. slug := vars["slug"]
  23. collAlias := vars["collection"]
  24. if app.cfg.App.SingleUser {
  25. // TODO: refactor all of this, especially for single-user blogs
  26. c, err := app.db.GetCollectionByID(1)
  27. if err != nil {
  28. return err
  29. }
  30. collAlias = c.Alias
  31. }
  32. appData := &struct {
  33. page.StaticPage
  34. Post *RawPost
  35. User *User
  36. Blogs *[]Collection
  37. Editing bool // True if we're modifying an existing post
  38. EditCollection *Collection // Collection of the post we're editing, if any
  39. }{
  40. StaticPage: pageForReq(app, r),
  41. Post: &RawPost{Font: "norm"},
  42. User: getUserSession(app, r),
  43. }
  44. var err error
  45. if appData.User != nil {
  46. appData.Blogs, err = app.db.GetPublishableCollections(appData.User)
  47. if err != nil {
  48. log.Error("Unable to get user's blogs for Pad: %v", err)
  49. }
  50. }
  51. padTmpl := app.cfg.App.Editor
  52. if padTmpl == "" {
  53. padTmpl = "pad"
  54. }
  55. if action == "" && slug == "" {
  56. // Not editing any post; simply render the Pad
  57. if templates[padTmpl] == nil {
  58. log.Info("No template '%s' found. Falling back to default 'pad' template.", padTmpl)
  59. padTmpl = "pad"
  60. }
  61. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  62. log.Error("Unable to execute template: %v", err)
  63. }
  64. return nil
  65. }
  66. // Retrieve post information for editing
  67. appData.Editing = true
  68. // Make sure this isn't cached, so user doesn't accidentally lose data
  69. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  70. w.Header().Set("Expires", "Thu, 04 Oct 1990 20:00:00 GMT")
  71. if slug != "" {
  72. // TODO: refactor all of this, especially for single-user blogs
  73. appData.Post = getRawCollectionPost(app, slug, collAlias)
  74. if appData.Post.OwnerID != appData.User.ID {
  75. // TODO: add ErrForbiddenEditPost message to flashes
  76. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/edit")]}
  77. }
  78. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  79. if err != nil {
  80. return err
  81. }
  82. } else {
  83. // Editing a floating article
  84. appData.Post = getRawPost(app, action)
  85. appData.Post.Id = action
  86. }
  87. if appData.Post.Gone {
  88. return ErrPostUnpublished
  89. } else if appData.Post.Found && appData.Post.Content != "" {
  90. // Got the post
  91. } else if appData.Post.Found {
  92. return ErrPostFetchError
  93. } else {
  94. return ErrPostNotFound
  95. }
  96. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  97. log.Error("Unable to execute template: %v", err)
  98. }
  99. return nil
  100. }
  101. func handleViewMeta(app *App, w http.ResponseWriter, r *http.Request) error {
  102. vars := mux.Vars(r)
  103. action := vars["action"]
  104. slug := vars["slug"]
  105. collAlias := vars["collection"]
  106. appData := &struct {
  107. page.StaticPage
  108. Post *RawPost
  109. User *User
  110. EditCollection *Collection // Collection of the post we're editing, if any
  111. Flashes []string
  112. NeedsToken bool
  113. }{
  114. StaticPage: pageForReq(app, r),
  115. Post: &RawPost{Font: "norm"},
  116. User: getUserSession(app, r),
  117. }
  118. var err error
  119. if action == "" && slug == "" {
  120. return ErrPostNotFound
  121. }
  122. // Make sure this isn't cached, so user doesn't accidentally lose data
  123. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  124. w.Header().Set("Expires", "Thu, 28 Jul 1989 12:00:00 GMT")
  125. if slug != "" {
  126. appData.Post = getRawCollectionPost(app, slug, collAlias)
  127. if appData.Post.OwnerID != appData.User.ID {
  128. // TODO: add ErrForbiddenEditPost message to flashes
  129. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/meta")]}
  130. }
  131. if app.cfg.App.SingleUser {
  132. // TODO: optimize this query just like we do in GetCollectionForPad (?)
  133. appData.EditCollection, err = app.db.GetCollectionByID(1)
  134. } else {
  135. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  136. }
  137. if err != nil {
  138. return err
  139. }
  140. } else {
  141. // Editing a floating article
  142. appData.Post = getRawPost(app, action)
  143. appData.Post.Id = action
  144. }
  145. appData.NeedsToken = appData.User == nil || appData.User.ID != appData.Post.OwnerID
  146. if appData.Post.Gone {
  147. return ErrPostUnpublished
  148. } else if appData.Post.Found && appData.Post.Content != "" {
  149. // Got the post
  150. } else if appData.Post.Found {
  151. return ErrPostFetchError
  152. } else {
  153. return ErrPostNotFound
  154. }
  155. appData.Flashes, _ = getSessionFlashes(app, w, r, nil)
  156. if err = templates["edit-meta"].ExecuteTemplate(w, "edit-meta", appData); err != nil {
  157. log.Error("Unable to execute template: %v", err)
  158. }
  159. return nil
  160. }