A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 

191 rinda
5.6 KiB

  1. /*
  2. * Copyright © 2018-2021 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. "net/http"
  13. "strings"
  14. "github.com/gorilla/mux"
  15. "github.com/writeas/impart"
  16. "github.com/writeas/web-core/log"
  17. "github.com/writefreely/writefreely/page"
  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. Silenced bool
  38. Editing bool // True if we're modifying an existing post
  39. EditCollection *Collection // Collection of the post we're editing, if any
  40. }{
  41. StaticPage: pageForReq(app, r),
  42. Post: &RawPost{Font: "norm"},
  43. User: getUserSession(app, r),
  44. }
  45. var err error
  46. if appData.User != nil {
  47. appData.Blogs, err = app.db.GetPublishableCollections(appData.User, app.cfg.App.Host)
  48. if err != nil {
  49. log.Error("Unable to get user's blogs for Pad: %v", err)
  50. }
  51. appData.Silenced, err = app.db.IsUserSilenced(appData.User.ID)
  52. if err != nil {
  53. log.Error("Unable to get user status for Pad: %v", err)
  54. }
  55. }
  56. padTmpl := app.cfg.App.Editor
  57. if templates[padTmpl] == nil {
  58. if padTmpl != "" {
  59. log.Info("No template '%s' found. Falling back to default 'pad' template.", padTmpl)
  60. }
  61. padTmpl = "pad"
  62. }
  63. if action == "" && slug == "" {
  64. // Not editing any post; simply render the Pad
  65. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  66. log.Error("Unable to execute template: %v", err)
  67. }
  68. return nil
  69. }
  70. // Retrieve post information for editing
  71. appData.Editing = true
  72. // Make sure this isn't cached, so user doesn't accidentally lose data
  73. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  74. w.Header().Set("Expires", "Thu, 04 Oct 1990 20:00:00 GMT")
  75. if slug != "" {
  76. // TODO: refactor all of this, especially for single-user blogs
  77. appData.Post = getRawCollectionPost(app, slug, collAlias)
  78. if appData.Post.OwnerID != appData.User.ID {
  79. // TODO: add ErrForbiddenEditPost message to flashes
  80. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/edit")]}
  81. }
  82. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  83. if err != nil {
  84. log.Error("Unable to GetCollectionForPad: %s", err)
  85. return err
  86. }
  87. appData.EditCollection.hostName = app.cfg.App.Host
  88. } else {
  89. // Editing a floating article
  90. appData.Post = getRawPost(app, action)
  91. appData.Post.Id = action
  92. }
  93. if appData.Post.Gone {
  94. return ErrPostUnpublished
  95. } else if appData.Post.Found && (appData.Post.Title != "" || appData.Post.Content != "") {
  96. // Got the post
  97. } else if appData.Post.Found {
  98. log.Error("Found post, but other conditions failed.")
  99. return ErrPostFetchError
  100. } else {
  101. return ErrPostNotFound
  102. }
  103. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  104. log.Error("Unable to execute template: %v", err)
  105. }
  106. return nil
  107. }
  108. func handleViewMeta(app *App, w http.ResponseWriter, r *http.Request) error {
  109. vars := mux.Vars(r)
  110. action := vars["action"]
  111. slug := vars["slug"]
  112. collAlias := vars["collection"]
  113. appData := &struct {
  114. page.StaticPage
  115. Post *RawPost
  116. User *User
  117. EditCollection *Collection // Collection of the post we're editing, if any
  118. Flashes []string
  119. NeedsToken bool
  120. Silenced bool
  121. }{
  122. StaticPage: pageForReq(app, r),
  123. Post: &RawPost{Font: "norm"},
  124. User: getUserSession(app, r),
  125. }
  126. var err error
  127. appData.Silenced, err = app.db.IsUserSilenced(appData.User.ID)
  128. if err != nil {
  129. log.Error("view meta: get user status: %v", err)
  130. return ErrInternalGeneral
  131. }
  132. if action == "" && slug == "" {
  133. return ErrPostNotFound
  134. }
  135. // Make sure this isn't cached, so user doesn't accidentally lose data
  136. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  137. w.Header().Set("Expires", "Thu, 28 Jul 1989 12:00:00 GMT")
  138. if slug != "" {
  139. appData.Post = getRawCollectionPost(app, slug, collAlias)
  140. if appData.Post.OwnerID != appData.User.ID {
  141. // TODO: add ErrForbiddenEditPost message to flashes
  142. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/meta")]}
  143. }
  144. if app.cfg.App.SingleUser {
  145. // TODO: optimize this query just like we do in GetCollectionForPad (?)
  146. appData.EditCollection, err = app.db.GetCollectionByID(1)
  147. } else {
  148. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  149. }
  150. if err != nil {
  151. return err
  152. }
  153. appData.EditCollection.hostName = app.cfg.App.Host
  154. } else {
  155. // Editing a floating article
  156. appData.Post = getRawPost(app, action)
  157. appData.Post.Id = action
  158. }
  159. appData.NeedsToken = appData.User == nil || appData.User.ID != appData.Post.OwnerID
  160. if appData.Post.Gone {
  161. return ErrPostUnpublished
  162. } else if appData.Post.Found && appData.Post.Content != "" {
  163. // Got the post
  164. } else if appData.Post.Found {
  165. return ErrPostFetchError
  166. } else {
  167. return ErrPostNotFound
  168. }
  169. appData.Flashes, _ = getSessionFlashes(app, w, r, nil)
  170. if err = templates["edit-meta"].ExecuteTemplate(w, "edit-meta", appData); err != nil {
  171. log.Error("Unable to execute template: %v", err)
  172. }
  173. return nil
  174. }