A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 

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