package server import ( "net/http" "music-server/internal/backend" "github.com/google/uuid" "github.com/labstack/echo/v5" ) type LibraryHandler struct { library *backend.LibraryService } func NewLibraryHandler(library *backend.LibraryService) *LibraryHandler { return &LibraryHandler{library: library} } // uuidParam parses the :uuid path parameter. func uuidParam(ctx *echo.Context) (uuid.UUID, error) { id, err := uuid.Parse(ctx.Param("uuid")) if err != nil { return uuid.Nil, echo.NewHTTPError(http.StatusBadRequest, "invalid uuid") } return id, nil } // GetSoundtracks godoc // // @Summary List soundtracks // @Description Returns all soundtracks with their UUIDs, sorted by name // @Tags library // @Produce json // @Success 200 {array} backend.Soundtrack // @Router /api/v1/soundtracks [get] func (l *LibraryHandler) GetSoundtracks(ctx *echo.Context) error { soundtracks, err := l.library.Soundtracks(ctx.Request().Context()) if err != nil { return songError(err) } return ctx.JSON(http.StatusOK, soundtracks) } // GetSoundtrack godoc // // @Summary Get soundtrack // @Description Returns a soundtrack with its songs // @Tags library // @Produce json // @Param uuid path string true "Soundtrack UUID" // @Success 200 {object} backend.SoundtrackWithSongList // @Failure 400 {string} string "invalid uuid" // @Failure 404 {string} string "not found" // @Router /api/v1/soundtracks/{uuid} [get] func (l *LibraryHandler) GetSoundtrack(ctx *echo.Context) error { id, err := uuidParam(ctx) if err != nil { return err } soundtrack, err := l.library.Soundtrack(ctx.Request().Context(), id) if err != nil { return songError(err) } return ctx.JSON(http.StatusOK, soundtrack) } // GetSong godoc // // @Summary Get song // @Description Returns information about a song // @Tags library // @Produce json // @Param uuid path string true "Song UUID" // @Success 200 {object} backend.Song // @Failure 400 {string} string "invalid uuid" // @Failure 404 {string} string "not found" // @Router /api/v1/songs/{uuid} [get] func (l *LibraryHandler) GetSong(ctx *echo.Context) error { id, err := uuidParam(ctx) if err != nil { return err } song, err := l.library.Song(ctx.Request().Context(), id) if err != nil { return songError(err) } return ctx.JSON(http.StatusOK, song) } // GetSongFile godoc // // @Summary Stream song // @Description Returns the audio file of a song. Supports Range requests. // @Tags library // @Produce audio/mpeg // @Param uuid path string true "Song UUID" // @Success 200 {file} file // @Success 206 {file} file // @Failure 400 {string} string "invalid uuid" // @Failure 404 {string} string "not found" // @Failure 423 {string} string "Syncing is in progress" // @Router /api/v1/songs/{uuid}/file [get] func (l *LibraryHandler) GetSongFile(ctx *echo.Context) error { id, err := uuidParam(ctx) if err != nil { return err } path, err := l.library.SongPath(ctx.Request().Context(), id) return serveSong(ctx, path, err) }