home to your local SPACEGIRL 馃挮
arimelody.space
1package api
2
3import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7
8 "arimelody-web/controller"
9 "arimelody-web/log"
10 "arimelody-web/model"
11)
12
13type (
14 Track struct {
15 *model.Track
16 Releases []string `json:"releases"`
17 }
18)
19
20func ServeAllTracks(app *model.AppState) http.Handler {
21 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
22 type Track struct {
23 ID string `json:"id"`
24 Title string `json:"title"`
25 }
26 var tracks = []Track{}
27
28 var dbTracks = []*model.Track{}
29 dbTracks, err := controller.GetAllTracks(app.DB)
30 if err != nil {
31 fmt.Printf("WARN: Failed to pull tracks from DB: %s\n", err)
32 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
33 }
34
35 for _, track := range dbTracks {
36 tracks = append(tracks, Track{
37 ID: track.ID,
38 Title: track.Title,
39 })
40 }
41
42 w.Header().Add("Content-Type", "application/json")
43 encoder := json.NewEncoder(w)
44 encoder.SetIndent("", "\t")
45 err = encoder.Encode(tracks)
46 if err != nil {
47 fmt.Printf("WARN: Failed to serve all tracks: %s\n", err)
48 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
49 }
50 })
51}
52
53func ServeTrack(app *model.AppState, track *model.Track) http.Handler {
54 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
55 dbReleases, err := controller.GetTrackReleases(app.DB, track.ID, false)
56 if err != nil {
57 fmt.Printf("WARN: Failed to pull track releases for %s from DB: %s\n", track.ID, err)
58 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
59 }
60
61 releases := []string{}
62 for _, release := range dbReleases {
63 releases = append(releases, release.ID)
64 }
65
66 w.Header().Add("Content-Type", "application/json")
67 encoder := json.NewEncoder(w)
68 encoder.SetIndent("", "\t")
69 err = encoder.Encode(Track{ track, releases })
70 if err != nil {
71 fmt.Printf("WARN: Failed to serve track %s: %s\n", track.ID, err)
72 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
73 }
74 })
75}
76
77func CreateTrack(app *model.AppState) http.Handler {
78 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
79 session := r.Context().Value("session").(*model.Session)
80
81 var track model.Track
82 err := json.NewDecoder(r.Body).Decode(&track)
83 if err != nil {
84 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
85 return
86 }
87
88 if track.Title == "" {
89 http.Error(w, "Track title cannot be empty\n", http.StatusBadRequest)
90 return
91 }
92
93 id, err := controller.CreateTrack(app.DB, &track)
94 if err != nil {
95 fmt.Printf("WARN: Failed to create track: %s\n", err)
96 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
97 return
98 }
99
100 app.Log.Info(log.TYPE_MUSIC, "Track \"%s\" (%s) created by \"%s\".", track.Title, track.ID, session.Account.Username)
101
102 w.Header().Add("Content-Type", "text/plain")
103 w.WriteHeader(http.StatusCreated)
104 w.Write([]byte(id))
105 })
106}
107
108func UpdateTrack(app *model.AppState, track *model.Track) http.Handler {
109 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
110 if r.URL.Path == "/" {
111 http.NotFound(w, r)
112 return
113 }
114
115 session := r.Context().Value("session").(*model.Session)
116
117 err := json.NewDecoder(r.Body).Decode(&track)
118 if err != nil {
119 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
120 return
121 }
122
123 if track.Title == "" {
124 http.Error(w, "Track title cannot be empty\n", http.StatusBadRequest)
125 return
126 }
127
128 err = controller.UpdateTrack(app.DB, track)
129 if err != nil {
130 fmt.Printf("WARN: Failed to update track %s: %s\n", track.ID, err)
131 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
132 return
133 }
134
135 app.Log.Info(log.TYPE_MUSIC, "Track \"%s\" (%s) updated by \"%s\".", track.Title, track.ID, session.Account.Username)
136
137 w.Header().Add("Content-Type", "application/json")
138 encoder := json.NewEncoder(w)
139 encoder.SetIndent("", "\t")
140 err = encoder.Encode(track)
141 if err != nil {
142 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
143 }
144 })
145}
146
147func DeleteTrack(app *model.AppState, track *model.Track) http.Handler {
148 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
149 if r.URL.Path == "/" {
150 http.NotFound(w, r)
151 return
152 }
153
154 session := r.Context().Value("session").(*model.Session)
155
156 var trackID = r.URL.Path[1:]
157 err := controller.DeleteTrack(app.DB, trackID)
158 if err != nil {
159 fmt.Printf("WARN: Failed to delete track %s: %s\n", trackID, err)
160 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
161 }
162
163 app.Log.Info(log.TYPE_MUSIC, "Track \"%s\" (%s) deleted by \"%s\".", track.Title, track.ID, session.Account.Username)
164 })
165}