diff options
| author | Yoni Rabkin <yoni@rabkins.net> | 2011-01-27 20:11:20 -0500 | 
|---|---|---|
| committer | Yoni Rabkin <yoni@rabkins.net> | 2011-01-27 20:11:20 -0500 | 
| commit | 10f15c1aad77a92fa6ac180454f4b53f73f22c55 (patch) | |
| tree | c48a240d86ce06eca8e8399097fd9ef3ed8e2060 | |
| parent | b416748e47b3573ae8f0d5d558cb4d8d70a4ebfd (diff) | |
* lisp/emms-lastfm-client.el: Implement artist.getInfo.
| -rw-r--r-- | lisp/emms-lastfm-client.el | 142 | 
1 files changed, 140 insertions, 2 deletions
| diff --git a/lisp/emms-lastfm-client.el b/lisp/emms-lastfm-client.el index 09651f1..7e2f7ac 100644 --- a/lisp/emms-lastfm-client.el +++ b/lisp/emms-lastfm-client.el @@ -34,6 +34,7 @@  (require 'emms)  (require 'emms-source-file)  (require 'xml) +(require 'w3m)  (require 'emms-lastfm-scrobbler)  (defcustom emms-lastfm-client-username nil @@ -72,6 +73,12 @@  	  "emms-lastfm-client-sessionkey")    "File for storing the Last.fm API session key.") +(defvar emms-lastfm-client-cache-directory +  (file-name-as-directory +   (concat (file-name-as-directory emms-directory) +	   "emms-lastfm-client-cache")) +  "File for storing Last.fm cache data.") +  (defvar emms-lastfm-client-playlist-valid nil    "True if the playlist hasn't expired.") @@ -87,7 +94,8 @@  (defvar emms-lastfm-client-original-next-function nil    "Original `-next-function'.") -(defvar emms-lastfm-client-playlist-buffer-name "*Emms Last.fm*" +(defvar emms-lastfm-client-playlist-buffer-name +  "*Emms Last.fm*"    "Name for non-interactive Emms Last.fm buffer.")  (defvar emms-lastfm-client-playlist-buffer nil @@ -96,6 +104,13 @@  (defvar emms-lastfm-client-inhibit-cleanup nil    "If true, do not perform clean-up after `emms-stop'.") +(defvar emms-lastfm-client-image-size "mega" +  "Default size for artist information images.") + +(defvar emms-lastfm-client-artist-info-buffer-name +  "*Emms Last.fm Artist Info*" +  "Name for displaying artist information.") +  (defvar emms-lastfm-client-api-method-dict    '((auth-get-token    . ("auth.gettoken"  			  emms-lastfm-client-auth-get-token-ok @@ -114,7 +129,10 @@  			  emms-lastfm-client-track-love-failed))      (track-ban         . ("track.ban"  			  emms-lastfm-client-track-ban-ok -			  emms-lastfm-client-track-ban-failed))) +			  emms-lastfm-client-track-ban-failed)) +    (artist-getinfo    . ("artist.getinfo" +			  emms-lastfm-client-artist-getinfo-ok +			  emms-lastfm-client-artist-getinfo-failed)))    "Mapping symbols to method calls. This is a list of cons pairs    where the CAR is the symbol name of the method and the CDR is a    list whose CAR is the method call string, CADR is the function @@ -560,6 +578,11 @@ This function includes the cryptographic signature."    "Run per-session functions."    (emms-lastfm-client-check-session-key)) +(defun emms-lastfm-client-info () +  "Display information about the latest track." +  (interactive) +  (emms-lastfm-client-make-call-artist-getinfo)) +  ;;; ------------------------------------------------------------------  ;;; Stations  ;;; ------------------------------------------------------------------ @@ -919,6 +942,121 @@ This function includes the cryptographic signature."    'track-love-succeed)  ;;; ------------------------------------------------------------------ +;;; method: artist.getInfo [http://www.last.fm/api/show?service=267] +;;; ------------------------------------------------------------------ + +(defun emms-lastfm-client-cache-file (url) +  "Download a file from URL and return a pathname." +  (make-directory emms-lastfm-client-cache-directory t) +  (let ((files (directory-files emms-lastfm-client-cache-directory +				t))) +    (dolist (file files) +      (when (file-regular-p file) +	(delete-file file))) +    (call-process "wget" nil nil nil url "-P" +		  (expand-file-name +		   emms-lastfm-client-cache-directory)) +    (car (directory-files emms-lastfm-client-cache-directory +			  t ".jpg")))) + +(defun emms-lastfm-client-display-artist-getinfo (artist-name +						  lastfm-url +						  artist-image +						  stats-listeners +						  stats-playcount +						  bio-summary +						  bio-complete) +  "Display a buffer with the artist information." +  (let ((buf (get-buffer-create +	      emms-lastfm-client-artist-info-buffer-name))) +    (with-current-buffer buf +      (let ((inhibit-read-only t)) +	(delete-region (point-min) (point-max)) +	(insert-image +	 (create-image (emms-lastfm-client-cache-file artist-image))) +	(insert (format "\n\n%s\n\n" +			(decode-coding-string artist-name 'utf-8))) +	(insert (format "Last.fm page: %s\n\n" lastfm-url)) +	(insert (format "Listeners: %s\n" stats-listeners)) +	(insert (format "Plays: %s\n\n" stats-playcount)) +	(let ((p (point))) +	  (insert (format "<p>%s</p>" bio-complete)) +	  (w3m-region p (point)))) +      (setq buffer-read-only t) +      (text-mode) +      (goto-char (point-min))) +    (switch-to-buffer buf))) + +(defun emms-lastfm-client-parse-artist-getinfo (data) +  "Parse the artist information." +  (when (or (not data) +	    (not (listp data))) +    (error "no artist info to parse")) +  (let ((c (copy-seq (nth 1 data))) +	artist-name lastfm-url artist-image +	stats-listeners stats-playcount +	bio-summary bio-complete) +    (while c +      (let ((entry (car c))) +	(when (listp entry) +	  (let ((name (nth 0 entry)) +		(value (nth 2 entry))) +	    (cond ((equal name 'name) (setq artist-name value)) +		  ((equal name 'url)  (setq lastfm-url value)) +		  ((equal name 'image) +		   (let ((size (cdar (nth 1 entry)))) +		     (when (string-equal emms-lastfm-client-image-size +					 size) +		       (setq artist-image value)))) +		  ((equal name 'stats) +		   (setq stats-listeners (nth 2 (nth 3 entry)) +			 stats-playcount (nth 2 (nth 5 entry)))) +		  ((equal name 'bio) +		   (setq bio-summary (nth 2 (nth 5 entry)) +			 bio-complete (nth 2 (nth 7 entry)))))))) +      (setq c (cdr c))) +    (emms-lastfm-client-display-artist-getinfo +     artist-name lastfm-url artist-image +     stats-listeners stats-playcount +     bio-summary bio-complete))) + +(defun emms-lastfm-client-construct-artist-getinfo () +  "Return a request for getting info about an artist." +  (let ((arguments +	 (emms-lastfm-client-encode-arguments +	  `(("sk"      . ,emms-lastfm-client-api-session-key) +	    ("api_key" . ,emms-lastfm-client-api-key) +	    ("autocorrect" . "1") +	    ("artist"  . ,(emms-lastfm-client-xspf-get +			   'creator emms-lastfm-client-track)))))) +    (emms-lastfm-client-construct-write-method-call +     'artist-getinfo arguments))) + +(defun emms-lastfm-client-make-call-artist-getinfo () +  "Make a call for artist info." +  (let ((url-request-method "POST") +	(url-request-extra-headers +	 `(("Content-type" . "application/x-www-form-urlencoded"))) +	(url-request-data +	 (emms-lastfm-client-construct-artist-getinfo))) +    (let ((response +	   (url-retrieve-synchronously +	    emms-lastfm-client-api-base-url))) +      (emms-lastfm-client-handle-response +       'artist-getinfo +       (with-current-buffer response +	 (xml-parse-region (point-min) (point-max))))))) + +(defun emms-lastfm-client-artist-getinfo-failed (data) +  "Function called with DATA when setting `ban' rating fails." +  'stub-needs-to-handle-artist-getinfo-issues +  (emms-lastfm-client-default-error-handler data)) + +(defun emms-lastfm-client-artist-getinfo-ok (data) +  "Function called with DATA after `ban' rating succeeds." +  (emms-lastfm-client-parse-artist-getinfo data)) + +;;; ------------------------------------------------------------------  ;;; method: track.ban [http://www.last.fm/api/show?service=261]  ;;; ------------------------------------------------------------------ | 
