merge main into dev
This commit is contained in:
commit
819ec891e7
|
@ -3,10 +3,11 @@
|
||||||
.air.toml/
|
.air.toml/
|
||||||
.gitattributes
|
.gitattributes
|
||||||
.gitignore
|
.gitignore
|
||||||
uploads/*
|
uploads/
|
||||||
test/
|
test/
|
||||||
tmp/
|
tmp/
|
||||||
db/
|
db/
|
||||||
|
res/
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
docker-compose-test.yml
|
docker-compose-test.yml
|
||||||
Dockerfile
|
Dockerfile
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,5 +3,5 @@
|
||||||
db/
|
db/
|
||||||
tmp/
|
tmp/
|
||||||
test/
|
test/
|
||||||
uploads/*
|
uploads/
|
||||||
docker-compose-test.yml
|
docker-compose-test.yml
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
11
api/api.go
11
api/api.go
|
@ -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 {
|
||||||
|
@ -24,7 +23,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)
|
||||||
|
@ -66,7 +65,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)
|
||||||
|
@ -80,7 +79,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)
|
||||||
|
@ -108,7 +107,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)
|
||||||
|
|
|
@ -8,18 +8,18 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"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)
|
||||||
|
@ -38,6 +38,10 @@ func ServeArtist(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) {
|
||||||
type (
|
type (
|
||||||
creditJSON struct {
|
creditJSON struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
ReleaseDate time.Time `json:"releaseDate" db:"release_date"`
|
||||||
|
Artwork string `json:"artwork"`
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Primary bool `json:"primary"`
|
Primary bool `json:"primary"`
|
||||||
}
|
}
|
||||||
|
@ -50,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)
|
||||||
|
@ -60,6 +64,10 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
||||||
var credits = map[string]creditJSON{}
|
var credits = map[string]creditJSON{}
|
||||||
for _, credit := range dbCredits {
|
for _, credit := range dbCredits {
|
||||||
credits[credit.Release.ID] = creditJSON{
|
credits[credit.Release.ID] = creditJSON{
|
||||||
|
ID: credit.Release.ID,
|
||||||
|
Title: credit.Release.Title,
|
||||||
|
ReleaseDate: credit.Release.ReleaseDate,
|
||||||
|
Artwork: credit.Release.Artwork,
|
||||||
Role: credit.Role,
|
Role: credit.Role,
|
||||||
Primary: credit.Primary,
|
Primary: credit.Primary,
|
||||||
}
|
}
|
||||||
|
@ -91,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)
|
||||||
|
@ -139,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)
|
||||||
|
@ -153,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)
|
||||||
|
|
114
api/release.go
114
api/release.go
|
@ -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)
|
||||||
|
|
14
api/track.go
14
api/track.go
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func GetArtistsNotOnRelease(db *sqlx.DB, releaseID string) ([]*model.Artist, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetArtistCredits(db *sqlx.DB, artistID string, show_hidden bool) ([]*model.Credit, error) {
|
func GetArtistCredits(db *sqlx.DB, artistID string, show_hidden bool) ([]*model.Credit, error) {
|
||||||
var query string = "SELECT release.id,release.title,release.artwork,artist.id,artist.name,artist.website,artist.avatar,role,is_primary "+
|
var query string = "SELECT release.id,title,artwork,release_date,artist.id,name,website,avatar,role,is_primary "+
|
||||||
"FROM musiccredit "+
|
"FROM musiccredit "+
|
||||||
"JOIN musicrelease AS release ON release=release.id "+
|
"JOIN musicrelease AS release ON release=release.id "+
|
||||||
"JOIN artist ON artist=artist.id "+
|
"JOIN artist ON artist=artist.id "+
|
||||||
|
@ -69,6 +69,7 @@ func GetArtistCredits(db *sqlx.DB, artistID string, show_hidden bool) ([]*model.
|
||||||
&credit.Release.ID,
|
&credit.Release.ID,
|
||||||
&credit.Release.Title,
|
&credit.Release.Title,
|
||||||
&credit.Release.Artwork,
|
&credit.Release.Artwork,
|
||||||
|
&credit.Release.ReleaseDate,
|
||||||
&credit.Artist.ID,
|
&credit.Artist.ID,
|
||||||
&credit.Artist.Name,
|
&credit.Artist.Name,
|
||||||
&credit.Artist.Website,
|
&credit.Artist.Website,
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
4
main.go
4
main.go
|
@ -13,7 +13,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"
|
||||||
|
@ -210,7 +210,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" {
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -59,11 +59,11 @@
|
||||||
</h2>
|
</h2>
|
||||||
<div class="answer">
|
<div class="answer">
|
||||||
<p>
|
<p>
|
||||||
<strong class="big">yes!</strong> well, in most cases...
|
<strong class="big">yes!*</strong> <em>in most cases...</em>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
from <a href="/music/dream">Dream (2022)</a> onward, all of my <em>self-released</em> songs are
|
all of my <em>self-released</em> songs are licensed under
|
||||||
licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative Commons Attribution-ShareAlike 4.0</a>.
|
<a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative Commons Attribution-ShareAlike 4.0</a>.
|
||||||
anyone may use and remix these songs freely, so long as they provide credit back to me and link back to this license!
|
anyone may use and remix these songs freely, so long as they provide credit back to me and link back to this license!
|
||||||
please note that all derivative works must inherit this license.
|
please note that all derivative works must inherit this license.
|
||||||
</p>
|
</p>
|
||||||
|
@ -71,23 +71,17 @@
|
||||||
a great example of some credit text would be as follows:
|
a great example of some credit text would be as follows:
|
||||||
</p>
|
</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
music used: mellodoot - Dream<br>
|
music used: ari melody - free2play<br>
|
||||||
<a href="/music/dream">https://arimelody.me/music/dream</a><br>
|
<a href="/music/free2play">https://arimelody.me/music/free2play</a><br>
|
||||||
licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>.
|
licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">CC BY-SA 4.0</a>.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>
|
<p>
|
||||||
for any songs prior to this, they were all either released by me (in which case, i honestly
|
if the song you want to use is <em>not</em> released by me (i.e. under a record label), their usage rights
|
||||||
don't mind), or in collaboration with chill people who i don't see having an issue with it.
|
will likely trump whatever i'd otherwise have in mind. i'll try to negotiate some nice terms, though!
|
||||||
do be sure to ask them about it, though!
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
in the event the song you want to use is released under some other label, their usage rights
|
i believe that encouraging creative use of artistic works is better than stifling any use at all.
|
||||||
will more than likely trump whatever i'd otherwise have in mind. i'll try to negotiate some
|
if you do happen to use my work in something you're particularly proud of, feel free to send it my way!
|
||||||
nice terms, though! ;3
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
i love the idea of other creators using my songs in their work, so if you do happen to use
|
|
||||||
my stuff in a work you're particularly proud of, feel free to send it my way!
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
> <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
|
> <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
|
||||||
|
|
Loading…
Reference in a new issue