Add api server to handle adding artists
authorJacob Casper <dev@jacobcasper.com>
Tue, 14 Apr 2020 04:34:11 +0000 (23:34 -0500)
committerJacob Casper <dev@jacobcasper.com>
Tue, 14 Apr 2020 04:52:20 +0000 (23:52 -0500)
main.go [new file with mode: 0644]
migrations/003-create_artist_genre_xref.sql [new file with mode: 0644]

diff --git a/main.go b/main.go
new file mode 100644 (file)
index 0000000..8ab8e7b
--- /dev/null
+++ b/main.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+       "git.jacobcasper.com/brackets/client"
+       "git.jacobcasper.com/brackets/db"
+       _ "github.com/mattn/go-sqlite3"
+       "github.com/zmb3/spotify"
+       "log"
+       "net/http"
+)
+
+type handler func(http.ResponseWriter, *http.Request)
+
+func main() {
+       lockedDb, err := db.New()
+       if err != nil {
+               log.Fatal("Could not open db: ", err.Error())
+       }
+
+       client, err := client.Get()
+       if err != nil {
+               log.Fatal("Could not get client: ", err.Error())
+       }
+
+       http.HandleFunc(
+               "/artist/add",
+               addArtistHandler(lockedDb, client),
+       )
+
+       log.Fatal(http.ListenAndServe(":8080", nil))
+}
+
+func addArtistHandler(db *db.DB, c *spotify.Client) handler {
+       return func(w http.ResponseWriter, r *http.Request) {
+               if r.Method != "POST" {
+                       http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+                       return
+               }
+
+               r.ParseForm()
+               artistId := r.PostForm.Get("artist_id")
+
+               if artistId == "" {
+                       http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+                       return
+               }
+
+               artist, err := c.GetArtist(spotify.ID(artistId))
+               if err != nil {
+                       log.Printf("Failed to retrieve artist %s: %s", artistId, err.Error())
+                       http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+                       return
+               }
+
+               db.Mu.Lock()
+               defer db.Mu.Unlock()
+               db.Db.Exec("INSERT INTO ARTIST (ID, NAME) VALUES (?, ?)", artist.ID, artist.Name)
+
+               for _, genre := range artist.Genres {
+                       result, err := db.Db.Exec("REPLACE INTO GENRE (NAME) VALUES (?)", genre)
+                       if err != nil {
+                               log.Printf("Failed to insert genre %s: %s", genre, err.Error())
+                               http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+                               return
+                       }
+
+                       genreId, err := result.LastInsertId()
+                       if err != nil {
+                               log.Print("Failed to retrieve last insert id: ", err.Error())
+                               http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+                               return
+                       }
+
+                       db.Db.Exec("INSERT INTO ARTIST_GENRE_XREF (ARTIST_ID, GENRE_ID) VALUES (?, ?)", artist.ID, genreId)
+               }
+               w.WriteHeader(http.StatusCreated)
+       }
+}
diff --git a/migrations/003-create_artist_genre_xref.sql b/migrations/003-create_artist_genre_xref.sql
new file mode 100644 (file)
index 0000000..25b9f42
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE ARTIST_GENRE_XREF (
+  ID INTEGER PRIMARY KEY AUTOINCREMENT,
+  ARTIST_ID NOT NULL,
+  GENRE_ID NOT NULL,
+  UNIQUE(ARTIST_ID, GENRE_ID),
+  FOREIGN KEY(ARTIST_ID) REFERENCES ARTIST(ID),
+  FOREIGN KEY(GENRE_ID) REFERENCES GENRE(ID)
+);