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.
 
 
 
 
 

147 lines
3.2 KiB

  1. /*
  2. * Copyright © 2020 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. "bytes"
  13. "fmt"
  14. "io"
  15. "strings"
  16. "github.com/prologic/go-gopher"
  17. "github.com/writeas/web-core/log"
  18. )
  19. func initGopher(apper Apper) {
  20. handler := NewWFHandler(apper)
  21. gopher.HandleFunc("/", handler.Gopher(handleGopher))
  22. log.Info("Serving on gopher://localhost:%d", apper.App().Config().Server.GopherPort)
  23. gopher.ListenAndServe(fmt.Sprintf(":%d", apper.App().Config().Server.GopherPort), nil)
  24. }
  25. func handleGopher(app *App, w gopher.ResponseWriter, r *gopher.Request) error {
  26. parts := strings.Split(r.Selector, "/")
  27. if app.cfg.App.SingleUser {
  28. if parts[1] != "" {
  29. return handleGopherCollectionPost(app, w, r)
  30. }
  31. return handleGopherCollection(app, w, r)
  32. }
  33. // Show all public collections (a gopher Reader view, essentially)
  34. if len(parts) == 3 {
  35. return handleGopherCollection(app, w, r)
  36. }
  37. w.WriteInfo(fmt.Sprintf("Welcome to %s", app.cfg.App.SiteName))
  38. colls, err := app.db.GetPublicCollections(app.cfg.App.Host)
  39. if err != nil {
  40. return err
  41. }
  42. for _, c := range *colls {
  43. w.WriteItem(&gopher.Item{
  44. Type: gopher.DIRECTORY,
  45. Description: c.DisplayTitle(),
  46. Selector: "/" + c.Alias + "/",
  47. })
  48. }
  49. return w.End()
  50. }
  51. func handleGopherCollection(app *App, w gopher.ResponseWriter, r *gopher.Request) error {
  52. var collAlias, slug string
  53. var c *Collection
  54. var err error
  55. var baseSel = "/"
  56. parts := strings.Split(r.Selector, "/")
  57. if app.cfg.App.SingleUser {
  58. // sanity check
  59. slug = parts[1]
  60. if slug != "" {
  61. return handleGopherCollectionPost(app, w, r)
  62. }
  63. c, err = app.db.GetCollectionByID(1)
  64. if err != nil {
  65. return err
  66. }
  67. } else {
  68. collAlias = parts[1]
  69. slug = parts[2]
  70. if slug != "" {
  71. return handleGopherCollectionPost(app, w, r)
  72. }
  73. c, err = app.db.GetCollection(collAlias)
  74. if err != nil {
  75. return err
  76. }
  77. baseSel = "/" + c.Alias + "/"
  78. }
  79. c.hostName = app.cfg.App.Host
  80. posts, err := app.db.GetPosts(app.cfg, c, 0, false, false, false)
  81. if err != nil {
  82. return err
  83. }
  84. for _, p := range *posts {
  85. w.WriteItem(&gopher.Item{
  86. Type: gopher.FILE,
  87. Description: p.CreatedDate() + " - " + p.DisplayTitle(),
  88. Selector: baseSel + p.Slug.String,
  89. })
  90. }
  91. return w.End()
  92. }
  93. func handleGopherCollectionPost(app *App, w gopher.ResponseWriter, r *gopher.Request) error {
  94. var collAlias, slug string
  95. var c *Collection
  96. var err error
  97. parts := strings.Split(r.Selector, "/")
  98. if app.cfg.App.SingleUser {
  99. slug = parts[1]
  100. c, err = app.db.GetCollectionByID(1)
  101. if err != nil {
  102. return err
  103. }
  104. } else {
  105. collAlias = parts[1]
  106. slug = parts[2]
  107. c, err = app.db.GetCollection(collAlias)
  108. if err != nil {
  109. return err
  110. }
  111. }
  112. c.hostName = app.cfg.App.Host
  113. p, err := app.db.GetPost(slug, c.ID)
  114. if err != nil {
  115. return err
  116. }
  117. b := bytes.Buffer{}
  118. if p.Title.String != "" {
  119. b.WriteString(p.Title.String + "\n")
  120. }
  121. b.WriteString(p.DisplayDate + "\n\n")
  122. b.WriteString(p.Content)
  123. io.Copy(w, &b)
  124. return w.End()
  125. }