app.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package main
  2. import (
  3. "errors"
  4. "html/template"
  5. "log"
  6. "net/http"
  7. "github.com/masterminds/sprig"
  8. )
  9. const (
  10. addr = ":8080"
  11. )
  12. type data map[string]any
  13. /*
  14. @app.route("/")
  15. def index():
  16. */
  17. func index(w http.ResponseWriter, r *http.Request) {
  18. http.Redirect(w, r, "/contacts", http.StatusSeeOther)
  19. }
  20. /*
  21. @app.route("/contacts")
  22. */
  23. func contacts(cs *ContactsStore) http.HandlerFunc {
  24. tpl := makeTemplate(
  25. "layout",
  26. "index",
  27. )
  28. return func(w http.ResponseWriter, r *http.Request) {
  29. search := r.URL.Query().Get("q")
  30. var contacts_set []Contact
  31. if search == "" {
  32. contacts_set = cs.GetAll()
  33. } else {
  34. contacts_set = cs.Get(search)
  35. }
  36. if err := tpl.ExecuteTemplate(w, "layout.html", data{
  37. "contacts": contacts_set,
  38. "search": search,
  39. }); err != nil {
  40. http.Error(w, err.Error(), http.StatusInternalServerError)
  41. }
  42. }
  43. }
  44. /*
  45. @app.route("/contacts/new", methods=['GET']) (1)
  46. def contacts_new_get():
  47. return render_template("new.html", contact=Contact()
  48. */
  49. func contactsNewGet(cs *ContactsStore) http.HandlerFunc {
  50. tpl := makeTemplate(
  51. "layout",
  52. "new",
  53. )
  54. return func(w http.ResponseWriter, r *http.Request) {
  55. c := cs.New()
  56. if err := tpl.ExecuteTemplate(w, "layout.html", c); err != nil {
  57. http.Error(w, err.Error(), http.StatusInternalServerError)
  58. }
  59. }
  60. }
  61. func makeTemplate(first string, others ...string) *template.Template {
  62. paths := append([]string{first}, others...)
  63. for i, path := range paths {
  64. paths[i] = "./templates/" + path + ".gohtml"
  65. }
  66. tpl := template.Must(template.ParseFiles(paths...)).
  67. Funcs(sprig.FuncMap())
  68. return tpl
  69. }
  70. func setupRoutes(mux *http.ServeMux, cs *ContactsStore) {
  71. mux.HandleFunc("/", index)
  72. mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
  73. http.ServeFile(w, r, "./static/img/favicon.ico")
  74. })
  75. mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
  76. mux.Handle("GET /contacts", contacts(cs))
  77. mux.Handle("GET /contacts/new", contactsNewGet(cs))
  78. }
  79. func main() {
  80. cs, err := NewContactsStore()
  81. if err != nil {
  82. log.Fatalf("initializing contacts: %v\n", err)
  83. }
  84. mux := http.NewServeMux()
  85. setupRoutes(mux, cs)
  86. log.Printf("Listening on http://localhost%s", addr)
  87. if err := http.ListenAndServe(addr, mux); err != nil {
  88. if !errors.Is(err, http.ErrServerClosed) {
  89. log.Printf("Server error: %v\n", err)
  90. return
  91. }
  92. }
  93. log.Println("Server shutdown")
  94. }