merged main, dev, and i guess got accounts working??
i am so good at commit messages :3
This commit is contained in:
commit
5566a795da
53 changed files with 1366 additions and 398 deletions
175
api/account.go
Normal file
175
api/account.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
"arimelody-web/global"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func handleLogin() http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
credentials := LoginRequest{}
|
||||
err := json.NewDecoder(r.Body).Decode(&credentials)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
account, err := controller.GetAccount(global.DB, credentials.Username)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.Error(w, "Invalid username or password", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(account.Password, []byte(credentials.Password))
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid username or password", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: sessions and tokens
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Logged in successfully. TODO: Session tokens\n"))
|
||||
})
|
||||
}
|
||||
|
||||
func handleAccountRegistration() http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
credentials := RegisterRequest{}
|
||||
err := json.NewDecoder(r.Body).Decode(&credentials)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// make sure code exists in DB
|
||||
invite := model.Invite{}
|
||||
err = global.DB.Get(&invite, "SELECT * FROM invite WHERE code=$1", credentials.Code)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.Error(w, "Invalid invite code", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve invite: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if time.Now().After(invite.ExpiresAt) {
|
||||
http.Error(w, "Invalid invite code", http.StatusBadRequest)
|
||||
_, err = global.DB.Exec("DELETE FROM invite WHERE code=$1", credentials.Code)
|
||||
if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to delete expired invite: %s\n", err.Error()) }
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(credentials.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to generate password hash: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
account := model.Account{
|
||||
Username: credentials.Username,
|
||||
Password: hashedPassword,
|
||||
Email: credentials.Email,
|
||||
AvatarURL: "/img/default-avatar.png",
|
||||
}
|
||||
err = controller.CreateAccount(global.DB, &account)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to create account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = global.DB.Exec("DELETE FROM invite WHERE code=$1", credentials.Code)
|
||||
if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to delete expired invite: %s\n", err.Error()) }
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte("Account created successfully\n"))
|
||||
})
|
||||
}
|
||||
|
||||
func handleDeleteAccount() http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
credentials := LoginRequest{}
|
||||
err := json.NewDecoder(r.Body).Decode(&credentials)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
account, err := controller.GetAccount(global.DB, credentials.Username)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "no rows") {
|
||||
http.Error(w, "Invalid username or password", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = bcrypt.CompareHashAndPassword(account.Password, []byte(credentials.Password))
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid username or password", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = controller.DeleteAccount(global.DB, account.ID)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to delete account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Account deleted successfully\n"))
|
||||
})
|
||||
}
|
28
api/api.go
28
api/api.go
|
@ -13,6 +13,12 @@ import (
|
|||
func Handler() http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
// ACCOUNT ENDPOINTS
|
||||
|
||||
mux.Handle("/v1/login", handleLogin())
|
||||
mux.Handle("/v1/register", handleAccountRegistration())
|
||||
mux.Handle("/v1/delete-account", handleDeleteAccount())
|
||||
|
||||
// ARTIST ENDPOINTS
|
||||
|
||||
mux.Handle("/v1/artist/", http.StripPrefix("/v1/artist", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -34,10 +40,10 @@ func Handler() http.Handler {
|
|||
ServeArtist(artist).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/artist/{id} (admin)
|
||||
admin.MustAuthorise(UpdateArtist(artist)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, UpdateArtist(artist)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/artist/{id} (admin)
|
||||
admin.MustAuthorise(DeleteArtist(artist)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, DeleteArtist(artist)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -49,7 +55,7 @@ func Handler() http.Handler {
|
|||
ServeAllArtists().ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/artist (admin)
|
||||
admin.MustAuthorise(CreateArtist()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, CreateArtist()).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -76,10 +82,10 @@ func Handler() http.Handler {
|
|||
ServeRelease(release).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/music/{id} (admin)
|
||||
admin.MustAuthorise(UpdateRelease(release)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, UpdateRelease(release)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/music/{id} (admin)
|
||||
admin.MustAuthorise(DeleteRelease(release)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, DeleteRelease(release)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -91,7 +97,7 @@ func Handler() http.Handler {
|
|||
ServeCatalog().ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/music (admin)
|
||||
admin.MustAuthorise(CreateRelease()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, CreateRelease()).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -115,13 +121,13 @@ func Handler() http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/track/{id} (admin)
|
||||
admin.MustAuthorise(ServeTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, ServeTrack(track)).ServeHTTP(w, r)
|
||||
case http.MethodPut:
|
||||
// PUT /api/v1/track/{id} (admin)
|
||||
admin.MustAuthorise(UpdateTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, UpdateTrack(track)).ServeHTTP(w, r)
|
||||
case http.MethodDelete:
|
||||
// DELETE /api/v1/track/{id} (admin)
|
||||
admin.MustAuthorise(DeleteTrack(track)).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, DeleteTrack(track)).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -130,10 +136,10 @@ func Handler() http.Handler {
|
|||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
// GET /api/v1/track (admin)
|
||||
admin.MustAuthorise(ServeAllTracks()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, ServeAllTracks()).ServeHTTP(w, r)
|
||||
case http.MethodPost:
|
||||
// POST /api/v1/track (admin)
|
||||
admin.MustAuthorise(CreateTrack()).ServeHTTP(w, r)
|
||||
admin.RequireAccount(global.DB, CreateTrack()).ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"arimelody-web/admin"
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
|
@ -21,13 +20,15 @@ func ServeAllArtists() http.Handler {
|
|||
var artists = []*model.Artist{}
|
||||
artists, err := controller.GetAllArtists(global.DB)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to serve all artists: %s\n", err)
|
||||
fmt.Printf("WARN: Failed to serve all artists: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(artists)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(artists)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
@ -51,12 +52,17 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
|||
}
|
||||
)
|
||||
|
||||
show_hidden_releases := admin.GetSession(r) != nil
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
show_hidden_releases := account != nil
|
||||
|
||||
var dbCredits []*model.Credit
|
||||
dbCredits, err := controller.GetArtistCredits(global.DB, artist.ID, show_hidden_releases)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to retrieve artist credits for %s: %s\n", artist.ID, err)
|
||||
fmt.Printf("WARN: Failed to retrieve artist credits for %s: %s\n", artist.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -74,7 +80,9 @@ func ServeArtist(artist *model.Artist) http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(artistJSON{
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(artistJSON{
|
||||
Artist: artist,
|
||||
Credits: credits,
|
||||
})
|
||||
|
@ -105,7 +113,7 @@ func CreateArtist() http.Handler {
|
|||
http.Error(w, fmt.Sprintf("Artist %s already exists\n", artist.ID), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to create artist %s: %s\n", artist.ID, err)
|
||||
fmt.Printf("WARN: Failed to create artist %s: %s\n", artist.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -118,7 +126,7 @@ func UpdateArtist(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 {
|
||||
fmt.Printf("FATAL: Failed to update artist: %s\n", err)
|
||||
fmt.Printf("WARN: Failed to update artist: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
@ -153,7 +161,7 @@ func UpdateArtist(artist *model.Artist) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to update artist %s: %s\n", artist.ID, err)
|
||||
fmt.Printf("WARN: Failed to update artist %s: %s\n", artist.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -167,7 +175,7 @@ func DeleteArtist(artist *model.Artist) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to delete artist %s: %s\n", artist.ID, err)
|
||||
fmt.Printf("WARN: Failed to delete artist %s: %s\n", artist.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"arimelody-web/admin"
|
||||
"arimelody-web/global"
|
||||
"arimelody-web/controller"
|
||||
"arimelody-web/model"
|
||||
|
@ -19,10 +18,23 @@ import (
|
|||
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
|
||||
privileged := false
|
||||
if !release.Visible {
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if account != nil {
|
||||
// TODO: check privilege on release
|
||||
privileged = true
|
||||
}
|
||||
|
||||
if !privileged {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
|
@ -53,18 +65,18 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
Links: make(map[string]string),
|
||||
}
|
||||
|
||||
if authorised || release.IsReleased() {
|
||||
if release.IsReleased() || privileged {
|
||||
// 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)
|
||||
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)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to serve release %s: Artists: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to serve release %s: Artists: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -79,7 +91,7 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
// 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)
|
||||
fmt.Printf("WARN: Failed to serve release %s: Tracks: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -94,7 +106,7 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
// 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)
|
||||
fmt.Printf("WARN: Failed to serve release %s: Links: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -104,7 +116,9 @@ func ServeRelease(release *model.Release) http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err := json.NewEncoder(w).Encode(response)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err := encoder.Encode(response)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -132,11 +146,24 @@ func ServeCatalog() http.Handler {
|
|||
}
|
||||
|
||||
catalog := []Release{}
|
||||
authorised := admin.GetSession(r) != nil
|
||||
account, err := controller.GetAccountByRequest(global.DB, r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to fetch account: %s\n", err.Error())
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
for _, release := range releases {
|
||||
if !release.Visible && !authorised {
|
||||
continue
|
||||
if !release.Visible {
|
||||
privileged := false
|
||||
if account != nil {
|
||||
// TODO: check privilege on release
|
||||
privileged = true
|
||||
}
|
||||
if !privileged {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
artists := []string{}
|
||||
for _, credit := range release.Credits {
|
||||
if !credit.Primary { continue }
|
||||
|
@ -155,7 +182,9 @@ func ServeCatalog() http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(catalog)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(catalog)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
|
@ -197,14 +226,16 @@ func CreateRelease() http.Handler {
|
|||
http.Error(w, fmt.Sprintf("Release %s already exists\n", release.ID), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to create release %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to create release %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
err = json.NewEncoder(w).Encode(release)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(release)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Release %s created, but failed to send JSON response: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -275,7 +306,7 @@ func UpdateRelease(release *model.Release) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to update release %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to update release %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -296,7 +327,7 @@ func UpdateReleaseTracks(release *model.Release) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to update tracks for %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to update tracks for %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -337,7 +368,7 @@ func UpdateReleaseCredits(release *model.Release) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to update links for %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to update links for %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -363,7 +394,7 @@ func UpdateReleaseLinks(release *model.Release) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to update links for %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to update links for %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -377,7 +408,7 @@ func DeleteRelease(release *model.Release) http.Handler {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
fmt.Printf("FATAL: Failed to delete release %s: %s\n", release.ID, err)
|
||||
fmt.Printf("WARN: Failed to delete release %s: %s\n", release.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
|
22
api/track.go
22
api/track.go
|
@ -28,7 +28,7 @@ func ServeAllTracks() http.Handler {
|
|||
var dbTracks = []*model.Track{}
|
||||
dbTracks, err := controller.GetAllTracks(global.DB)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to pull tracks from DB: %s\n", err)
|
||||
fmt.Printf("WARN: Failed to pull tracks from DB: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,11 @@ func ServeAllTracks() http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(tracks)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(tracks)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to serve all tracks: %s\n", err)
|
||||
fmt.Printf("WARN: Failed to serve all tracks: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -52,7 +54,7 @@ func ServeTrack(track *model.Track) http.Handler {
|
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
dbReleases, err := controller.GetTrackReleases(global.DB, track.ID, false)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to pull track releases for %s from DB: %s\n", track.ID, err)
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -62,9 +64,11 @@ func ServeTrack(track *model.Track) http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(Track{ track, releases })
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(Track{ track, releases })
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to serve track %s: %s\n", track.ID, err)
|
||||
fmt.Printf("WARN: Failed to serve track %s: %s\n", track.ID, err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
@ -91,7 +95,7 @@ func CreateTrack() http.Handler {
|
|||
|
||||
id, err := controller.CreateTrack(global.DB, &track)
|
||||
if err != nil {
|
||||
fmt.Printf("FATAL: Failed to create track: %s\n", err)
|
||||
fmt.Printf("WARN: Failed to create track: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
@ -128,7 +132,9 @@ func UpdateTrack(track *model.Track) http.Handler {
|
|||
}
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
err = json.NewEncoder(w).Encode(track)
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetIndent("", "\t")
|
||||
err = encoder.Encode(track)
|
||||
if err != nil {
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"arimelody-web/global"
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
|
@ -15,6 +16,7 @@ func HandleImageUpload(data *string, directory string, filename string) (string,
|
|||
header := split[0]
|
||||
imageData, err := base64.StdEncoding.DecodeString(split[1])
|
||||
ext, _ := strings.CutPrefix(header, "data:image/")
|
||||
directory = filepath.Join(global.Config.DataDirectory, directory)
|
||||
|
||||
switch ext {
|
||||
case "png":
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue