Track artist popularity
[brackets.git] / routes / artist / artist.go
CommitLineData
2400eea4
JC
1package artist
2
3import (
d7efcbb7 4 "database/sql"
2353fc58 5 "encoding/json"
2400eea4
JC
6 "git.jacobcasper.com/brackets/env"
7 "git.jacobcasper.com/brackets/routes"
2353fc58 8 "git.jacobcasper.com/brackets/types"
2400eea4
JC
9 "github.com/zmb3/spotify"
10 "log"
11 "net/http"
12)
13
2353fc58
JC
14func Index(env *env.Env) routes.Handler {
15 return func(w http.ResponseWriter, r *http.Request) {
16 if r.Method != "GET" {
17 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
18 return
19 }
20
21 w.Header().Set("Content-Type", "application/json")
22
23 artistId := r.FormValue("id")
24 if artistId != "" {
25 artist := types.Artist{}
9a3c373c 26 row := env.Db.Db.QueryRow(`
30baa977 27SELECT ID, NAME, POPULARITY
9a3c373c
JC
28FROM ARTIST
29WHERE ID = ?`,
30 artistId,
31 )
30baa977 32 if err := row.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
2353fc58
JC
33 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
34 return
35 }
36 b, err := json.Marshal(artist)
37 if err != nil {
38 log.Print(err)
39 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
40 return
41 }
42 w.Write(b)
43 return
44 }
45
9a3c373c 46 rows, err := env.Db.Db.Query(`
30baa977 47SELECT ID, NAME, POPULARITY
9a3c373c
JC
48FROM ARTIST
49LIMIT 20`,
50 )
2353fc58
JC
51 if err != nil {
52 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
53 return
54 }
55 defer rows.Close()
56
57 artists := make([]types.Artist, 0)
58 for rows.Next() {
59 artist := types.Artist{}
30baa977 60 if err := rows.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
2353fc58
JC
61 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
62 return
63 }
64 artists = append(artists, artist)
65 }
66 if err = rows.Err(); err != nil {
67 log.Print(err)
68 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
69 return
70 }
71 b, err := json.Marshal(artists)
72 if err != nil {
73 log.Print(err)
74 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
75 return
76 }
77 w.Write(b)
78 }
79}
80
2400eea4
JC
81func Add(env *env.Env) routes.Handler {
82 return func(w http.ResponseWriter, r *http.Request) {
83 if r.Method != "POST" {
84 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
85 return
86 }
87
88 r.ParseForm()
89 artistId := r.PostForm.Get("id")
90
91 if artistId == "" {
92 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
93 return
94 }
95
96 artist, err := env.C.GetArtist(spotify.ID(artistId))
97 if err != nil {
98 log.Printf("Failed to retrieve artist %s: %s", artistId, err.Error())
99 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
100 return
101 }
102
103 env.Db.Mu.Lock()
104 defer env.Db.Mu.Unlock()
9a3c373c
JC
105 env.Db.Db.Exec(`
106INSERT INTO ARTIST
30baa977
JC
107(ID, NAME, POPULARITY)
108VALUES (?, ?, ?)`,
9a3c373c
JC
109 artist.ID,
110 artist.Name,
30baa977 111 artist.Popularity,
9a3c373c 112 )
2400eea4
JC
113
114 for _, genre := range artist.Genres {
d7efcbb7
JC
115 var genreId int64
116 row := env.Db.Db.QueryRow(`
117SELECT ID
118FROM GENRE
119WHERE NAME = lower(?)
120`,
9a3c373c
JC
121 genre,
122 )
d7efcbb7
JC
123
124 err := row.Scan(&genreId)
125 if err == sql.ErrNoRows {
9a3c373c
JC
126 result, err := env.Db.Db.Exec(`
127INSERT INTO GENRE
128(NAME)
129VALUES (?)`,
130 genre,
131 )
d7efcbb7
JC
132 if err != nil {
133 log.Printf("Failed to insert genre %s: %s", genre, err.Error())
134 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
135 return
136 }
137
138 genreId, err = result.LastInsertId()
139 if err != nil {
140 log.Print("Failed to retrieve last insert id: ", err.Error())
141 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
142 return
143 }
2400eea4
JC
144 }
145
9a3c373c
JC
146 env.Db.Db.Exec(`
147INSERT INTO ARTIST_GENRE_XREF
148(ARTIST_ID, GENRE_ID)
149VALUES (?, ?)`,
150 artist.ID,
151 genreId,
152 )
2400eea4
JC
153 }
154 w.WriteHeader(http.StatusCreated)
155 }
156}
eac0dfd6
JC
157
158func ByGenre(env *env.Env) routes.Handler {
159 return func(w http.ResponseWriter, r *http.Request) {
160 if r.Method != "GET" {
161 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
162 return
163 }
164
165 w.Header().Set("Content-Type", "application/json")
166 genreName := r.FormValue("genre_name")
167 if genreName != "" {
9a3c373c
JC
168 rows, err := env.Db.Db.Query(`
169SELECT a.ID, a.NAME
170FROM ARTIST a
171JOIN ARTIST_GENRE_XREF x ON a.ID = x.ARTIST_ID
172JOIN GENRE g ON g.ID = x.GENRE_ID
173WHERE g.NAME = lower(?)
174`,
175 genreName,
176 )
eac0dfd6
JC
177 if err != nil {
178 log.Print(err)
179 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
180 return
181 }
182 defer rows.Close()
183
184 artists := make([]types.Artist, 0)
185 for rows.Next() {
186 artist := types.Artist{}
30baa977 187 if err := rows.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
eac0dfd6
JC
188 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
189 return
190 }
191 artists = append(artists, artist)
192 }
193 if err = rows.Err(); err != nil {
194 log.Print(err)
195 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
196 return
197 }
198 b, err := json.Marshal(artists)
199 if err != nil {
200 log.Print(err)
201 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
202 return
203 }
204 w.Write(b)
205 }
206 }
207}