lyrics

lyrics
git clone git://brookjeynes.dev/bjeynes/lyrics.git
Log | Files | Refs

song.go (1382B)


      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 	"lyrics/internal/server/ui/views/song"
     12 	"net/http"
     13 	"strconv"
     14 )
     15 
     16 func (ss *ServerState) Song(w http.ResponseWriter, r *http.Request) {
     17 	logger := ss.logger.With("handler", "Song")
     18 
     19 	idStr := r.PathValue("id")
     20 	id, err := strconv.Atoi(idStr)
     21 	if err != nil {
     22 		logger.Error("failed to convert song 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 	s, err := db.Song(ss.db, domain.SongID(id))
     31 	if err != nil {
     32 		logger.Error("failed to get song", "err", err)
     33 		htmx.HxError(w, http.StatusInternalServerError, fmt.Sprintf("failed to query for song '%s'", slug))
     34 		return
     35 	}
     36 
     37 	songTitle := s.Title
     38 	if s.LatinTitle != nil {
     39 		songTitle = *s.LatinTitle
     40 	}
     41 
     42 	if domain.Slug(songTitle) != slug {
     43 		htmx.HxRedirect(w, http.StatusMovedPermanently, routes.SongPath(domain.SongID(id), songTitle))
     44 		return
     45 	}
     46 
     47 	err = song.Song(song.SongParams{Song: s}).Render(r.Context(), w)
     48 	if err != nil {
     49 		if errors.Is(err, context.Canceled) {
     50 			return
     51 		}
     52 
     53 		logger.Error("failed to render song page", "err", err)
     54 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
     55 		return
     56 	}
     57 }