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.
 
 
 
 
 

169 lines
4.8 KiB

  1. /*
  2. * Copyright © 2018 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 := "pad"
  52. if action == "" && slug == "" {
  53. // Not editing any post; simply render the Pad
  54. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  55. log.Error("Unable to execute template: %v", err)
  56. }
  57. return nil
  58. }
  59. // Retrieve post information for editing
  60. appData.Editing = true
  61. // Make sure this isn't cached, so user doesn't accidentally lose data
  62. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  63. w.Header().Set("Expires", "Thu, 04 Oct 1990 20:00:00 GMT")
  64. if slug != "" {
  65. // TODO: refactor all of this, especially for single-user blogs
  66. appData.Post = getRawCollectionPost(app, slug, collAlias)
  67. if appData.Post.OwnerID != appData.User.ID {
  68. // TODO: add ErrForbiddenEditPost message to flashes
  69. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/edit")]}
  70. }
  71. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  72. if err != nil {
  73. return err
  74. }
  75. } else {
  76. // Editing a floating article
  77. appData.Post = getRawPost(app, action)
  78. appData.Post.Id = action
  79. }
  80. if appData.Post.Gone {
  81. return ErrPostUnpublished
  82. } else if appData.Post.Found && appData.Post.Content != "" {
  83. // Got the post
  84. } else if appData.Post.Found {
  85. return ErrPostFetchError
  86. } else {
  87. return ErrPostNotFound
  88. }
  89. if err = templates[padTmpl].ExecuteTemplate(w, "pad", appData); err != nil {
  90. log.Error("Unable to execute template: %v", err)
  91. }
  92. return nil
  93. }
  94. func handleViewMeta(app *app, w http.ResponseWriter, r *http.Request) error {
  95. vars := mux.Vars(r)
  96. action := vars["action"]
  97. slug := vars["slug"]
  98. collAlias := vars["collection"]
  99. appData := &struct {
  100. page.StaticPage
  101. Post *RawPost
  102. User *User
  103. EditCollection *Collection // Collection of the post we're editing, if any
  104. Flashes []string
  105. NeedsToken bool
  106. }{
  107. StaticPage: pageForReq(app, r),
  108. Post: &RawPost{Font: "norm"},
  109. User: getUserSession(app, r),
  110. }
  111. var err error
  112. if action == "" && slug == "" {
  113. return ErrPostNotFound
  114. }
  115. // Make sure this isn't cached, so user doesn't accidentally lose data
  116. w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
  117. w.Header().Set("Expires", "Thu, 28 Jul 1989 12:00:00 GMT")
  118. if slug != "" {
  119. appData.Post = getRawCollectionPost(app, slug, collAlias)
  120. if appData.Post.OwnerID != appData.User.ID {
  121. // TODO: add ErrForbiddenEditPost message to flashes
  122. return impart.HTTPError{http.StatusFound, r.URL.Path[:strings.LastIndex(r.URL.Path, "/meta")]}
  123. }
  124. if app.cfg.App.SingleUser {
  125. // TODO: optimize this query just like we do in GetCollectionForPad (?)
  126. appData.EditCollection, err = app.db.GetCollectionByID(1)
  127. } else {
  128. appData.EditCollection, err = app.db.GetCollectionForPad(collAlias)
  129. }
  130. if err != nil {
  131. return err
  132. }
  133. } else {
  134. // Editing a floating article
  135. appData.Post = getRawPost(app, action)
  136. appData.Post.Id = action
  137. }
  138. appData.NeedsToken = appData.User == nil || appData.User.ID != appData.Post.OwnerID
  139. if appData.Post.Gone {
  140. return ErrPostUnpublished
  141. } else if appData.Post.Found && appData.Post.Content != "" {
  142. // Got the post
  143. } else if appData.Post.Found {
  144. return ErrPostFetchError
  145. } else {
  146. return ErrPostNotFound
  147. }
  148. appData.Flashes, _ = getSessionFlashes(app, w, r, nil)
  149. if err = templates["edit-meta"].ExecuteTemplate(w, "edit-meta", appData); err != nil {
  150. log.Error("Unable to execute template: %v", err)
  151. }
  152. return nil
  153. }