diff options
Diffstat (limited to 'src/dionysus/spotify.clj')
| -rw-r--r-- | src/dionysus/spotify.clj | 70 |
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)) |
