refactored out global
. long live AppState
This commit is contained in:
parent
3d674515ce
commit
384579ee5e
24 changed files with 350 additions and 375 deletions
|
@ -3,7 +3,6 @@ package api
|
|||
import (
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
"arimelody-web/global"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -14,7 +13,7 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func handleLogin() http.HandlerFunc {
|
||||
func handleLogin(app *model.AppState) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
|
@ -33,7 +32,7 @@ func handleLogin() http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
account, err := controller.GetAccount(global.DB, credentials.Username)
|
||||
account, err := controller.GetAccount(app.DB, credentials.Username)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve account: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -50,7 +49,7 @@ func handleLogin() http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
token, err := controller.CreateToken(global.DB, account.ID, r.UserAgent())
|
||||
token, err := controller.CreateToken(app.DB, account.ID, r.UserAgent())
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
|
@ -67,7 +66,7 @@ func handleLogin() http.HandlerFunc {
|
|||
})
|
||||
}
|
||||
|
||||
func handleAccountRegistration() http.HandlerFunc {
|
||||
func handleAccountRegistration(app *model.AppState) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
|
@ -89,7 +88,7 @@ func handleAccountRegistration() http.HandlerFunc {
|
|||
}
|
||||
|
||||
// make sure code exists in DB
|
||||
invite, err := controller.GetInvite(global.DB, credentials.Invite)
|
||||
invite, err := controller.GetInvite(app.DB, credentials.Invite)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve invite: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -101,7 +100,7 @@ func handleAccountRegistration() http.HandlerFunc {
|
|||
}
|
||||
|
||||
if time.Now().After(invite.ExpiresAt) {
|
||||
err := controller.DeleteInvite(global.DB, invite.Code)
|
||||
err := controller.DeleteInvite(app.DB, invite.Code)
|
||||
if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to delete expired invite: %v\n", err) }
|
||||
http.Error(w, "Invalid invite code", http.StatusBadRequest)
|
||||
return
|
||||
|
@ -120,7 +119,7 @@ func handleAccountRegistration() http.HandlerFunc {
|
|||
Email: credentials.Email,
|
||||
AvatarURL: "/img/default-avatar.png",
|
||||
}
|
||||
err = controller.CreateAccount(global.DB, &account)
|
||||
err = controller.CreateAccount(app.DB, &account)
|
||||
if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "pq: duplicate key") {
|
||||
http.Error(w, "An account with that username already exists", http.StatusBadRequest)
|
||||
|
@ -131,10 +130,10 @@ func handleAccountRegistration() http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
err = controller.DeleteInvite(global.DB, invite.Code)
|
||||
err = controller.DeleteInvite(app.DB, invite.Code)
|
||||
if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to delete expired invite: %v\n", err) }
|
||||
|
||||
token, err := controller.CreateToken(global.DB, account.ID, r.UserAgent())
|
||||
token, err := controller.CreateToken(app.DB, account.ID, r.UserAgent())
|
||||
type LoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
|
@ -151,7 +150,7 @@ func handleAccountRegistration() http.HandlerFunc {
|
|||
})
|
||||
}
|
||||
|
||||
func handleDeleteAccount() http.HandlerFunc {
|
||||
func handleDeleteAccount(app *model.AppState) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
|
@ -170,7 +169,7 @@ func handleDeleteAccount() http.HandlerFunc {
|
|||
return
|
||||
}
|
||||
|
||||
account, err := controller.GetAccount(global.DB, credentials.Username)
|
||||
account, err := controller.GetAccount(app.DB, credentials.Username)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.Error(w, "Invalid username or password", http.StatusBadRequest)
|
||||
|
@ -189,7 +188,7 @@ func handleDeleteAccount() http.HandlerFunc {
|
|||
|
||||
// TODO: check TOTP
|
||||
|
||||
err = controller.DeleteAccount(global.DB, account.Username)
|
||||
err = controller.DeleteAccount(app.DB, account.Username)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to delete account: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
|
41
api/api.go
41
api/api.go
|
@ -7,11 +7,10 @@ import (
|
|||
|
||||
"arimelody-web/admin"
|
||||
"arimelody-web/controller"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
||||
func Handler(db *sqlx.DB) http.Handler {
|
||||
func Handler(app *model.AppState) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// ACCOUNT ENDPOINTS
|
||||
|
@ -32,7 +31,7 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
|
||||
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]
|
||||
artist, err := controller.GetArtist(db, artistID)
|
||||
artist, err := controller.GetArtist(app.DB, artistID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -46,13 +45,13 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/artist/{id}
|
||||
ServeArtist(artist).ServeHTTP(w, r)
|
||||
ServeArtist(app, artist).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/artist/{id} (admin)
|
||||
admin.RequireAccount(db, UpdateArtist(artist)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, UpdateArtist(app, artist)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/artist/{id} (admin)
|
||||
admin.RequireAccount(db, DeleteArtist(artist)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, DeleteArtist(app, artist)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -61,10 +60,10 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/artist
|
||||
ServeAllArtists().ServeHTTP(w, r)
|
||||
ServeAllArtists(app).ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/artist (admin)
|
||||
admin.RequireAccount(db, CreateArtist()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, CreateArtist(app)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -74,7 +73,7 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
|
||||
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]
|
||||
release, err := controller.GetRelease(db, releaseID, true)
|
||||
release, err := controller.GetRelease(app.DB, releaseID, true)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -88,13 +87,13 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/music/{id}
|
||||
ServeRelease(release).ServeHTTP(w, r)
|
||||
ServeRelease(app, release).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/music/{id} (admin)
|
||||
admin.RequireAccount(db, UpdateRelease(release)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, UpdateRelease(app, release)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/music/{id} (admin)
|
||||
admin.RequireAccount(db, DeleteRelease(release)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, DeleteRelease(app, release)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -103,10 +102,10 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/music
|
||||
ServeCatalog().ServeHTTP(w, r)
|
||||
ServeCatalog(app).ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/music (admin)
|
||||
admin.RequireAccount(db, CreateRelease()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, CreateRelease(app)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -116,7 +115,7 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
|
||||
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]
|
||||
track, err := controller.GetTrack(db, trackID)
|
||||
track, err := controller.GetTrack(app.DB, trackID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -130,13 +129,13 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/track/{id} (admin)
|
||||
admin.RequireAccount(db, ServeTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, ServeTrack(app, track)).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/track/{id} (admin)
|
||||
admin.RequireAccount(db, UpdateTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, UpdateTrack(app, track)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/track/{id} (admin)
|
||||
admin.RequireAccount(db, DeleteTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, DeleteTrack(app, track)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -145,10 +144,10 @@ func Handler(db *sqlx.DB) http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/track (admin)
|
||||
admin.RequireAccount(db, ServeAllTracks()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, ServeAllTracks(app)).ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/track (admin)
|
||||
admin.RequireAccount(db, CreateTrack()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(app, CreateTrack(app)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
|
|
@ -10,15 +10,14 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
||||
func ServeAllArtists() http.Handler {
|
||||
func ServeAllArtists(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var artists = []*model.Artist{}
|
||||
artists, err := controller.GetAllArtists(global.DB)
|
||||
artists, err := controller.GetAllArtists(app.DB)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to serve all artists: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -35,7 +34,7 @@ func ServeAllArtists() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func ServeArtist(artist *model.Artist) http.Handler {
|
||||
func ServeArtist(app *model.AppState, artist *model.Artist) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
type (
|
||||
creditJSON struct {
|
||||
|
@ -52,7 +51,7 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
|||
}
|
||||
)
|
||||
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
account, err := controller.GetAccountByRequest(app.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -60,7 +59,7 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
|||
}
|
||||
show_hidden_releases := account != nil
|
||||
|
||||
dbCredits, err := controller.GetArtistCredits(global.DB, artist.ID, show_hidden_releases)
|
||||
dbCredits, err := controller.GetArtistCredits(app.DB, artist.ID, show_hidden_releases)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to retrieve artist credits for %s: %v\n", artist.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -92,7 +91,7 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func CreateArtist() http.Handler {
|
||||
func CreateArtist(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var artist model.Artist
|
||||
err := json.NewDecoder(r.Body).Decode(&artist)
|
||||
|
@ -107,7 +106,7 @@ func CreateArtist() http.Handler {
|
|||
}
|
||||
if artist.Name == "" { artist.Name = artist.ID }
|
||||
|
||||
err = controller.CreateArtist(global.DB, &artist)
|
||||
err = controller.CreateArtist(app.DB, &artist)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "duplicate key") {
|
||||
http.Error(w, fmt.Sprintf("Artist %s already exists\n", artist.ID), http.StatusBadRequest)
|
||||
|
@ -122,7 +121,7 @@ func CreateArtist() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateArtist(artist *model.Artist) http.Handler {
|
||||
func UpdateArtist(app *model.AppState, artist *model.Artist) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
err := json.NewDecoder(r.Body).Decode(&artist)
|
||||
if err != nil {
|
||||
|
@ -136,7 +135,7 @@ func UpdateArtist(artist *model.Artist) http.Handler {
|
|||
} else {
|
||||
if strings.Contains(artist.Avatar, ";base64,") {
|
||||
var artworkDirectory = filepath.Join("uploads", "avatar")
|
||||
filename, err := HandleImageUpload(&artist.Avatar, artworkDirectory, artist.ID)
|
||||
filename, err := HandleImageUpload(app, &artist.Avatar, artworkDirectory, artist.ID)
|
||||
|
||||
// clean up files with this ID and different extensions
|
||||
err = filepath.Walk(artworkDirectory, func(path string, info fs.FileInfo, err error) error {
|
||||
|
@ -155,7 +154,7 @@ func UpdateArtist(artist *model.Artist) http.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
err = controller.UpdateArtist(global.DB, artist)
|
||||
err = controller.UpdateArtist(app.DB, artist)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -167,9 +166,9 @@ func UpdateArtist(artist *model.Artist) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func DeleteArtist(artist *model.Artist) http.Handler {
|
||||
func DeleteArtist(app *model.AppState, artist *model.Artist) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
err := controller.DeleteArtist(global.DB, artist.ID)
|
||||
err := controller.DeleteArtist(app.DB, artist.ID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
|
|
@ -10,17 +10,16 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
||||
func ServeRelease(release *model.Release) http.Handler {
|
||||
func ServeRelease(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// only allow authorised users to view hidden releases
|
||||
privileged := false
|
||||
if !release.Visible {
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
account, err := controller.GetAccountByRequest(app.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -67,14 +66,14 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
|
||||
if release.IsReleased() || privileged {
|
||||
// get credits
|
||||
credits, err := controller.GetReleaseCredits(global.DB, release.ID)
|
||||
credits, err := controller.GetReleaseCredits(app.DB, 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(global.DB, credit.Artist.ID)
|
||||
artist, err := controller.GetArtist(app.DB, 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)
|
||||
|
@ -89,7 +88,7 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
}
|
||||
|
||||
// get tracks
|
||||
tracks, err := controller.GetReleaseTracks(global.DB, release.ID)
|
||||
tracks, err := controller.GetReleaseTracks(app.DB, 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)
|
||||
|
@ -104,7 +103,7 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
}
|
||||
|
||||
// get links
|
||||
links, err := controller.GetReleaseLinks(global.DB, release.ID)
|
||||
links, err := controller.GetReleaseLinks(app.DB, 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)
|
||||
|
@ -126,9 +125,9 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func ServeCatalog() http.Handler {
|
||||
func ServeCatalog(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
releases, err := controller.GetAllReleases(global.DB, false, 0, true)
|
||||
releases, err := controller.GetAllReleases(app.DB, false, 0, true)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -146,7 +145,7 @@ func ServeCatalog() http.Handler {
|
|||
}
|
||||
|
||||
catalog := []Release{}
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
account, err := controller.GetAccountByRequest(app.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -192,7 +191,7 @@ func ServeCatalog() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func CreateRelease() http.Handler {
|
||||
func CreateRelease(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
|
@ -220,7 +219,7 @@ func CreateRelease() http.Handler {
|
|||
|
||||
if release.Artwork == "" { release.Artwork = "/img/default-cover-art.png" }
|
||||
|
||||
err = controller.CreateRelease(global.DB, &release)
|
||||
err = controller.CreateRelease(app.DB, &release)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "duplicate key") {
|
||||
http.Error(w, fmt.Sprintf("Release %s already exists\n", release.ID), http.StatusBadRequest)
|
||||
|
@ -243,7 +242,7 @@ func CreateRelease() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateRelease(release *model.Release) http.Handler {
|
||||
func UpdateRelease(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/" {
|
||||
http.NotFound(w, r)
|
||||
|
@ -255,11 +254,11 @@ func UpdateRelease(release *model.Release) http.Handler {
|
|||
if len(segments) == 2 {
|
||||
switch segments[1] {
|
||||
case "tracks":
|
||||
UpdateReleaseTracks(release).ServeHTTP(w, r)
|
||||
UpdateReleaseTracks(app, release).ServeHTTP(w, r)
|
||||
case "credits":
|
||||
UpdateReleaseCredits(release).ServeHTTP(w, r)
|
||||
UpdateReleaseCredits(app, release).ServeHTTP(w, r)
|
||||
case "links":
|
||||
UpdateReleaseLinks(release).ServeHTTP(w, r)
|
||||
UpdateReleaseLinks(app, release).ServeHTTP(w, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -281,7 +280,7 @@ func UpdateRelease(release *model.Release) http.Handler {
|
|||
} else {
|
||||
if strings.Contains(release.Artwork, ";base64,") {
|
||||
var artworkDirectory = filepath.Join("uploads", "musicart")
|
||||
filename, err := HandleImageUpload(&release.Artwork, artworkDirectory, release.ID)
|
||||
filename, err := HandleImageUpload(app, &release.Artwork, artworkDirectory, release.ID)
|
||||
|
||||
// clean up files with this ID and different extensions
|
||||
err = filepath.Walk(artworkDirectory, func(path string, info fs.FileInfo, err error) error {
|
||||
|
@ -300,7 +299,7 @@ func UpdateRelease(release *model.Release) http.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
err = controller.UpdateRelease(global.DB, release)
|
||||
err = controller.UpdateRelease(app.DB, release)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -312,7 +311,7 @@ func UpdateRelease(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateReleaseTracks(release *model.Release) http.Handler {
|
||||
func UpdateReleaseTracks(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var trackIDs = []string{}
|
||||
err := json.NewDecoder(r.Body).Decode(&trackIDs)
|
||||
|
@ -321,7 +320,7 @@ func UpdateReleaseTracks(release *model.Release) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
err = controller.UpdateReleaseTracks(global.DB, release.ID, trackIDs)
|
||||
err = controller.UpdateReleaseTracks(app.DB, release.ID, trackIDs)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -333,7 +332,7 @@ func UpdateReleaseTracks(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateReleaseCredits(release *model.Release) http.Handler {
|
||||
func UpdateReleaseCredits(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
type creditJSON struct {
|
||||
Artist string
|
||||
|
@ -358,7 +357,7 @@ func UpdateReleaseCredits(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
err = controller.UpdateReleaseCredits(global.DB, release.ID, credits)
|
||||
err = controller.UpdateReleaseCredits(app.DB, release.ID, credits)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "duplicate key") {
|
||||
http.Error(w, "Artists may only be credited once\n", http.StatusBadRequest)
|
||||
|
@ -374,7 +373,7 @@ func UpdateReleaseCredits(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateReleaseLinks(release *model.Release) http.Handler {
|
||||
func UpdateReleaseLinks(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPut {
|
||||
http.NotFound(w, r)
|
||||
|
@ -388,7 +387,7 @@ func UpdateReleaseLinks(release *model.Release) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
err = controller.UpdateReleaseLinks(global.DB, release.ID, links)
|
||||
err = controller.UpdateReleaseLinks(app.DB, release.ID, links)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
@ -400,9 +399,9 @@ func UpdateReleaseLinks(release *model.Release) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func DeleteRelease(release *model.Release) http.Handler {
|
||||
func DeleteRelease(app *model.AppState, release *model.Release) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
err := controller.DeleteRelease(global.DB, release.ID)
|
||||
err := controller.DeleteRelease(app.DB, release.ID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.NotFound(w, r)
|
||||
|
|
21
api/track.go
21
api/track.go
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
@ -17,7 +16,7 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
func ServeAllTracks() http.Handler {
|
||||
func ServeAllTracks(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
type Track struct {
|
||||
ID string `json:"id"`
|
||||
|
@ -26,7 +25,7 @@ func ServeAllTracks() http.Handler {
|
|||
var tracks = []Track{}
|
||||
|
||||
var dbTracks = []*model.Track{}
|
||||
dbTracks, err := controller.GetAllTracks(global.DB)
|
||||
dbTracks, err := controller.GetAllTracks(app.DB)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to pull tracks from DB: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -50,9 +49,9 @@ func ServeAllTracks() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func ServeTrack(track *model.Track) http.Handler {
|
||||
func ServeTrack(app *model.AppState, track *model.Track) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
dbReleases, err := controller.GetTrackReleases(global.DB, track.ID, false)
|
||||
dbReleases, err := controller.GetTrackReleases(app.DB, track.ID, false)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to pull track releases for %s from DB: %s\n", track.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -74,7 +73,7 @@ func ServeTrack(track *model.Track) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func CreateTrack() http.Handler {
|
||||
func CreateTrack(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
|
@ -93,7 +92,7 @@ func CreateTrack() http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
id, err := controller.CreateTrack(global.DB, &track)
|
||||
id, err := controller.CreateTrack(app.DB, &track)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to create track: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -106,7 +105,7 @@ func CreateTrack() http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func UpdateTrack(track *model.Track) http.Handler {
|
||||
func UpdateTrack(app *model.AppState, track *model.Track) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPut || r.URL.Path == "/" {
|
||||
http.NotFound(w, r)
|
||||
|
@ -124,7 +123,7 @@ func UpdateTrack(track *model.Track) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
err = controller.UpdateTrack(global.DB, track)
|
||||
err = controller.UpdateTrack(app.DB, track)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to update track %s: %s\n", track.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -141,7 +140,7 @@ func UpdateTrack(track *model.Track) http.Handler {
|
|||
})
|
||||
}
|
||||
|
||||
func DeleteTrack(track *model.Track) http.Handler {
|
||||
func DeleteTrack(app *model.AppState, track *model.Track) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodDelete || r.URL.Path == "/" {
|
||||
http.NotFound(w, r)
|
||||
|
@ -149,7 +148,7 @@ func DeleteTrack(track *model.Track) http.Handler {
|
|||
}
|
||||
|
||||
var trackID = r.URL.Path[1:]
|
||||
err := controller.DeleteTrack(global.DB, trackID)
|
||||
err := controller.DeleteTrack(app.DB, trackID)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to delete track %s: %s\n", trackID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/model"
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
|
@ -11,12 +11,12 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func HandleImageUpload(data *string, directory string, filename string) (string, error) {
|
||||
func HandleImageUpload(app *model.AppState, data *string, directory string, filename string) (string, error) {
|
||||
split := strings.Split(*data, ";base64,")
|
||||
header := split[0]
|
||||
imageData, err := base64.StdEncoding.DecodeString(split[1])
|
||||
ext, _ := strings.CutPrefix(header, "data:image/")
|
||||
directory = filepath.Join(global.Config.DataDirectory, directory)
|
||||
directory = filepath.Join(app.Config.DataDirectory, directory)
|
||||
|
||||
switch ext {
|
||||
case "png":
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue