HEAVY: finish music service migration, tidy up services, more tests
This commit is contained in:
parent
9e311df462
commit
90a671982c
47 changed files with 2698 additions and 902 deletions
171
api/release.go
171
api/release.go
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue