move models, views, and controllers to root

This commit is contained in:
ari melody 2024-11-01 19:33:26 +00:00
parent f0d29126ab
commit 96cc64464f
Signed by: ari
GPG key ID: CF99829C92678188
21 changed files with 190 additions and 203 deletions

View file

@ -6,6 +6,7 @@
uploads/* uploads/*
test/ test/
tmp/ tmp/
res/
docker-compose.yml docker-compose.yml
Dockerfile Dockerfile
schema.sql schema.sql

2
.gitignore vendored
View file

@ -3,5 +3,5 @@
db/ db/
tmp/ tmp/
test/ test/
uploads/* uploads/
docker-compose-test.yml docker-compose-test.yml

View file

@ -6,15 +6,15 @@ import (
"strings" "strings"
"arimelody-web/global" "arimelody-web/global"
"arimelody-web/music/model" "arimelody-web/model"
"arimelody-web/music/controller" "arimelody-web/controller"
) )
func serveArtist() http.Handler { func serveArtist() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
slices := strings.Split(r.URL.Path[1:], "/") slices := strings.Split(r.URL.Path[1:], "/")
id := slices[0] id := slices[0]
artist, err := music.GetArtist(global.DB, id) artist, err := controller.GetArtist(global.DB, id)
if err != nil { if err != nil {
if artist == nil { if artist == nil {
http.NotFound(w, r) http.NotFound(w, r)
@ -25,7 +25,7 @@ func serveArtist() http.Handler {
return return
} }
credits, err := music.GetArtistCredits(global.DB, artist.ID, true) credits, err := controller.GetArtistCredits(global.DB, artist.ID, true)
if err != nil { if err != nil {
fmt.Printf("Error rendering admin track page for %s: %s\n", id, err) fmt.Printf("Error rendering admin track page for %s: %s\n", id, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

View file

@ -11,8 +11,8 @@ import (
"arimelody-web/discord" "arimelody-web/discord"
"arimelody-web/global" "arimelody-web/global"
musicDB "arimelody-web/music/controller" "arimelody-web/controller"
musicModel "arimelody-web/music/model" "arimelody-web/model"
) )
type loginData struct { type loginData struct {
@ -41,21 +41,21 @@ func Handler() http.Handler {
return return
} }
releases, err := musicDB.GetAllReleases(global.DB, false, 0, true) releases, err := controller.GetAllReleases(global.DB, false, 0, true)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull releases: %s\n", err) fmt.Printf("FATAL: Failed to pull releases: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
artists, err := musicDB.GetAllArtists(global.DB) artists, err := controller.GetAllArtists(global.DB)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull artists: %s\n", err) fmt.Printf("FATAL: Failed to pull artists: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
} }
tracks, err := musicDB.GetOrphanTracks(global.DB) tracks, err := controller.GetOrphanTracks(global.DB)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull orphan tracks: %s\n", err) fmt.Printf("FATAL: Failed to pull orphan tracks: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -63,9 +63,9 @@ func Handler() http.Handler {
} }
type IndexData struct { type IndexData struct {
Releases []*musicModel.Release Releases []*model.Release
Artists []*musicModel.Artist Artists []*model.Artist
Tracks []*musicModel.Track Tracks []*model.Track
} }
err = pages["index"].Execute(w, IndexData{ err = pages["index"].Execute(w, IndexData{

View file

@ -6,8 +6,8 @@ import (
"strings" "strings"
"arimelody-web/global" "arimelody-web/global"
db "arimelody-web/music/controller" "arimelody-web/controller"
"arimelody-web/music/model" "arimelody-web/model"
) )
func serveRelease() http.Handler { func serveRelease() http.Handler {
@ -15,7 +15,7 @@ func serveRelease() http.Handler {
slices := strings.Split(r.URL.Path[1:], "/") slices := strings.Split(r.URL.Path[1:], "/")
releaseID := slices[0] releaseID := slices[0]
release, err := db.GetRelease(global.DB, releaseID, true) release, err := controller.GetRelease(global.DB, releaseID, true)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -81,7 +81,7 @@ func serveEditCredits(release *model.Release) http.Handler {
func serveAddCredit(release *model.Release) http.Handler { func serveAddCredit(release *model.Release) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
artists, err := db.GetArtistsNotOnRelease(global.DB, release.ID) artists, err := controller.GetArtistsNotOnRelease(global.DB, release.ID)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull artists not on %s: %s\n", release.ID, err) fmt.Printf("FATAL: Failed to pull artists not on %s: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -108,7 +108,7 @@ func serveAddCredit(release *model.Release) http.Handler {
func serveNewCredit() http.Handler { func serveNewCredit() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
artistID := strings.Split(r.URL.Path, "/")[3] artistID := strings.Split(r.URL.Path, "/")[3]
artist, err := db.GetArtist(global.DB, artistID) artist, err := controller.GetArtist(global.DB, artistID)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull artists %s: %s\n", artistID, err) fmt.Printf("FATAL: Failed to pull artists %s: %s\n", artistID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -152,7 +152,7 @@ func serveEditTracks(release *model.Release) http.Handler {
func serveAddTrack(release *model.Release) http.Handler { func serveAddTrack(release *model.Release) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tracks, err := db.GetTracksNotOnRelease(global.DB, release.ID) tracks, err := controller.GetTracksNotOnRelease(global.DB, release.ID)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull tracks not on %s: %s\n", release.ID, err) fmt.Printf("FATAL: Failed to pull tracks not on %s: %s\n", release.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -180,7 +180,7 @@ func serveAddTrack(release *model.Release) http.Handler {
func serveNewTrack() http.Handler { func serveNewTrack() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
trackID := strings.Split(r.URL.Path, "/")[3] trackID := strings.Split(r.URL.Path, "/")[3]
track, err := db.GetTrack(global.DB, trackID) track, err := controller.GetTrack(global.DB, trackID)
if err != nil { if err != nil {
fmt.Printf("Error rendering new track component for %s: %s\n", trackID, err) fmt.Printf("Error rendering new track component for %s: %s\n", trackID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

View file

@ -6,15 +6,15 @@ import (
"strings" "strings"
"arimelody-web/global" "arimelody-web/global"
"arimelody-web/music/model" "arimelody-web/model"
"arimelody-web/music/controller" "arimelody-web/controller"
) )
func serveTrack() http.Handler { func serveTrack() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
slices := strings.Split(r.URL.Path[1:], "/") slices := strings.Split(r.URL.Path[1:], "/")
id := slices[0] id := slices[0]
track, err := music.GetTrack(global.DB, id) track, err := controller.GetTrack(global.DB, id)
if err != nil { if err != nil {
fmt.Printf("Error rendering admin track page for %s: %s\n", id, err) fmt.Printf("Error rendering admin track page for %s: %s\n", id, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -25,7 +25,7 @@ func serveTrack() http.Handler {
return return
} }
releases, err := music.GetTrackReleases(global.DB, track.ID, true) releases, err := controller.GetTrackReleases(global.DB, track.ID, true)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull releases for %s: %s\n", id, err) fmt.Printf("FATAL: Failed to pull releases for %s: %s\n", id, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

View file

@ -7,8 +7,7 @@ import (
"arimelody-web/admin" "arimelody-web/admin"
"arimelody-web/global" "arimelody-web/global"
music "arimelody-web/music/controller" "arimelody-web/controller"
musicView "arimelody-web/music/view"
) )
func Handler() http.Handler { func Handler() http.Handler {
@ -18,7 +17,7 @@ func Handler() http.Handler {
mux.Handle("/v1/artist/", http.StripPrefix("/v1/artist", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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] var artistID = strings.Split(r.URL.Path[1:], "/")[0]
artist, err := music.GetArtist(global.DB, artistID) artist, err := controller.GetArtist(global.DB, artistID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -60,7 +59,7 @@ func Handler() http.Handler {
mux.Handle("/v1/music/", http.StripPrefix("/v1/music", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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] var releaseID = strings.Split(r.URL.Path[1:], "/")[0]
release, err := music.GetRelease(global.DB, releaseID, true) release, err := controller.GetRelease(global.DB, releaseID, true)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -74,7 +73,7 @@ func Handler() http.Handler {
switch r.Method { switch r.Method {
case http.MethodGet: case http.MethodGet:
// GET /api/v1/music/{id} // GET /api/v1/music/{id}
musicView.ServeRelease(release).ServeHTTP(w, r) ServeRelease(release).ServeHTTP(w, r)
case http.MethodPut: case http.MethodPut:
// PUT /api/v1/music/{id} (admin) // PUT /api/v1/music/{id} (admin)
admin.MustAuthorise(UpdateRelease(release)).ServeHTTP(w, r) admin.MustAuthorise(UpdateRelease(release)).ServeHTTP(w, r)
@ -102,7 +101,7 @@ func Handler() http.Handler {
mux.Handle("/v1/track/", http.StripPrefix("/v1/track", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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] var trackID = strings.Split(r.URL.Path[1:], "/")[0]
track, err := music.GetTrack(global.DB, trackID) track, err := controller.GetTrack(global.DB, trackID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)

View file

@ -12,15 +12,14 @@ import (
"arimelody-web/admin" "arimelody-web/admin"
"arimelody-web/global" "arimelody-web/global"
db "arimelody-web/music/controller" "arimelody-web/controller"
music "arimelody-web/music/controller" "arimelody-web/model"
"arimelody-web/music/model"
) )
func ServeAllArtists() http.Handler { func ServeAllArtists() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var artists = []*model.Artist{} var artists = []*model.Artist{}
artists, err := db.GetAllArtists(global.DB) artists, err := controller.GetAllArtists(global.DB)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to serve all artists: %s\n", err) fmt.Printf("FATAL: Failed to serve all artists: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -55,7 +54,7 @@ func ServeArtist(artist *model.Artist) http.Handler {
show_hidden_releases := admin.GetSession(r) != nil show_hidden_releases := admin.GetSession(r) != nil
var dbCredits []*model.Credit var dbCredits []*model.Credit
dbCredits, err := db.GetArtistCredits(global.DB, artist.ID, show_hidden_releases) dbCredits, err := controller.GetArtistCredits(global.DB, artist.ID, show_hidden_releases)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to retrieve artist credits for %s: %s\n", artist.ID, err) fmt.Printf("FATAL: Failed to retrieve artist credits for %s: %s\n", artist.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -100,7 +99,7 @@ func CreateArtist() http.Handler {
} }
if artist.Name == "" { artist.Name = artist.ID } if artist.Name == "" { artist.Name = artist.ID }
err = music.CreateArtist(global.DB, &artist) err = controller.CreateArtist(global.DB, &artist)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "duplicate key") { if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Artist %s already exists\n", artist.ID), http.StatusBadRequest) http.Error(w, fmt.Sprintf("Artist %s already exists\n", artist.ID), http.StatusBadRequest)
@ -148,7 +147,7 @@ func UpdateArtist(artist *model.Artist) http.Handler {
} }
} }
err = music.UpdateArtist(global.DB, artist) err = controller.UpdateArtist(global.DB, artist)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -162,7 +161,7 @@ func UpdateArtist(artist *model.Artist) http.Handler {
func DeleteArtist(artist *model.Artist) http.Handler { func DeleteArtist(artist *model.Artist) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := music.DeleteArtist(global.DB, artist.ID) err := controller.DeleteArtist(global.DB, artist.ID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)

View file

@ -12,13 +12,109 @@ import (
"arimelody-web/admin" "arimelody-web/admin"
"arimelody-web/global" "arimelody-web/global"
music "arimelody-web/music/controller" "arimelody-web/controller"
"arimelody-web/music/model" "arimelody-web/model"
) )
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
}
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"`
}
)
response := Release{
Release: release,
Tracks: []Track{},
Credits: []Credit{},
Links: make(map[string]string),
}
if authorised || release.IsReleased() {
// get credits
credits, err := controller.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 := controller.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 := controller.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 := controller.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 ServeCatalog() http.Handler { func ServeCatalog() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
releases, err := music.GetAllReleases(global.DB, false, 0, true) releases, err := controller.GetAllReleases(global.DB, false, 0, true)
if err != nil { if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return return
@ -95,7 +191,7 @@ func CreateRelease() http.Handler {
if release.Artwork == "" { release.Artwork = "/img/default-cover-art.png" } if release.Artwork == "" { release.Artwork = "/img/default-cover-art.png" }
err = music.CreateRelease(global.DB, &release) err = controller.CreateRelease(global.DB, &release)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "duplicate key") { if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, fmt.Sprintf("Release %s already exists\n", release.ID), http.StatusBadRequest) http.Error(w, fmt.Sprintf("Release %s already exists\n", release.ID), http.StatusBadRequest)
@ -173,7 +269,7 @@ func UpdateRelease(release *model.Release) http.Handler {
} }
} }
err = music.UpdateRelease(global.DB, release) err = controller.UpdateRelease(global.DB, release)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -194,7 +290,7 @@ func UpdateReleaseTracks(release *model.Release) http.Handler {
return return
} }
err = music.UpdateReleaseTracks(global.DB, release.ID, trackIDs) err = controller.UpdateReleaseTracks(global.DB, release.ID, trackIDs)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -231,7 +327,7 @@ func UpdateReleaseCredits(release *model.Release) http.Handler {
}) })
} }
err = music.UpdateReleaseCredits(global.DB, release.ID, credits) err = controller.UpdateReleaseCredits(global.DB, release.ID, credits)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "duplicate key") { if strings.Contains(err.Error(), "duplicate key") {
http.Error(w, "Artists may only be credited once\n", http.StatusBadRequest) http.Error(w, "Artists may only be credited once\n", http.StatusBadRequest)
@ -261,7 +357,7 @@ func UpdateReleaseLinks(release *model.Release) http.Handler {
return return
} }
err = music.UpdateReleaseLinks(global.DB, release.ID, links) err = controller.UpdateReleaseLinks(global.DB, release.ID, links)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)
@ -275,7 +371,7 @@ func UpdateReleaseLinks(release *model.Release) http.Handler {
func DeleteRelease(release *model.Release) http.Handler { func DeleteRelease(release *model.Release) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := music.DeleteRelease(global.DB, release.ID) err := controller.DeleteRelease(global.DB, release.ID)
if err != nil { if err != nil {
if strings.Contains(err.Error(), "no rows") { if strings.Contains(err.Error(), "no rows") {
http.NotFound(w, r) http.NotFound(w, r)

View file

@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"arimelody-web/global" "arimelody-web/global"
music "arimelody-web/music/controller" "arimelody-web/controller"
"arimelody-web/music/model" "arimelody-web/model"
) )
type ( type (
@ -26,7 +26,7 @@ func ServeAllTracks() http.Handler {
var tracks = []Track{} var tracks = []Track{}
var dbTracks = []*model.Track{} var dbTracks = []*model.Track{}
dbTracks, err := music.GetAllTracks(global.DB) dbTracks, err := controller.GetAllTracks(global.DB)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull tracks from DB: %s\n", err) fmt.Printf("FATAL: Failed to pull tracks from DB: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -50,7 +50,7 @@ func ServeAllTracks() http.Handler {
func ServeTrack(track *model.Track) http.Handler { func ServeTrack(track *model.Track) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dbReleases, err := music.GetTrackReleases(global.DB, track.ID, false) dbReleases, err := controller.GetTrackReleases(global.DB, track.ID, false)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull track releases for %s from DB: %s\n", track.ID, err) fmt.Printf("FATAL: Failed to pull track releases for %s from DB: %s\n", track.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -89,7 +89,7 @@ func CreateTrack() http.Handler {
return return
} }
id, err := music.CreateTrack(global.DB, &track) id, err := controller.CreateTrack(global.DB, &track)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to create track: %s\n", err) fmt.Printf("FATAL: Failed to create track: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -120,7 +120,7 @@ func UpdateTrack(track *model.Track) http.Handler {
return return
} }
err = music.UpdateTrack(global.DB, track) err = controller.UpdateTrack(global.DB, track)
if err != nil { if err != nil {
fmt.Printf("Failed to update track %s: %s\n", track.ID, err) fmt.Printf("Failed to update track %s: %s\n", track.ID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -143,7 +143,7 @@ func DeleteTrack(track *model.Track) http.Handler {
} }
var trackID = r.URL.Path[1:] var trackID = r.URL.Path[1:]
err := music.DeleteTrack(global.DB, trackID) err := controller.DeleteTrack(global.DB, trackID)
if err != nil { if err != nil {
fmt.Printf("Failed to delete track %s: %s\n", trackID, err) fmt.Printf("Failed to delete track %s: %s\n", trackID, err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

View file

@ -1,7 +1,7 @@
package music package controller
import ( import (
"arimelody-web/music/model" "arimelody-web/model"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
) )

View file

@ -1,10 +1,10 @@
package music package controller
import ( import (
"errors" "errors"
"fmt" "fmt"
"arimelody-web/music/model" "arimelody-web/model"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
) )

View file

@ -1,7 +1,7 @@
package music package controller
import ( import (
"arimelody-web/music/model" "arimelody-web/model"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
) )

View file

@ -12,7 +12,7 @@ import (
"arimelody-web/admin" "arimelody-web/admin"
"arimelody-web/api" "arimelody-web/api"
"arimelody-web/global" "arimelody-web/global"
musicView "arimelody-web/music/view" "arimelody-web/view"
"arimelody-web/templates" "arimelody-web/templates"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
@ -49,7 +49,7 @@ func createServeMux() *http.ServeMux {
mux.Handle("/admin/", http.StripPrefix("/admin", admin.Handler())) mux.Handle("/admin/", http.StripPrefix("/admin", admin.Handler()))
mux.Handle("/api/", http.StripPrefix("/api", api.Handler())) mux.Handle("/api/", http.StripPrefix("/api", api.Handler()))
mux.Handle("/music/", http.StripPrefix("/music", musicView.Handler())) mux.Handle("/music/", http.StripPrefix("/music", view.MusicHandler()))
mux.Handle("/uploads/", http.StripPrefix("/uploads", staticHandler("uploads"))) mux.Handle("/uploads/", http.StripPrefix("/uploads", staticHandler("uploads")))
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/" || r.URL.Path == "/index.html" { if r.URL.Path == "/" || r.URL.Path == "/index.html" {

View file

@ -1,136 +0,0 @@
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
}
})
}

View file

@ -4,15 +4,16 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"arimelody-web/admin"
"arimelody-web/controller"
"arimelody-web/global" "arimelody-web/global"
music "arimelody-web/music/controller" "arimelody-web/model"
"arimelody-web/music/model"
"arimelody-web/templates" "arimelody-web/templates"
) )
// HTTP HANDLER METHODS // HTTP HANDLER METHODS
func Handler() http.Handler { func MusicHandler() http.Handler {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@ -21,7 +22,7 @@ func Handler() http.Handler {
return return
} }
release, err := music.GetRelease(global.DB, r.URL.Path[1:], true) release, err := controller.GetRelease(global.DB, r.URL.Path[1:], true)
if err != nil { if err != nil {
http.NotFound(w, r) http.NotFound(w, r)
return return
@ -35,7 +36,7 @@ func Handler() http.Handler {
func ServeCatalog() http.Handler { func ServeCatalog() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
releases, err := music.GetAllReleases(global.DB, true, 0, true) releases, err := controller.GetAllReleases(global.DB, true, 0, true)
if err != nil { if err != nil {
fmt.Printf("FATAL: Failed to pull releases for catalog: %s\n", err) fmt.Printf("FATAL: Failed to pull releases for catalog: %s\n", err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@ -54,3 +55,30 @@ func ServeCatalog() http.Handler {
} }
}) })
} }
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
}
})
}