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.
 
 
 
 
 

124 lines
6.3 KiB

  1. package writefreely
  2. import (
  3. "github.com/gorilla/mux"
  4. "github.com/writeas/go-nodeinfo"
  5. "github.com/writeas/web-core/log"
  6. "github.com/writeas/writefreely/config"
  7. "net/http"
  8. "strings"
  9. )
  10. func initRoutes(handler *Handler, r *mux.Router, cfg *config.Config, db *datastore) {
  11. hostSubroute := cfg.App.Host[strings.Index(cfg.App.Host, "://")+3:]
  12. if cfg.App.SingleUser {
  13. hostSubroute = "{domain}"
  14. } else {
  15. if strings.HasPrefix(hostSubroute, "localhost") {
  16. hostSubroute = "localhost"
  17. }
  18. }
  19. if cfg.App.SingleUser {
  20. log.Info("Adding %s routes (single user)...", hostSubroute)
  21. } else {
  22. log.Info("Adding %s routes (multi-user)...", hostSubroute)
  23. }
  24. // Primary app routes
  25. write := r.Host(hostSubroute).Subrouter()
  26. // Federation endpoints
  27. // nodeinfo
  28. niCfg := nodeInfoConfig(cfg)
  29. ni := nodeinfo.NewService(*niCfg, nodeInfoResolver{cfg, db})
  30. write.HandleFunc(nodeinfo.NodeInfoPath, handler.LogHandlerFunc(http.HandlerFunc(ni.NodeInfoDiscover)))
  31. write.HandleFunc(niCfg.InfoURL, handler.LogHandlerFunc(http.HandlerFunc(ni.NodeInfo)))
  32. // Handle logged in user sections
  33. me := write.PathPrefix("/me").Subrouter()
  34. me.HandleFunc("/", handler.Redirect("/me", UserLevelUser))
  35. me.HandleFunc("/c", handler.Redirect("/me/c/", UserLevelUser)).Methods("GET")
  36. me.HandleFunc("/c/", handler.User(viewCollections)).Methods("GET")
  37. me.HandleFunc("/c/{collection}", handler.User(viewEditCollection)).Methods("GET")
  38. me.HandleFunc("/c/{collection}/stats", handler.User(viewStats)).Methods("GET")
  39. me.HandleFunc("/posts", handler.Redirect("/me/posts/", UserLevelUser)).Methods("GET")
  40. me.HandleFunc("/posts/", handler.User(viewArticles)).Methods("GET")
  41. me.HandleFunc("/posts/export.csv", handler.Download(viewExportPosts, UserLevelUser)).Methods("GET")
  42. me.HandleFunc("/posts/export.zip", handler.Download(viewExportPosts, UserLevelUser)).Methods("GET")
  43. me.HandleFunc("/posts/export.json", handler.Download(viewExportPosts, UserLevelUser)).Methods("GET")
  44. me.HandleFunc("/export", handler.User(viewExportOptions)).Methods("GET")
  45. me.HandleFunc("/export.json", handler.Download(viewExportFull, UserLevelUser)).Methods("GET")
  46. me.HandleFunc("/settings", handler.User(viewSettings)).Methods("GET")
  47. me.HandleFunc("/logout", handler.Web(viewLogout, UserLevelNone)).Methods("GET")
  48. write.HandleFunc("/api/me", handler.All(viewMeAPI)).Methods("GET")
  49. apiMe := write.PathPrefix("/api/me/").Subrouter()
  50. apiMe.HandleFunc("/", handler.All(viewMeAPI)).Methods("GET")
  51. apiMe.HandleFunc("/posts", handler.UserAPI(viewMyPostsAPI)).Methods("GET")
  52. apiMe.HandleFunc("/collections", handler.UserAPI(viewMyCollectionsAPI)).Methods("GET")
  53. apiMe.HandleFunc("/password", handler.All(updatePassphrase)).Methods("POST")
  54. apiMe.HandleFunc("/self", handler.All(updateSettings)).Methods("POST")
  55. // Sign up validation
  56. write.HandleFunc("/api/alias", handler.All(handleUsernameCheck)).Methods("POST")
  57. // Handle collections
  58. write.HandleFunc("/api/collections", handler.All(newCollection)).Methods("POST")
  59. apiColls := write.PathPrefix("/api/collections/").Subrouter()
  60. apiColls.HandleFunc("/{alias:[0-9a-zA-Z\\-]+}", handler.All(fetchCollection)).Methods("GET")
  61. apiColls.HandleFunc("/{alias:[0-9a-zA-Z\\-]+}", handler.All(existingCollection)).Methods("POST", "DELETE")
  62. apiColls.HandleFunc("/{alias}/posts", handler.All(fetchCollectionPosts)).Methods("GET")
  63. apiColls.HandleFunc("/{alias}/posts", handler.All(newPost)).Methods("POST")
  64. apiColls.HandleFunc("/{alias}/posts/{post}", handler.All(fetchPost)).Methods("GET")
  65. apiColls.HandleFunc("/{alias}/posts/{post:[a-zA-Z0-9]{10}}", handler.All(existingPost)).Methods("POST")
  66. apiColls.HandleFunc("/{alias}/posts/{post}/{property}", handler.All(fetchPostProperty)).Methods("GET")
  67. apiColls.HandleFunc("/{alias}/collect", handler.All(addPost)).Methods("POST")
  68. apiColls.HandleFunc("/{alias}/pin", handler.All(pinPost)).Methods("POST")
  69. apiColls.HandleFunc("/{alias}/unpin", handler.All(pinPost)).Methods("POST")
  70. // Handle posts
  71. write.HandleFunc("/api/posts", handler.All(newPost)).Methods("POST")
  72. posts := write.PathPrefix("/api/posts/").Subrouter()
  73. posts.HandleFunc("/{post:[a-zA-Z0-9]{10}}", handler.All(fetchPost)).Methods("GET")
  74. posts.HandleFunc("/{post:[a-zA-Z0-9]{10}}", handler.All(existingPost)).Methods("POST", "PUT")
  75. posts.HandleFunc("/{post:[a-zA-Z0-9]{10}}", handler.All(deletePost)).Methods("DELETE")
  76. posts.HandleFunc("/{post:[a-zA-Z0-9]{10}}/{property}", handler.All(fetchPostProperty)).Methods("GET")
  77. posts.HandleFunc("/claim", handler.All(addPost)).Methods("POST")
  78. posts.HandleFunc("/disperse", handler.All(dispersePost)).Methods("POST")
  79. if cfg.App.SingleUser {
  80. write.HandleFunc("/me/new", handler.Web(handleViewPad, UserLevelOptional)).Methods("GET")
  81. } else {
  82. write.HandleFunc("/new", handler.Web(handleViewPad, UserLevelOptional)).Methods("GET")
  83. }
  84. // All the existing stuff
  85. write.HandleFunc("/{action}/edit", handler.Web(handleViewPad, UserLevelOptional)).Methods("GET")
  86. write.HandleFunc("/{action}/meta", handler.Web(handleViewMeta, UserLevelOptional)).Methods("GET")
  87. // Collections
  88. if cfg.App.SingleUser {
  89. RouteCollections(handler, write.PathPrefix("/").Subrouter())
  90. } else {
  91. write.HandleFunc("/{prefix:[@~$!\\-+]}{collection}", handler.Web(handleViewCollection, UserLevelOptional))
  92. write.HandleFunc("/{collection}/", handler.Web(handleViewCollection, UserLevelOptional))
  93. RouteCollections(handler, write.PathPrefix("/{prefix:[@~$!\\-+]?}{collection}").Subrouter())
  94. // Posts
  95. write.HandleFunc("/{post}", handler.Web(handleViewPost, UserLevelOptional))
  96. }
  97. write.HandleFunc("/", handler.Web(handleViewHome, UserLevelOptional))
  98. }
  99. func RouteCollections(handler *Handler, r *mux.Router) {
  100. r.HandleFunc("/page/{page:[0-9]+}", handler.Web(handleViewCollection, UserLevelOptional))
  101. r.HandleFunc("/tag:{tag}", handler.Web(handleViewCollectionTag, UserLevelOptional))
  102. r.HandleFunc("/tag:{tag}/feed/", handler.Web(ViewFeed, UserLevelOptional))
  103. r.HandleFunc("/tags/{tag}", handler.Web(handleViewCollectionTag, UserLevelOptional))
  104. r.HandleFunc("/sitemap.xml", handler.All(handleViewSitemap))
  105. r.HandleFunc("/feed/", handler.All(ViewFeed))
  106. r.HandleFunc("/{slug}", handler.Web(viewCollectionPost, UserLevelOptional))
  107. r.HandleFunc("/{slug}/edit", handler.Web(handleViewPad, UserLevelUser))
  108. r.HandleFunc("/{slug}/edit/meta", handler.Web(handleViewMeta, UserLevelUser))
  109. r.HandleFunc("/{slug}/", handler.Web(handleCollectionPostRedirect, UserLevelOptional)).Methods("GET")
  110. }