HEAVY: finish music service migration, tidy up services, more tests

This commit is contained in:
ari melody 2026-08-01 00:29:31 +01:00
parent 9e311df462
commit 90a671982c
Signed by: ari
GPG key ID: CF99829C92678188
47 changed files with 2698 additions and 902 deletions

View file

@ -10,6 +10,7 @@ import (
"arimelody-web/controller"
"arimelody-web/model"
"arimelody-web/model/app"
"arimelody-web/errors"
)
func Handler(app *app.AppState) http.Handler {
@ -21,9 +22,9 @@ func Handler(app *app.AppState) http.Handler {
mux.Handle("/v1/artist/", http.StripPrefix("/v1/artist", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var artistID = strings.Split(r.URL.Path[1:], "/")[0]
artist, err := controller.GetArtist(app.DB, artistID)
artist, err := app.MusicService.GetArtistByID(artistID)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
@ -63,9 +64,9 @@ func Handler(app *app.AppState) http.Handler {
mux.Handle("/v1/music/", http.StripPrefix("/v1/music", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var releaseID = strings.Split(r.URL.Path[1:], "/")[0]
release, err := controller.GetRelease(app.DB, releaseID, true)
release, err := app.MusicService.GetFullReleaseByID(releaseID)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
@ -105,9 +106,9 @@ func Handler(app *app.AppState) http.Handler {
mux.Handle("/v1/track/", http.StripPrefix("/v1/track", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var trackID = strings.Split(r.URL.Path[1:], "/")[0]
track, err := controller.GetTrack(app.DB, trackID)
track, err := app.MusicService.GetTrackByID(trackID)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
@ -187,7 +188,10 @@ func getSession(app *app.AppState, r *http.Request) (*model.Session, error) {
// fetch existing session
session, err := controller.GetSession(app, token)
if err != nil && !strings.Contains(err.Error(), "no rows") {
if errors.IsValidationError(err) {
return nil, err
}
if errors.IsNotExistError(err) {
return nil, fmt.Errorf("Failed to retrieve session: %v\n", err)
}

View file

@ -10,15 +10,15 @@ import (
"strings"
"time"
"arimelody-web/controller"
"arimelody-web/model"
"arimelody-web/model/app"
"arimelody-web/errors"
)
func ServeAllArtists(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var artists = []*model.Artist{}
artists, err := controller.GetAllArtists(app.DB)
artists, err := app.MusicService.GetAllArtists()
if err != nil {
fmt.Printf("WARN: Failed to serve all artists: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -53,9 +53,9 @@ func ServeArtist(app *app.AppState, artist *model.Artist) http.Handler {
)
session := r.Context().Value("session").(*model.Session)
show_hidden_releases := session != nil && session.Account != nil
showHiddenReleases := session != nil && session.Account != nil
dbCredits, err := controller.GetArtistCredits(app.DB, artist.ID, show_hidden_releases)
dbCredits, err := app.MusicService.GetArtistCredits(artist.ID, showHiddenReleases)
if err != nil {
fmt.Printf("WARN: Failed to retrieve artist credits for %s: %v\n", artist.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -91,31 +91,34 @@ func CreateArtist(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
var artist model.Artist
err := json.NewDecoder(r.Body).Decode(&artist)
type CreateArtistDTO struct {
ID string `json:"id"`
Name string `json:"name"`
}
dto := &CreateArtistDTO{}
err := json.NewDecoder(r.Body).Decode(dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
if artist.ID == "" {
http.Error(w, "Artist ID cannot be blank\n", http.StatusBadRequest)
return
}
if artist.Name == "" { artist.Name = artist.ID }
err = controller.CreateArtist(app.DB, &artist)
err = app.MusicService.CreateArtist(dto.ID, dto.Name, "", "")
if err != nil {
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Artist %s already exists\n", artist.ID), http.StatusBadRequest)
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to create artist %s: %s\n", artist.ID, err)
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Artist %s already exists\n", dto.ID), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to create artist %s: %s\n", dto.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
app.LogService.Info(model.LOG_ARTIST, "Artist \"%s\" created by \"%s\".", artist.Name, session.Account.Username)
app.LogService.Info(model.LOG_ARTIST, "Artist \"%s\" created by \"%s\".", dto.Name, session.Account.Username)
w.WriteHeader(http.StatusCreated)
})
@ -156,9 +159,13 @@ func UpdateArtist(app *app.AppState, artist *model.Artist) http.Handler {
}
}
err = controller.UpdateArtist(app.DB, artist)
err = app.MusicService.UpdateArtist(artist)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
@ -174,9 +181,13 @@ func DeleteArtist(app *app.AppState, artist *model.Artist) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
err := controller.DeleteArtist(app.DB, artist.ID)
err := app.MusicService.DeleteArtist(artist.ID)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}

View file

@ -13,6 +13,7 @@ import (
"arimelody-web/controller"
"arimelody-web/model"
"arimelody-web/model/app"
"arimelody-web/errors"
)
func ServeRelease(app *app.AppState, release *model.Release) http.Handler {
@ -39,50 +40,50 @@ func ServeRelease(app *app.AppState, release *model.Release) http.Handler {
}
type (
Track struct {
TrackDTO struct {
Title string `json:"title"`
Description string `json:"description"`
Lyrics string `json:"lyrics"`
}
Credit struct {
CreditDTO struct {
*model.Artist
Role string `json:"role"`
Primary bool `json:"primary"`
}
Release struct {
ReleaseDTO struct {
*model.Release
Tracks []Track `json:"tracks"`
Credits []Credit `json:"credits"`
Tracks []TrackDTO `json:"tracks"`
Credits []CreditDTO `json:"credits"`
Links map[string]string `json:"links"`
}
)
response := Release{
response := ReleaseDTO{
Release: release,
Tracks: []Track{},
Credits: []Credit{},
Tracks: []TrackDTO{},
Credits: []CreditDTO{},
Links: make(map[string]string),
}
if release.IsReleased() || privileged {
// get credits
credits, err := controller.GetReleaseCredits(app.DB, release.ID)
credits, err := app.MusicService.GetReleaseCredits(release.ID)
if err != nil {
fmt.Printf("WARN: Failed to serve release %s: Credits: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
for _, credit := range credits {
artist, err := controller.GetArtist(app.DB, credit.Artist.ID)
artist, err := app.MusicService.GetArtistByID(credit.Artist.ID)
if err != nil {
fmt.Printf("WARN: Failed to serve release %s: Artists: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
response.Credits = append(response.Credits, Credit{
response.Credits = append(response.Credits, CreditDTO{
Artist: artist,
Role: credit.Role,
Primary: credit.Primary,
@ -90,14 +91,14 @@ func ServeRelease(app *app.AppState, release *model.Release) http.Handler {
}
// get tracks
tracks, err := controller.GetReleaseTracks(app.DB, release.ID)
tracks, err := app.MusicService.GetReleaseTracks(release.ID)
if err != nil {
fmt.Printf("WARN: Failed to serve release %s: Tracks: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
for _, track := range tracks {
response.Tracks = append(response.Tracks, Track{
response.Tracks = append(response.Tracks, TrackDTO{
Title: track.Title,
Description: track.Description,
Lyrics: track.Lyrics,
@ -105,7 +106,7 @@ func ServeRelease(app *app.AppState, release *model.Release) http.Handler {
}
// get links
links, err := controller.GetReleaseLinks(app.DB, release.ID)
links, err := app.MusicService.GetReleaseLinks(release.ID)
if err != nil {
fmt.Printf("WARN: Failed to serve release %s: Links: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -129,7 +130,7 @@ func ServeRelease(app *app.AppState, release *model.Release) http.Handler {
func ServeCatalog(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
releases, err := controller.GetAllReleases(app.DB, false, 0, true)
releases, err := app.MusicService.GetAllFullReleases(false, 0)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
@ -192,47 +193,56 @@ func CreateRelease(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
var release model.Release
err := json.NewDecoder(r.Body).Decode(&release)
type CreateReleaseDTO struct {
ID string `json:"id"`
Title string `json:"title"`
ReleaseType string `json:"type"`
ReleaseDate time.Time `json:"release_date"`
Artwork string `json:"artwork"`
}
var dto CreateReleaseDTO
err := json.NewDecoder(r.Body).Decode(&dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
if release.ID == "" {
http.Error(w, "Release ID cannot be empty\n", http.StatusBadRequest)
return
}
if release.Title == "" { release.Title = release.ID }
if release.ReleaseType == "" { release.ReleaseType = model.Single }
if release.ReleaseDate != time.Unix(0, 0) {
release.ReleaseDate = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.UTC)
if dto.ReleaseType == "" { dto.ReleaseType = string(model.Single) }
if dto.ReleaseDate != time.Unix(0, 0) {
dto.ReleaseDate = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.UTC)
}
if dto.Artwork == "" { dto.Artwork = model.DEFAULT_RELEASE_ARTWORK_URL }
if release.Artwork == "" { release.Artwork = "/img/default-cover-art.png" }
err = controller.CreateRelease(app.DB, &release)
err = app.MusicService.CreateRelease(
dto.ID,
dto.Title,
dto.ReleaseType,
dto.ReleaseDate,
dto.Artwork,
)
if err != nil {
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Release %s already exists\n", release.ID), http.StatusBadRequest)
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to create release %s: %s\n", release.ID, err)
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Release %s already exists\n", dto.ID), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to create release %s: %s\n", dto.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
app.LogService.Info(model.LOG_MUSIC, "Release \"%s\" created by \"%s\".", release.ID, session.Account.Username)
app.LogService.Info(model.LOG_MUSIC, "Release \"%s\" created by \"%s\".", dto.ID, session.Account.Username)
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
encoder := json.NewEncoder(w)
encoder.SetIndent("", "\t")
err = encoder.Encode(release)
err = encoder.Encode(dto)
if err != nil {
fmt.Printf("WARN: Release %s created, but failed to send JSON response: %s\n", release.ID, err)
fmt.Printf("WARN: Release %s created, but failed to send JSON response: %s\n", dto.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
})
@ -297,9 +307,13 @@ func UpdateRelease(app *app.AppState, release *model.Release) http.Handler {
}
}
err = controller.UpdateRelease(app.DB, release)
err = app.MusicService.UpdateRelease(release)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
@ -315,28 +329,32 @@ func UpdateReleaseTracks(app *app.AppState, release *model.Release) http.Handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
var trackIDs = []string{}
err := json.NewDecoder(r.Body).Decode(&trackIDs)
var newTrackIDs = []string{}
err := json.NewDecoder(r.Body).Decode(&newTrackIDs)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
err = controller.UpdateReleaseTracks(app.DB, release.ID, trackIDs)
err = app.MusicService.UpdateReleaseTracks(release.ID, newTrackIDs)
if err != nil {
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Release cannot have duplicate tracks", http.StatusBadRequest)
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Release cannot have duplicate tracks", http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to update tracks for %s: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
app.LogService.Info(model.LOG_MUSIC, "Tracklist for release \"%s\" updated by \"%s\".", release.ID, session.Account.Username)
app.LogService.Info(model.LOG_MUSIC, "Release \"%s\" tracklist updated by \"%s\".", release.ID, session.Account.Username)
})
}
@ -344,22 +362,22 @@ func UpdateReleaseCredits(app *app.AppState, release *model.Release) http.Handle
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
type creditJSON struct {
type CreditDTO struct {
Artist string
Role string
Primary bool
}
var data []creditJSON
err := json.NewDecoder(r.Body).Decode(&data)
var dto []CreditDTO
err := json.NewDecoder(r.Body).Decode(&dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
var credits []*model.Credit
for _, credit := range data {
credits = append(credits, &model.Credit{
Artist: model.Artist{
var newCredits []*model.Credit
for _, credit := range dto {
newCredits = append(newCredits, &model.Credit{
Artist: &model.Artist{
ID: credit.Artist,
},
Role: credit.Role,
@ -367,21 +385,25 @@ func UpdateReleaseCredits(app *app.AppState, release *model.Release) http.Handle
})
}
err = controller.UpdateReleaseCredits(app.DB, release.ID, credits)
err = app.MusicService.UpdateReleaseCredits(release.ID, newCredits)
if err != nil {
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Artists may only be credited once", http.StatusBadRequest)
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Artists may only be credited once", http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to update credits for %s: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
app.LogService.Info(model.LOG_MUSIC, "Credits for release \"%s\" updated by \"%s\".", release.ID, session.Account.Username)
app.LogService.Info(model.LOG_MUSIC, "Release \"%s\" credits updated by \"%s\".", release.ID, session.Account.Username)
})
}
@ -389,28 +411,41 @@ func UpdateReleaseLinks(app *app.AppState, release *model.Release) http.Handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
var links = []*model.Link{}
err := json.NewDecoder(r.Body).Decode(&links)
type LinkDTO struct {
Name string `json:"name"`
URL string `json:"url"`
}
var dto = []LinkDTO{}
err := json.NewDecoder(r.Body).Decode(&dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
err = controller.UpdateReleaseLinks(app.DB, release.ID, links)
links := []*model.Link{}
for _, link := range dto {
links = append(links, &model.Link{ Name: link.Name, URL: link.URL })
}
err = app.MusicService.UpdateReleaseLinks(release.ID, links)
if err != nil {
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Release cannot have duplicate link names", http.StatusBadRequest)
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if strings.Contains(err.Error(), "no rows") {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Release cannot have duplicate link names", http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to update links for %s: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
app.LogService.Info(model.LOG_MUSIC, "Links for release \"%s\" updated by \"%s\".", release.ID, session.Account.Username)
app.LogService.Info(model.LOG_MUSIC, "Release \"%s\" links updated by \"%s\".", release.ID, session.Account.Username)
})
}
@ -418,9 +453,13 @@ func DeleteRelease(app *app.AppState, release *model.Release) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
err := controller.DeleteRelease(app.DB, release.ID)
err := app.MusicService.DeleteRelease(release.ID)
if err != nil {
if strings.Contains(err.Error(), "no rows") {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}

View file

@ -5,7 +5,7 @@ import (
"fmt"
"net/http"
"arimelody-web/controller"
"arimelody-web/errors"
"arimelody-web/model"
"arimelody-web/model/app"
)
@ -26,7 +26,7 @@ func ServeAllTracks(app *app.AppState) http.Handler {
var tracks = []Track{}
var dbTracks = []*model.Track{}
dbTracks, err := controller.GetAllTracks(app.DB)
dbTracks, err := app.MusicService.GetAllTracks()
if err != nil {
fmt.Printf("WARN: Failed to pull tracks from DB: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -52,7 +52,7 @@ func ServeAllTracks(app *app.AppState) http.Handler {
func ServeTrack(app *app.AppState, track *model.Track) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dbReleases, err := controller.GetTrackReleases(app.DB, track.ID, false)
dbReleases, err := app.MusicService.GetTrackReleases(track.ID)
if err != nil {
fmt.Printf("WARN: Failed to pull track releases for %s from DB: %s\n", track.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -78,26 +78,30 @@ func CreateTrack(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := r.Context().Value("session").(*model.Session)
var track model.Track
err := json.NewDecoder(r.Body).Decode(&track)
type CreateTrackDTO struct {
Title string `json:"title"`
Description string `json:"description"`
Lyrics string `json:"lyrics"`
}
var dto CreateTrackDTO
err := json.NewDecoder(r.Body).Decode(&dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
if track.Title == "" {
http.Error(w, "Track title cannot be empty\n", http.StatusBadRequest)
return
}
id, err := controller.CreateTrack(app.DB, &track)
id, err := app.MusicService.CreateTrack(dto.Title, dto.Description, dto.Lyrics, "")
if err != nil {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to create track: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
app.LogService.Info(model.LOG_MUSIC, "Track \"%s\" (%s) created by \"%s\".", track.Title, track.ID, session.Account.Username)
app.LogService.Info(model.LOG_MUSIC, "Track \"%s\" (%s) created by \"%s\".", dto.Title, id, session.Account.Username)
w.Header().Add("Content-Type", "text/plain")
w.WriteHeader(http.StatusCreated)
@ -114,19 +118,28 @@ func UpdateTrack(app *app.AppState, track *model.Track) http.Handler {
session := r.Context().Value("session").(*model.Session)
err := json.NewDecoder(r.Body).Decode(&track)
type UpdateTrackDTO struct {
Title string `json:"title"`
Description string `json:"description"`
Lyrics string `json:"lyrics"`
}
var dto UpdateTrackDTO
err := json.NewDecoder(r.Body).Decode(&dto)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
if track.Title == "" {
http.Error(w, "Track title cannot be empty\n", http.StatusBadRequest)
return
}
track.Title = dto.Title
track.Description = dto.Description
track.Lyrics = dto.Lyrics
err = controller.UpdateTrack(app.DB, track)
err = app.MusicService.UpdateTrack(track)
if err != nil {
if errors.IsValidationError(err) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Printf("WARN: Failed to update track %s: %s\n", track.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
@ -154,8 +167,12 @@ func DeleteTrack(app *app.AppState, track *model.Track) http.Handler {
session := r.Context().Value("session").(*model.Session)
var trackID = r.URL.Path[1:]
err := controller.DeleteTrack(app.DB, trackID)
err := app.MusicService.DeleteTrack(trackID)
if err != nil {
if errors.IsNotExistError(err) {
http.NotFound(w, r)
return
}
fmt.Printf("WARN: Failed to delete track %s: %s\n", trackID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}