app.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. func makeTemplate(first string, others ...string) *template.Template {
  45. paths := append([]string{first}, others...)
  46. for i, path := range paths {
  47. paths[i] = "./templates/" + path + ".gohtml"
  48. }
  49. tpl := template.Must(template.ParseFiles(paths...)).
  50. Funcs(sprig.FuncMap())
  51. return tpl
  52. }
  53. func setupRoutes(mux *http.ServeMux, cs *ContactsStore) {
  54. mux.HandleFunc("/", index)
  55. mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
  56. http.ServeFile(w, r, "./static/img/favicon.ico")
  57. })
  58. mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
  59. mux.Handle("/contacts", contacts(cs))
  60. }
  61. func main() {
  62. cs, err := NewContactsStore()
  63. if err != nil {
  64. log.Fatalf("initializing contacts: %v\n", err)
  65. }
  66. mux := http.NewServeMux()
  67. setupRoutes(mux, cs)
  68. log.Printf("Listening on http://localhost%s", addr)
  69. if err := http.ListenAndServe(addr, mux); err != nil {
  70. if !errors.Is(err, http.ErrServerClosed) {
  71. log.Printf("Server error: %v\n", err)
  72. return
  73. }
  74. }
  75. log.Println("Server shutdown")
  76. }