arimelody-web/api/track.go

183 lines
6.2 KiB
Go
Raw Permalink Normal View History

package api
import (
"encoding/json"
"fmt"
"net/http"
"arimelody-web/errors"
"arimelody-web/model"
"arimelody-web/model/app"
)
2024-09-02 00:15:23 +01:00
type (
Track struct {
2024-09-03 08:07:45 +01:00
*model.Track
Releases []string `json:"releases"`
2024-09-02 00:15:23 +01:00
}
)
func ServeAllTracks(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2024-09-02 00:15:23 +01:00
type Track struct {
ID string `json:"id"`
Title string `json:"title"`
}
2024-09-02 00:15:23 +01:00
var tracks = []Track{}
2024-09-02 00:15:23 +01:00
var dbTracks = []*model.Track{}
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)
}
2024-09-02 00:15:23 +01:00
for _, track := range dbTracks {
tracks = append(tracks, Track{
ID: track.ID,
Title: track.Title,
})
}
w.Header().Add("Content-Type", "application/json")
2024-12-02 12:47:42 +00:00
encoder := json.NewEncoder(w)
encoder.SetIndent("", "\t")
err = encoder.Encode(tracks)
if err != nil {
fmt.Printf("WARN: Failed to serve all tracks: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
})
}
func ServeTrack(app *app.AppState, track *model.Track) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
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)
}
2024-09-03 08:07:45 +01:00
releases := []string{}
for _, release := range dbReleases {
releases = append(releases, release.ID)
}
w.Header().Add("Content-Type", "application/json")
2024-12-02 12:47:42 +00:00
encoder := json.NewEncoder(w)
encoder.SetIndent("", "\t")
err = encoder.Encode(Track{ track, releases })
if err != nil {
fmt.Printf("WARN: Failed to serve track %s: %s\n", track.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
})
}
func CreateTrack(app *app.AppState) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2025-02-07 16:40:58 +00:00
session := r.Context().Value("session").(*model.Session)
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
}
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\".", dto.Title, id, session.Account.Username)
2025-02-07 16:40:58 +00:00
w.Header().Add("Content-Type", "text/plain")
w.WriteHeader(http.StatusCreated)
2024-09-02 00:15:23 +01:00
w.Write([]byte(id))
})
}
func UpdateTrack(app *app.AppState, track *model.Track) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2025-02-07 16:40:58 +00:00
if r.URL.Path == "/" {
http.NotFound(w, r)
return
}
2025-02-07 16:40:58 +00:00
session := r.Context().Value("session").(*model.Session)
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
}
track.Title = dto.Title
track.Description = dto.Description
track.Lyrics = dto.Lyrics
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
}
2026-07-31 10:02:34 +01:00
app.LogService.Info(model.LOG_MUSIC, "Track \"%s\" (%s) updated by \"%s\".", track.Title, track.ID, session.Account.Username)
2025-02-07 16:40:58 +00:00
w.Header().Add("Content-Type", "application/json")
2024-12-02 12:47:42 +00:00
encoder := json.NewEncoder(w)
encoder.SetIndent("", "\t")
err = encoder.Encode(track)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
})
}
func DeleteTrack(app *app.AppState, track *model.Track) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2025-02-07 16:40:58 +00:00
if r.URL.Path == "/" {
http.NotFound(w, r)
return
}
2025-02-07 16:40:58 +00:00
session := r.Context().Value("session").(*model.Session)
var trackID = r.URL.Path[1:]
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)
}
2025-02-07 16:40:58 +00:00
2026-07-31 10:02:34 +01:00
app.LogService.Info(model.LOG_MUSIC, "Track \"%s\" (%s) deleted by \"%s\".", track.Title, track.ID, session.Account.Username)
})
}