my-emacs-d/elpa/helm-spotify-20160905.1447/helm-spotify.el

133 lines
4.3 KiB
EmacsLisp

;;; helm-spotify.el --- Control Spotify with Helm.
;; Copyright 2013 Kris Jenkins
;;
;; Author: Kris Jenkins <krisajenkins@gmail.com>
;; Maintainer: Kris Jenkins <krisajenkins@gmail.com>
;; Keywords: helm spotify
;; Package-Version: 20160905.1447
;; URL: https://github.com/krisajenkins/helm-spotify
;; Created: 14th October 2013
;; Version: 0.1.1
;; Package-Requires: ((helm "0.0.0") (multi "2.0.0"))
;;; Commentary:
;;
;; A search & play interface for Spotify.
;;
;; Currently supports OSX, Linux & Windows.
;;
;; (Want support for another platform? There's a guide in the github README.)
;;; Code:
;;; API Reference: https://developer.spotify.com/technologies/web-api/
(require 'url)
(require 'json)
(require 'helm)
(require 'multi)
(defun alist-get (symbols alist)
"Look up the value for the chain of SYMBOLS in ALIST."
(if symbols
(alist-get (cdr symbols)
(assoc (car symbols) alist))
(cdr alist)))
(defmulti spotify-play-href (href)
"Get the Spotify app to play the object with the given HREF."
system-type)
(defmulti-method spotify-play-href 'darwin
(href)
(shell-command (format "osascript -e 'tell application %S to play track %S'"
"Spotify"
href)))
(defmulti-method spotify-play-href 'gnu/linux
(href)
(shell-command "dbus-send --print-reply --session --type=method_call --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause")
(shell-command (format "dbus-send --session --type=method_call --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.OpenUri \"string:%s\""
href)))
(defmulti-method spotify-play-href 'windows-nt
(href)
(shell-command (format "explorer %S" href)))
(defmulti-method-fallback spotify-play-href
(href)
(message "Sorry, helm-spotify does not support playing tracks on %S." system-type))
(defun spotify-play-track (track)
"Get the Spotify app to play the TRACK."
(spotify-play-href (alist-get '(uri) track)))
(defun spotify-get-track (album-href)
(let ((response (with-current-buffer
(url-retrieve-synchronously album-href)
(goto-char url-http-end-of-headers)
(json-read))))
(aref (alist-get '(tracks items) response) 0)))
(defun spotify-play-album (track)
"Get the Spotify app to play the album for this TRACK."
(let ((first-track (spotify-get-track (alist-get '(album href) track))))
(spotify-play-href (alist-get '(uri) first-track))))
(defun spotify-search (search-term)
"Search spotify for SEARCH-TERM, returning the results as a Lisp structure."
(let ((a-url (format "https://api.spotify.com/v1/search?q=%s&type=track" search-term)))
(with-current-buffer
(url-retrieve-synchronously a-url)
(goto-char url-http-end-of-headers)
(json-read))))
(defun spotify-format-track (track)
"Given a TRACK, return a a formatted string suitable for display."
(let ((track-name (alist-get '(name) track))
(track-length (/ (alist-get '(duration_ms) track) 1000))
(album-name (alist-get '(album name) track))
(artist-names (mapcar (lambda (artist)
(alist-get '(name) artist))
(alist-get '(artists) track))))
(format "%s (%dm%0.2ds)\n%s - %s"
track-name
(/ track-length 60) (mod track-length 60)
(mapconcat 'identity artist-names "/")
album-name)))
(defun spotify-search-formatted (search-term)
(mapcar (lambda (track)
(cons (spotify-format-track track) track))
(alist-get '(tracks items) (spotify-search search-term))))
(defun helm-spotify-search ()
(spotify-search-formatted helm-pattern))
(defun helm-spotify-actions-for-track (actions track)
"Return a list of helm ACTIONS available for this TRACK."
`((,(format "Play Track - %s" (alist-get '(name) track)) . spotify-play-track)
(,(format "Play Album - %s" (alist-get '(album name) track)) . spotify-play-album)
("Show Track Metadata" . pp)))
;;;###autoload
(defvar helm-source-spotify-track-search
'((name . "Spotify")
(volatile)
(delayed)
(multiline)
(requires-pattern . 2)
(candidates-process . helm-spotify-search)
(action-transformer . helm-spotify-actions-for-track)))
;;;###autoload
(defun helm-spotify ()
"Bring up a Spotify search interface in helm."
(interactive)
(helm :sources '(helm-source-spotify-track-search)
:buffer "*helm-spotify*"))
(provide 'helm-spotify)
;;; helm-spotify.el ends here