release.go (1498B)
1 package server 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "lyrics/internal/db" 8 "lyrics/internal/domain" 9 "lyrics/internal/server/htmx" 10 "lyrics/internal/server/routes" 11 releaseview "lyrics/internal/server/ui/views/release" 12 "net/http" 13 "strconv" 14 ) 15 16 func (ss *ServerState) Release(w http.ResponseWriter, r *http.Request) { 17 logger := ss.logger.With("handler", "Release") 18 19 idStr := r.PathValue("id") 20 id, err := strconv.Atoi(idStr) 21 if err != nil { 22 logger.Error("failed to convert release id to integer", "id", idStr, "err", err) 23 htmx.HxError(w, http.StatusBadRequest, err.Error()) 24 return 25 } 26 27 slug := r.PathValue("slug") 28 logger = logger.With("id", id, "slug", slug) 29 30 release, err := db.Release(ss.db, domain.ReleaseID(id)) 31 if err != nil { 32 logger.Error("failed to get release", "err", err) 33 htmx.HxError(w, http.StatusInternalServerError, fmt.Sprintf("failed to query for release '%s'", slug)) 34 return 35 } 36 37 releaseTitle := release.Title 38 if release.LatinTitle != nil { 39 releaseTitle = *release.LatinTitle 40 } 41 42 if domain.Slug(releaseTitle) != slug { 43 htmx.HxRedirect(w, http.StatusMovedPermanently, routes.ReleasePath(domain.ReleaseID(id), releaseTitle)) 44 return 45 } 46 47 err = releaseview.Release(releaseview.ReleaseParams{ 48 Release: release, 49 }).Render(r.Context(), w) 50 if err != nil { 51 if errors.Is(err, context.Canceled) { 52 return 53 } 54 55 logger.Error("failed to render release page", "err", err) 56 http.Error(w, "Internal Server Error", http.StatusInternalServerError) 57 return 58 } 59 }