legend has it that if you refactor your code enough times, one day you will finally be happy
251 lines
9.5 KiB
Go
251 lines
9.5 KiB
Go
package music
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"arimelody-web/admin/core"
|
|
"arimelody-web/admin/templates"
|
|
"arimelody-web/controller"
|
|
"arimelody-web/model"
|
|
)
|
|
|
|
func serveReleases(app *model.AppState) http.Handler {
|
|
mux := http.NewServeMux()
|
|
|
|
mux.HandleFunc("/{id}/", func(w http.ResponseWriter, r *http.Request) {
|
|
releaseID := r.PathValue("id")
|
|
release, err := controller.GetRelease(app.DB, releaseID, true)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "no rows") {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch full release data for %s: %s\n", releaseID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
|
|
mux.Handle("/{id}/editcredits", serveEditCredits(release))
|
|
mux.Handle("/{id}/addcredit", serveAddCredit(app, release))
|
|
mux.Handle("/{id}/newcredit", serveNewCredit(app))
|
|
|
|
mux.Handle("/{id}/editlinks", serveEditLinks(release))
|
|
|
|
mux.Handle("/{id}/edittracks", serveEditTracks(release))
|
|
mux.Handle("/{id}/addtrack", serveAddTrack(app, release))
|
|
mux.Handle("/{id}/newtrack", serveNewTrack(app))
|
|
|
|
mux.ServeHTTP(w, r)
|
|
})
|
|
|
|
mux.HandleFunc("/{id}", func(w http.ResponseWriter, r *http.Request) {
|
|
serveRelease(app, r.PathValue("id")).ServeHTTP(w, r)
|
|
})
|
|
|
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
session := r.Context().Value("session").(*model.Session)
|
|
|
|
type ReleasesData struct {
|
|
core.AdminPageData
|
|
Releases []*model.Release
|
|
}
|
|
|
|
releases, err := controller.GetAllReleases(app.DB, false, 0, true)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch releases: %s\n", err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
err = templates.ReleasesTemplate.Execute(w, ReleasesData{
|
|
AdminPageData: core.AdminPageData{
|
|
Path: r.URL.Path,
|
|
Session: session,
|
|
},
|
|
Releases: releases,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve releases page: %s\n", err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
})
|
|
|
|
return mux
|
|
}
|
|
|
|
func serveRelease(app *model.AppState, releaseID string) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
session := r.Context().Value("session").(*model.Session)
|
|
|
|
release, err := controller.GetRelease(app.DB, releaseID, true)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "no rows") {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch full release data for %s: %s\n", releaseID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
type ReleaseResponse struct {
|
|
core.AdminPageData
|
|
Release *model.Release
|
|
}
|
|
|
|
for i, track := range release.Tracks { track.Number = i + 1 }
|
|
|
|
err = templates.EditReleaseTemplate.Execute(w, ReleaseResponse{
|
|
AdminPageData: core.AdminPageData{ Path: r.URL.Path, Session: session },
|
|
Release: release,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve admin release page for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveEditCredits(release *model.Release) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err := templates.EditCreditsTemplate.Execute(w, release)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve edit credits component for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveAddCredit(app *model.AppState, release *model.Release) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
artists, err := controller.GetArtistsNotOnRelease(app.DB, release.ID)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch artists not on %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
type response struct {
|
|
ReleaseID string;
|
|
Artists []*model.Artist
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err = templates.AddCreditTemplate.Execute(w, response{
|
|
ReleaseID: release.ID,
|
|
Artists: artists,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve add credits component for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveNewCredit(app *model.AppState) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
split := strings.Split(r.URL.Path, "/")
|
|
artistID := split[len(split) - 1]
|
|
artist, err := controller.GetArtist(app.DB, artistID)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch artist %s: %s\n", artistID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if artist == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err = templates.NewCreditTemplate.Execute(w, artist)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve new credit component for %s: %s\n", artist.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveEditLinks(release *model.Release) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err := templates.EditLinksTemplate.Execute(w, release)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve edit links component for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveEditTracks(release *model.Release) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/html")
|
|
|
|
type editTracksData struct { Release *model.Release }
|
|
|
|
for i, track := range release.Tracks { track.Number = i + 1 }
|
|
|
|
err := templates.EditTracksTemplate.Execute(w, editTracksData{ Release: release })
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve edit tracks component for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveAddTrack(app *model.AppState, release *model.Release) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
tracks, err := controller.GetTracksNotOnRelease(app.DB, release.ID)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch tracks not on %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
type response struct {
|
|
ReleaseID string;
|
|
Tracks []*model.Track
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err = templates.AddTrackTemplate.Execute(w, response{
|
|
ReleaseID: release.ID,
|
|
Tracks: tracks,
|
|
})
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to add tracks component for %s: %s\n", release.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|
|
|
|
func serveNewTrack(app *model.AppState) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
split := strings.Split(r.URL.Path, "/")
|
|
trackID := split[len(split) - 1]
|
|
track, err := controller.GetTrack(app.DB, trackID)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch track %s: %s\n", trackID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
if track == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
err = templates.NewTrackTemplate.Execute(w, track)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to serve new track component for %s: %s\n", track.ID, err)
|
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
}
|
|
})
|
|
}
|