aboutsummaryrefslogtreecommitdiff
path: root/src/dionysus/spotify.clj
diff options
context:
space:
mode:
Diffstat (limited to 'src/dionysus/spotify.clj')
-rw-r--r--src/dionysus/spotify.clj70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/dionysus/spotify.clj b/src/dionysus/spotify.clj
new file mode 100644
index 0000000..531c825
--- /dev/null
+++ b/src/dionysus/spotify.clj
@@ -0,0 +1,70 @@
+(ns dionysus.spotify
+ (:require [clj-spotify.core :as spotify-api]
+ [hato.client :as hc]
+ [dotenv :as env]
+ [overtone.at-at :as at])
+ (:import (java.util Date Calendar)))
+
+(def token (atom nil))
+
+(defn search! [query] (spotify-api/search {:q query :type "track"} (:token @token)))
+
+(defn add-item-to-queue! [uri] ((spotify-api/api-post "me/player/queue" {:query-params [:uri]})
+ {:uri uri} (:token @token)))
+
+(defn get-current-track! [] (spotify-api/get-users-currently-playing-track {} (:token @token)))
+#_(:item (get-current-track!))
+
+(defn get-track! [id] (spotify-api/get-a-track {:id id} (:token @token)))
+
+(defn get-artist! [id] (spotify-api/get-an-artist {:id id} (:token @token)))
+
+(defn parse-share-url [url]
+ (when-let [parsed (->> url
+ (re-seq #"https:\/\/open\.spotify\.com\/intl-de\/(track|artist)\/([0-9A-z]*)")
+ first)]
+ {:url (first parsed)
+ :type (second parsed)
+ :id (last parsed)}))
+
+(defn time-to-refresh-token? []
+ (when-let [t @token]
+ (-> t
+ :expires
+ .getTime
+ (- (.getTime (Date.)))
+ (< 120000) ; Is token valid for under two minutes?
+ )))
+
+(def ^:private http-client (delay (hc/build-http-client {})))
+
+(defn- update-token! [refresh-resp-body]
+ (swap! token assoc :token (get refresh-resp-body "access_token"))
+ (swap! token assoc :expires (let [calendar-instance (Calendar/getInstance)]
+ (.setTime calendar-instance (Date.))
+ (.add calendar-instance Calendar/SECOND (get refresh-resp-body "expires_in"))
+ (.getTime calendar-instance))))
+
+(defn- request-new-token! []
+ (hc/post "https://accounts.spotify.com/api/token"
+ {:http-client @http-client
+ :throw-exceptions? false
+ :content-type "application/x-www-form-urlencoded"
+ :form-params {"grant_type" "refresh_token"
+ "refresh_token" (:refresh-token @token)}
+ :basic-auth {:user (env/env "SPOTIFY_CLIENT_ID")
+ :pass (env/env "SPOTIFY_CLIENT_SECRET")}
+ :as :json-string-keys}))
+
+(defn- refresh-token! []
+ (when (time-to-refresh-token?)
+ (let [resp (request-new-token!)]
+ (if (= (:status resp) 200)
+ (do (update-token! (:body resp))
+ (println "refreshed token"))
+ (println "refreshing token failed")))))
+
+(def ^:private at-pool (at/mk-pool))
+
+(defn start-token-watcher! []
+ (at/every 60000 refresh-token! at-pool))