Publish HTML quickly. https://html.house
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.
 
 
 
 

119 lines
2.8 KiB

  1. package htmlhouse
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "html/template"
  6. "io/ioutil"
  7. "net/http"
  8. "github.com/gorilla/mux"
  9. "github.com/writeas/impart"
  10. )
  11. type app struct {
  12. cfg *config
  13. router *mux.Router
  14. db *sql.DB
  15. session sessionManager
  16. templates map[string]*template.Template
  17. }
  18. func newApp() (*app, error) {
  19. var err error
  20. app := &app{}
  21. app.cfg, err = newConfig()
  22. if err != nil {
  23. return app, err
  24. }
  25. app.session, err = newSessionManager(app.cfg)
  26. if err != nil {
  27. return app, err
  28. }
  29. err = app.initDatabase()
  30. if err != nil {
  31. return app, err
  32. }
  33. app.initTemplates()
  34. app.initRouter()
  35. return app, nil
  36. }
  37. func (app *app) close() {
  38. app.db.Close()
  39. }
  40. func (app *app) initRouter() {
  41. app.router = mux.NewRouter()
  42. api := app.router.PathPrefix("/⌂/").Subrouter()
  43. api.HandleFunc("/create", app.handler(createHouse)).Methods("POST").Name("create")
  44. api.HandleFunc("/{house:[A-Za-z0-9.-]{8}}", app.handler(renovateHouse)).Methods("POST").Name("update")
  45. app.router.HandleFunc("/", app.handler(getEditor)).Methods("GET").Name("index")
  46. app.router.HandleFunc("/edit/{house:[A-Za-z0-9.-]{8}}.html", app.handler(getEditor)).Methods("GET").Name("edit")
  47. app.router.HandleFunc("/stats/{house:[A-Za-z0-9.-]{8}}.html", app.handler(viewHouseStats)).Methods("GET").Name("stats")
  48. app.router.HandleFunc("/{house:[A-Za-z0-9.-]{8}}.html", app.handler(getHouse)).Methods("GET").Name("get")
  49. app.router.HandleFunc("/browse", app.handler(viewHouses)).Methods("GET").Name("browse")
  50. app.router.PathPrefix("/").Handler(http.FileServer(http.Dir(app.cfg.StaticDir)))
  51. }
  52. type EditorPage struct {
  53. ID string
  54. Content string
  55. }
  56. func getEditor(app *app, w http.ResponseWriter, r *http.Request) error {
  57. vars := mux.Vars(r)
  58. house := vars["house"]
  59. if house == "" {
  60. defaultPage, err := ioutil.ReadFile(app.cfg.StaticDir + "/default.html")
  61. if err != nil {
  62. fmt.Printf("\n%s\n", err)
  63. defaultPage = []byte("<!DOCTYPE html>\n<html>\n</html>")
  64. }
  65. app.templates["editor"].ExecuteTemplate(w, "editor", &EditorPage{"", string(defaultPage)})
  66. return nil
  67. }
  68. html, err := getHouseHTML(app, house)
  69. if err != nil {
  70. return err
  71. }
  72. app.templates["editor"].ExecuteTemplate(w, "editor", &EditorPage{house, html})
  73. return nil
  74. }
  75. type handlerFunc func(app *app, w http.ResponseWriter, r *http.Request) error
  76. func (app *app) handler(h handlerFunc) http.HandlerFunc {
  77. return func(w http.ResponseWriter, r *http.Request) {
  78. handleError(w, r, func() error {
  79. return h(app, w, r)
  80. }())
  81. }
  82. }
  83. func handleError(w http.ResponseWriter, r *http.Request, err error) {
  84. if err == nil {
  85. return
  86. }
  87. if err, ok := err.(impart.HTTPError); ok {
  88. impart.WriteError(w, err)
  89. return
  90. }
  91. impart.WriteError(w, impart.HTTPError{http.StatusInternalServerError, "This is an unhelpful error message for a miscellaneous internal error."})
  92. }