Add artist lookup by genre
[brackets.git] / routes / artist / artist.go
1 package artist
2
3 import (
4 "encoding/json"
5 "git.jacobcasper.com/brackets/env"
6 "git.jacobcasper.com/brackets/routes"
7 "git.jacobcasper.com/brackets/types"
8 "github.com/zmb3/spotify"
9 "log"
10 "net/http"
11 )
12
13 func Index(env *env.Env) routes.Handler {
14 return func(w http.ResponseWriter, r *http.Request) {
15 if r.Method != "GET" {
16 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
17 return
18 }
19
20 w.Header().Set("Content-Type", "application/json")
21
22 artistId := r.FormValue("id")
23 if artistId != "" {
24 artist := types.Artist{}
25 row := env.Db.Db.QueryRow("SELECT ID, NAME FROM ARTIST WHERE ID = ?", artistId)
26 if err := row.Scan(&artist.ID, &artist.Name); err != nil {
27 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
28 return
29 }
30 b, err := json.Marshal(artist)
31 if err != nil {
32 log.Print(err)
33 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
34 return
35 }
36 w.Write(b)
37 return
38 }
39
40 rows, err := env.Db.Db.Query("SELECT ID, NAME FROM ARTIST LIMIT 20")
41 if err != nil {
42 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
43 return
44 }
45 defer rows.Close()
46
47 artists := make([]types.Artist, 0)
48 for rows.Next() {
49 artist := types.Artist{}
50 if err := rows.Scan(&artist.ID, &artist.Name); err != nil {
51 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
52 return
53 }
54 artists = append(artists, artist)
55 }
56 if err = rows.Err(); err != nil {
57 log.Print(err)
58 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
59 return
60 }
61 b, err := json.Marshal(artists)
62 if err != nil {
63 log.Print(err)
64 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
65 return
66 }
67 w.Write(b)
68 }
69 }
70
71 func Add(env *env.Env) routes.Handler {
72 return func(w http.ResponseWriter, r *http.Request) {
73 if r.Method != "POST" {
74 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
75 return
76 }
77
78 r.ParseForm()
79 artistId := r.PostForm.Get("id")
80
81 if artistId == "" {
82 http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
83 return
84 }
85
86 artist, err := env.C.GetArtist(spotify.ID(artistId))
87 if err != nil {
88 log.Printf("Failed to retrieve artist %s: %s", artistId, err.Error())
89 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
90 return
91 }
92
93 env.Db.Mu.Lock()
94 defer env.Db.Mu.Unlock()
95 env.Db.Db.Exec("INSERT INTO ARTIST (ID, NAME) VALUES (?, ?)", artist.ID, artist.Name)
96
97 for _, genre := range artist.Genres {
98 result, err := env.Db.Db.Exec("INSERT OR IGNORE INTO GENRE (NAME) VALUES (?)", genre)
99 if err != nil {
100 log.Printf("Failed to insert genre %s: %s", genre, err.Error())
101 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
102 return
103 }
104
105 genreId, err := result.LastInsertId()
106 if err != nil {
107 log.Print("Failed to retrieve last insert id: ", err.Error())
108 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
109 return
110 }
111
112 env.Db.Db.Exec("INSERT INTO ARTIST_GENRE_XREF (ARTIST_ID, GENRE_ID) VALUES (?, ?)", artist.ID, genreId)
113 }
114 w.WriteHeader(http.StatusCreated)
115 }
116 }
117
118 func ByGenre(env *env.Env) routes.Handler {
119 return func(w http.ResponseWriter, r *http.Request) {
120 if r.Method != "GET" {
121 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
122 return
123 }
124
125 w.Header().Set("Content-Type", "application/json")
126 genreName := r.FormValue("genre_name")
127 if genreName != "" {
128 rows, err := env.Db.Db.Query("SELECT ID, NAME FROM ARTIST WHERE ID IN (SELECT ARTIST_ID FROM ARTIST_GENRE_XREF WHERE GENRE_ID IN (SELECT ID FROM GENRE WHERE NAME = lower(?))) LIMIT 20", genreName)
129 if err != nil {
130 log.Print(err)
131 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
132 return
133 }
134 defer rows.Close()
135
136 artists := make([]types.Artist, 0)
137 for rows.Next() {
138 artist := types.Artist{}
139 if err := rows.Scan(&artist.ID, &artist.Name); err != nil {
140 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
141 return
142 }
143 artists = append(artists, artist)
144 }
145 if err = rows.Err(); err != nil {
146 log.Print(err)
147 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
148 return
149 }
150 b, err := json.Marshal(artists)
151 if err != nil {
152 log.Print(err)
153 http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
154 return
155 }
156 w.Write(b)
157 }
158 }
159 }