Added artist.gettoptags API

master
Abhinav Sarkar 2010-07-24 11:52:23 +05:30
parent e8f36cecd8
commit 544c0be318
2 changed files with 59 additions and 24 deletions

View File

@ -9,6 +9,7 @@
[clojure.contrib.logging])) [clojure.contrib.logging]))
(import-static java.lang.Integer parseInt) (import-static java.lang.Integer parseInt)
(import-static java.lang.Double parseDouble)
;;;;;;;;;; Basic ;;;;;;;;;; ;;;;;;;;;; Basic ;;;;;;;;;;
@ -21,14 +22,14 @@
(throw (IllegalStateException. "lastfm API key is not set")) (throw (IllegalStateException. "lastfm API key is not set"))
lastfm-api-key))) lastfm-api-key)))
(def guid-pattern (def #^{:private true} guid-pattern
#"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") #"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$")
(def #^{:private true} sdf (def #^{:private true} sdf
(doto (SimpleDateFormat. "EEE, dd MMMM yyyy HH:mm:ss +0000") (doto (SimpleDateFormat. "EEE, dd MMMM yyyy HH:mm:ss +0000")
(.setTimeZone (TimeZone/getTimeZone "GMT")))) (.setTimeZone (TimeZone/getTimeZone "GMT"))))
(defn parse-date [date-str] (defn- parse-date [date-str]
(.parse sdf date-str)) (.parse sdf date-str))
(defn- remove-nil-values [m] (defn- remove-nil-values [m]
@ -65,34 +66,38 @@
(let [url (create-url params)] (let [url (create-url params)]
(-> url get-url read-json keywordize-keys))) (-> url get-url read-json keywordize-keys)))
(defn create-get-obj-fn [fixed-params parse-fn] (defn- create-get-obj-fn [fixed-params parse-fn]
(fn [more-params] (fn [more-params]
(parse-fn (get-data (merge fixed-params more-params))))) (parse-fn (get-data (merge fixed-params more-params)))))
(defn create-get-obj-field-fn [create-obj-fn extract-obj-id-fields-fn] (defn- create-get-obj-field-fn [create-obj-fn extract-obj-id-fields-fn]
(fn [obj field-kw] (fn [obj field-kw]
(let [field-val (obj field-kw)] (let [field-val (obj field-kw)]
(if (nil? field-val) (if (nil? field-val)
((apply create-obj-fn (extract-obj-id-fields-fn obj)) field-kw) ((apply create-obj-fn (extract-obj-id-fields-fn obj)) field-kw)
field-val)))) field-val))))
;;;;;;;;;; forward declaration ;;;;;;;;;;
(declare bio-struct artist-struct tag-struct)
;;;;;;;;;; Bio/Wiki ;;;;;;;;;; ;;;;;;;;;; Bio/Wiki ;;;;;;;;;;
(defstruct bio-struct :published :summary :content) (defstruct bio-struct :published :summary :content)
(defn parse-bio [data] (defn- parse-bio [data]
(struct (struct
bio-struct bio-struct
(-> data :published parse-date) (-> data :published parse-date)
(-> data :summary) (-> data :summary)
(-> data :content))) (-> data :content)))
;;;;;;;;;; Artist ;;;;;;;;;; ;;;;;;;;;; artist.getinfo ;;;;;;;;;;
(defstruct artist-struct (defstruct artist-struct
:name :url :mbid :streamable :listeners :playcount :bio) :name :url :mbid :streamable :listeners :playcount :bio)
(defn parse-artist [data] (defn- parse-artist [data]
(struct (struct
artist-struct artist-struct
(-> data :artist :name) (-> data :artist :name)
@ -125,30 +130,57 @@
(def artist-info (def artist-info
(create-get-obj-field-fn artist #(vector (% :name)))) (create-get-obj-field-fn artist #(vector (% :name))))
(defn parse-artist-similar [data] ;;;;;;;;;; artist.getsimilar ;;;;;;;;;;
(map
#(struct artist-struct (defn- parse-artist-similar [data]
(% :name) (vec
(% :url) (map
(% :mbid) #(struct-map artist-struct
(= 1 (-> % :streamable parseInt)) :name (% :name)
nil nil nil) :url (% :url)
(-> data :similarartists :artist))) :mbid (% :mbid)
:streamable (= 1 (-> % :streamable parseInt))
:match (-> % :match parseDouble))
(-> data :similarartists :artist))))
(def #^{:private true} get-artist-similar (def #^{:private true} get-artist-similar
(create-get-obj-fn {:method "artist.getsimilar"} parse-artist-similar)) (create-get-obj-fn {:method "artist.getsimilar"} parse-artist-similar))
(defmulti artist-similar (defn- artist-or-name [artst-or-name & _]
(fn [artst-or-name & _] (if (instance? clojure.lang.PersistentStructMap artst-or-name)
(instance? clojure.lang.PersistentStructMap artst-or-name))) :artist :name))
(defmethod artist-similar true (defmulti artist-similar artist-or-name)
(defmethod artist-similar :artist
([artst] (-> artst :name artist-similar)) ([artst] (-> artst :name artist-similar))
([artst limit] (artist-similar (artst :name) limit))) ([artst limit] (artist-similar (artst :name) limit)))
(defmethod artist-similar false (defmethod artist-similar :name
([artist-name] (get-artist-similar {:artist artist-name})) ([artist-name]
([artist-name limit] (get-artist-similar {:artist artist-name :limit limit}))) (get-artist-similar {:artist artist-name}))
([artist-name limit]
(get-artist-similar {:artist artist-name :limit limit})))
;;;;;;;;;; artist.gettoptags ;;;;;;;;;;
(defn- parse-artist-toptags [data]
(vec (map #(struct tag-struct (% :name) (% :url)) (-> data :toptags :tag))))
(def #^{:private true} get-artist-toptags
(create-get-obj-fn {:method "artist.gettoptags"} parse-artist-toptags))
(defmulti artist-toptags artist-or-name)
(defmethod artist-toptags :artist [artst]
(-> artst :name artist-toptags))
(defmethod artist-toptags :name [artist-name]
(get-artist-toptags {:artist artist-name}))
;;;;;;;;;; tag ;;;;;;;;;;
(defstruct tag-struct :name :url)
(comment (comment

View File

@ -1,6 +1,7 @@
(ns clj-lastfm.filecache (ns clj-lastfm.filecache
(:import (java.io File)) (:import (java.io File))
(:use clojure.contrib.duck-streams)) (:use [clojure.contrib.duck-streams]
[clojure.contrib.logging]))
(def default-cache-dir (File. (System/getProperty "java.io.tmpdir"))) (def default-cache-dir (File. (System/getProperty "java.io.tmpdir")))
(def default-expiry-time (* 24 60)) ;in minutes (def default-expiry-time (* 24 60)) ;in minutes
@ -25,7 +26,9 @@
cache-file (File. (str (.getCanonicalPath cache-dir) cache-file (File. (str (.getCanonicalPath cache-dir)
File/separator "clj-lastfm-" url-hash))] File/separator "clj-lastfm-" url-hash))]
(do (do
(debug (str "getting URL: " url))
(when-not (and (.exists cache-file) (recently-modified? cache-file expiry-time)) (when-not (and (.exists cache-file) (recently-modified? cache-file expiry-time))
(debug "cache missed")
(copy (reader url) cache-file)) (copy (reader url) cache-file))
(slurp (.getCanonicalPath cache-file))))) (slurp (.getCanonicalPath cache-file)))))