fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 22h ago
272 lines · 9.1 KB Raw Blame History
1 ;;; emms-idapi-browser.el --- EMMS Music ID API support -*- lexical-binding: t; -*-
2 ;;
3
4 ;; Copyright (C) 2024 Free Software Foundation, Inc.
5
6 ;; Author: Yoni Rabkin <yrk@gnu.org>
7
8 ;; This file is part of EMMS.
9
10 ;; EMMS is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; EMMS is distributed in the hope that it will be useful, but WITHOUT
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 ;; License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with EMMS; see the file COPYING. If not, write to the Free
22 ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 ;; MA 02110-1301, USA.
24
25
26 ;;; Commentary:
27 ;;
28
29 (defvar emms-idapi-browser-debug-name
30 " *Emms Search Debug Browser*"
31 "Name of the search browser debug buffer")
32
33 (defvar emms-idapi-browser-debug-buffer
34 nil
35 "Search browser debug buffer")
36
37 (defvar emms-idapi-browser-name
38 "Emms Search Browser"
39 "Name of the search browser buffer")
40
41 (defvar emms-idapi-browser-buffer
42 nil
43 "Search browser buffer")
44
45 (defvar emms-idapi-browser-mode-hook nil
46 "Emms search browser mode hook.")
47
48 (defvar emms-idapi-browser-field-alist
49 '(("artist" . info-artist)
50 ("album" . info-album)
51 ("track" . info-title))
52 "Association list of readable fields and track properties.")
53
54 ;;; Code:
55 (require 'emms-idapi)
56
57
58 ;;; ------------------------------------------------------------------
59 ;;; Search Mode
60 ;;; ------------------------------------------------------------------
61 (defun emms-idapi-browser-get-buffer ()
62 "Get/create and return `emms-idapi-browser-mode' buffer."
63 (when (or (not emms-idapi-browser-buffer)
64 (not (buffer-live-p emms-idapi-browser-buffer)))
65 (with-current-buffer (get-buffer-create emms-idapi-browser-name)
66 (when (not (equal major-mode 'emms-idapi-browser-mode))
67 (emms-idapi-browser-mode))))
68 emms-idapi-browser-buffer)
69
70 (defvar emms-idapi-browser-mode-map
71 (let ((map (make-sparse-keymap)))
72 (define-key map (kbd "q") #'bury-buffer)
73 map)
74 "Keymap for `emms-idapi-browser-mode'.")
75
76 (defun emms-idapi-browser-mode ()
77 "A major mode for the Emms search browser.
78 \\{emms-idapi-browser-mode-map}"
79 (interactive)
80
81 (use-local-map emms-idapi-browser-mode-map)
82
83 (setq major-mode 'emms-idapi-browser-mode
84 mode-name "Emms-Search-Browser"
85 buffer-read-only t
86 emms-idapi-browser-buffer (current-buffer))
87
88 (run-hooks 'emms-idapi-browser-mode-hook))
89
90
91 ;;; ------------------------------------------------------------------
92 ;;; Call
93 ;;; ------------------------------------------------------------------
94 (defun emms-idapi-browser-track-at ()
95 "Return a copy of the track at point."
96 (let* ((originial-track (emms-playlist-track-at (point)))
97 (track (copy-sequence originial-track)))
98 (when (not (emms-track-p track))
99 (error "could not read Emms track at point"))
100 track))
101
102 (defun emms-idapi-browser-search-recording-artist (track)
103 "Search for the recording and artist of TRACK."
104 (let ((recording (alist-get 'info-title track))
105 (artist (or (alist-get 'info-artist track)
106 (alist-get 'info-albumartist track))))
107 (list
108 (cons 'info-title (read-string "search for recording (track): " recording))
109 (cons 'info-artist (read-string "search for artist: " artist)))))
110
111 (defun emms-idapi-browser-search-recording (track)
112 "Search for the recording of TRACK."
113 (let ((recording (alist-get 'info-title track)))
114 (list
115 (cons 'info-title (read-string "search for recording (track): " recording)))))
116
117 (defun emms-idapi-browser-search-artist (track)
118 "Search for the artist of TRACK."
119 (let ((artist (or (alist-get 'info-artist track)
120 (alist-get 'info-albumartist track))))
121 (list
122 (cons 'info-artist (read-string "search for artist: " artist)))))
123
124 (defun emms-idapi-browser-search-album (track)
125 "Search for the album of TRACK."
126 (let ((album (alist-get 'info-album track)))
127 (list
128 (cons 'info-album (read-string "search for album: " album)))))
129
130 (defun emms-idapi-browser-search-album-artist (track)
131 "Search for both artist and album of TRACK."
132 (let ((artist (or (alist-get 'info-artist track)
133 (alist-get 'info-albumartist track)))
134 (album (alist-get 'info-album track))
135 search-album)
136 (setq search-album (read-string "search for album: " album))
137 (list
138 (cons 'info-album search-album)
139 (cons 'info-artist (read-string
140 (format "search for album \"%s\" by artist: " search-album)
141 artist)))))
142
143 (defun emms-idapi-browser-search-recording-artist-at ()
144 "Search for the recording and artist of the track at point."
145 (interactive)
146 (emms-idapi-browser-show
147 (emms-idapi-search emms-idapi-service
148 (emms-idapi-browser-search-recording-artist
149 (emms-playlist-track-at (point))))))
150
151 (defun emms-idapi-browser-search-recording-at ()
152 "Search for the recording of the track at point."
153 (interactive)
154 (emms-idapi-browser-show
155 (emms-idapi-search emms-idapi-service
156 (emms-idapi-browser-search-recording
157 (emms-playlist-track-at (point))))))
158
159 (defun emms-idapi-browser-search-artist-at ()
160 "Search for the artist of the track at point."
161 (interactive)
162 (emms-idapi-browser-show
163 (emms-idapi-search emms-idapi-service
164 (emms-idapi-browser-search-artist
165 (emms-playlist-track-at (point))))))
166
167 (defun emms-idapi-browser-search-album-at ()
168 "Search for the album of the track at point."
169 (interactive)
170 (emms-idapi-browser-show
171 (emms-idapi-search emms-idapi-service
172 (emms-idapi-browser-search-album
173 (emms-playlist-track-at (point))))))
174
175 (defun emms-idapi-browser-search-album-artist-at ()
176 "Search for the album and artist of the track at point."
177 (interactive)
178 (emms-idapi-browser-show
179 (emms-idapi-search emms-idapi-service
180 (emms-idapi-browser-search-album-artist
181 (emms-playlist-track-at (point))))))
182
183 ;;; ------------------------------------------------------------------
184 ;;; Response
185 ;;; ------------------------------------------------------------------
186 (defun emms-idapi-browser-write-debug (response)
187 "Write RESPONSE to the browser debug buffer."
188 (let ((buffer (get-buffer-create emms-idapi-browser-debug-name)))
189 (with-current-buffer buffer
190 (erase-buffer)
191 (insert (format "%s" response))
192 (setq emms-idapi-browser-debug-buffer buffer))))
193
194 (defun emms-idapi-browser-print-header (header)
195 "Print the material for the search HEADER."
196 (let ((artist (alist-get 'info-artist header))
197 (album (alist-get 'info-album header))
198 (title (alist-get 'info-title header))
199 (service (alist-get emms-idapi-service emms-idapi-services-alist)))
200 (when (not (or artist album title))
201 (error "could not read header: %s" header))
202 (insert (format "service: %s (%s)\n"
203 (alist-get 'name service)
204 (alist-get 'website service)))
205 (when artist
206 (insert (format "artist: %s\n" artist)))
207 (when album
208 (insert (format "album: %s\n" album)))
209 (when title
210 (insert (format "title: %s\n" title)))
211 (insert "\n")))
212
213 (defun emms-idapi-browser-entry-packaging (entry)
214 "Print packaging information for ENTRY."
215 (let ((packaging (alist-get 'info-packaging entry)))
216 (if (and packaging
217 (not (string= "None" packaging)))
218 (format ", %s" packaging)
219 "")))
220
221 (defun emms-idapi-browser-print-entry-artist (entry)
222 "Return artist ENTRY."
223 (format "%s%s%s\n\n"
224 (alist-get 'info-artist entry)
225 (if (alist-get 'info-country entry)
226 (format " (%s) " (alist-get 'info-country entry))
227 "")
228 (let ((begin (alist-get 'begin (alist-get 'info-time entry)))
229 (end (alist-get 'end (alist-get 'info-time entry))))
230 (format "%s%s"
231 (if begin begin "")
232 (if end (format " - %s, " end) "")))))
233
234 (defun emms-idapi-browser-print-entry (entry)
235 "Print ENTRY."
236 (cond ((equal 'idapi-release (alist-get 'type entry))
237 (insert (format "\"%s\" by %s%s\n"
238 (alist-get 'info-album entry)
239 (alist-get 'info-artist entry)
240 (if (alist-get 'info-date entry)
241 (format ", released on %s" (alist-get 'info-date entry))
242 "")))
243
244 (insert (format "%s tracks%s%s\n\n"
245 (alist-get 'info-track-count entry)
246 (emms-idapi-browser-entry-packaging entry)
247 (if (alist-get 'info-country entry)
248 (format ", (%s)" (alist-get 'info-country entry))
249 ""))))
250
251 ((equal 'idapi-artist (alist-get 'type entry))
252 (insert (emms-idapi-browser-print-entry-artist entry)))
253
254 (t (insert (format "unhandled entry:\n\n%s\n" entry)))))
255
256 (defun emms-idapi-browser-show (response)
257 "Display RESPONSE in a search buffer."
258 (emms-idapi-browser-write-debug response)
259 (let ((buffer (emms-idapi-browser-get-buffer)))
260 (pop-to-buffer buffer)
261 (let ((inhibit-read-only t))
262 (erase-buffer)
263 (insert "Emms Music Search Query\n\n")
264 (emms-idapi-browser-print-header (car response))
265 (insert (format "%d results\n\n" (length (cdr response))))
266 (dolist (e (cdr response))
267 (emms-idapi-browser-print-entry e)))))
268
269
270 (provide 'emms-idapi-browser)
271
272 ;;; emms-idapi-browser.el ends here