-
Notifications
You must be signed in to change notification settings - Fork 21
/
helm-spotify.el
131 lines (109 loc) · 4.3 KB
/
helm-spotify.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
;;; helm-spotify.el --- Control Spotify with Helm.
;; Copyright 2013 Kris Jenkins
;;
;; Author: Kris Jenkins <[email protected]>
;; Maintainer: Kris Jenkins <[email protected]>
;; Keywords: helm spotify
;; 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