package view import ( "encoding/json" "fmt" "net/http" "arimelody-web/admin" "arimelody-web/global" "arimelody-web/music/model" db "arimelody-web/music/controller" "arimelody-web/templates" ) type ( Track struct { Title string `json:"title"` Description string `json:"description"` Lyrics string `json:"lyrics"` } Credit struct { *model.Artist Role string `json:"role"` Primary bool `json:"primary"` } Release struct { *model.Release Tracks []Track `json:"tracks"` Credits []Credit `json:"credits"` Links map[string]string `json:"links"` } ) func ServeRelease(release *model.Release) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // only allow authorised users to view hidden releases authorised := admin.GetSession(r) != nil if !authorised && !release.Visible { http.NotFound(w, r) return } response := Release{ Release: release, Tracks: []Track{}, Credits: []Credit{}, Links: make(map[string]string), } if authorised || release.IsReleased() { // get credits credits, err := db.GetReleaseCredits(global.DB, release.ID) if err != nil { fmt.Printf("FATAL: 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 := db.GetArtist(global.DB, credit.Artist.ID) if err != nil { fmt.Printf("FATAL: 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{ Artist: artist, Role: credit.Role, Primary: credit.Primary, }) } // get tracks tracks, err := db.GetReleaseTracks(global.DB, release.ID) if err != nil { fmt.Printf("FATAL: 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{ Title: track.Title, Description: track.Description, Lyrics: track.Lyrics, }) } // get links links, err := db.GetReleaseLinks(global.DB, release.ID) if err != nil { fmt.Printf("FATAL: Failed to serve release %s: Links: %s\n", release.ID, err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } for _, link := range links { response.Links[link.Name] = link.URL } } w.Header().Add("Content-Type", "application/json") err := json.NewEncoder(w).Encode(response) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } }) } func ServeGateway(release *model.Release) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // only allow authorised users to view hidden releases authorised := admin.GetSession(r) != nil if !authorised && !release.Visible { http.NotFound(w, r) return } response := *release if authorised || release.IsReleased() { response.Tracks = release.Tracks response.Credits = release.Credits response.Links = release.Links } err := templates.Pages["music-gateway"].Execute(w, response) if err != nil { fmt.Printf("Error rendering music gateway for %s: %s\n", release.ID, err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } }) }