branch: externals/emms
commit cead7b435a679690fd4bbe91fa2f57739a1e0077
Author: Yoni Rabkin <y...@gnu.org>
Commit: Yoni Rabkin <y...@gnu.org>

    emms-idapi: track (recording) features and debug buffers
---
 emms-idapi-browser.el     | 88 ++++++++++++++++++++++++++++++++++++--------
 emms-idapi-musicbrainz.el | 93 +++++++++++++++++++++++++++++++++--------------
 2 files changed, 139 insertions(+), 42 deletions(-)

diff --git a/emms-idapi-browser.el b/emms-idapi-browser.el
index 84b6386893..d89a32666b 100644
--- a/emms-idapi-browser.el
+++ b/emms-idapi-browser.el
@@ -26,6 +26,14 @@
 ;;; Commentary:
 ;;
 
+(defvar emms-idapi-browser-debug-name
+  " *Emms Search Debug Browser*"
+  "Name of the search browser debug buffer")
+
+(defvar emms-idapi-browser-debug-buffer
+  nil
+  "Search browser debug buffer")
+
 (defvar emms-idapi-browser-name
   "Emms Search Browser"
   "Name of the search browser buffer")
@@ -91,6 +99,21 @@
       (error "could not read Emms track at point"))
     track))
 
+(defun emms-idapi-browser-search-recording-artist (track)
+  "Search for the recording and artist of TRACK."
+  (let ((recording (alist-get 'info-title track))
+       (artist (or (alist-get 'info-artist track)
+                   (alist-get 'info-albumartist track))))
+    (list
+     (cons 'info-title (read-string "search for recording (track): " 
recording))
+     (cons 'info-artist (read-string "search for artist: " artist)))))
+
+(defun emms-idapi-browser-search-recording (track)
+  "Search for the recording of TRACK."
+  (let ((recording (alist-get 'info-title track)))
+    (list
+     (cons 'info-title (read-string "search for recording (track): " 
recording)))))
+
 (defun emms-idapi-browser-search-artist (track)
   "Search for the artist of TRACK."
   (let ((artist (or (alist-get 'info-artist track)
@@ -117,6 +140,22 @@
                         (format "search for album \"%s\" by artist: " 
search-album)
                         artist)))))
 
+(defun emms-idapi-browser-search-recording-artist-at ()
+  "Search for the recording and artist of the track at point."
+  (interactive)
+  (emms-idapi-browser-show
+   (emms-idapi-search emms-idapi-service
+                     (emms-idapi-browser-search-recording-artist
+                      (emms-playlist-track-at (point))))))
+
+(defun emms-idapi-browser-search-recording-at ()
+  "Search for the recording of the track at point."
+  (interactive)
+  (emms-idapi-browser-show
+   (emms-idapi-search emms-idapi-service
+                     (emms-idapi-browser-search-recording
+                      (emms-playlist-track-at (point))))))
+
 (defun emms-idapi-browser-search-artist-at ()
   "Search for the artist of the track at point."
   (interactive)
@@ -144,12 +183,21 @@
 ;;; ------------------------------------------------------------------
 ;;; Response
 ;;; ------------------------------------------------------------------
+(defun emms-idapi-browser-write-debug (response)
+  "Write RESPONSE to the browser debug buffer."
+  (let ((buffer (get-buffer-create emms-idapi-browser-debug-name)))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (insert (format "%s" response))
+      (setq emms-idapi-browser-debug-buffer buffer))))
+
 (defun emms-idapi-browser-print-header (header)
   "Print the material for the search HEADER."
   (let ((artist (alist-get 'info-artist header))
-       (album (alist-get 'info-album header))
+       (album  (alist-get 'info-album header))
+       (title  (alist-get 'info-title header))
        (service (alist-get emms-idapi-service emms-idapi-services-alist)))
-    (when (not (or artist album))
+    (when (not (or artist album title))
       (error "could not read header: %s" header))
     (insert (format "service: %s (%s)\n"
                    (alist-get 'name service)
@@ -158,6 +206,8 @@
       (insert (format "artist:  %s\n" artist)))
     (when album
       (insert (format "album:   %s\n" album)))
+    (when title
+      (insert (format "title:   %s\n" title)))
     (insert "\n")))
 
 (defun emms-idapi-browser-entry-packaging (entry)
@@ -168,36 +218,44 @@
        (format ", %s" packaging)
       "")))
 
+(defun emms-idapi-browser-print-entry-artist (entry)
+  "Return artist ENTRY."
+  (format "%s%s%s\n\n"
+         (alist-get 'info-artist entry)
+         (if (alist-get 'info-country entry)
+             (format " (%s) " (alist-get 'info-country entry))
+           "")
+         (let ((begin (alist-get 'begin (alist-get 'info-time entry)))
+               (end (alist-get 'end (alist-get 'info-time entry))))
+           (format "%s%s"
+                   (if begin begin "")
+                   (if end (format " - %s, " end) "")))))
+
 (defun emms-idapi-browser-print-entry (entry)
   "Print ENTRY."
-  (cond ((equal 'info-release (alist-get 'type entry))
+  (cond ((equal 'idapi-release (alist-get 'type entry))
         (insert (format "\"%s\" by %s%s\n"
                         (alist-get 'info-album entry)
                         (alist-get 'info-artist entry)
                         (if (alist-get 'info-date entry)
                             (format ", released on %s" (alist-get 'info-date 
entry))
                           "")))
+
         (insert (format "%s tracks%s%s\n\n"
                         (alist-get 'info-track-count entry)
                         (emms-idapi-browser-entry-packaging entry)
                         (if (alist-get 'info-country entry)
                             (format ", (%s)" (alist-get 'info-country entry))
                           ""))))
-       ((equal 'info-track-artist (alist-get 'type entry))
-        (insert (format "%s%s%s\n\n"
-                        (alist-get 'info-artist entry)
-                        (if (alist-get 'info-country entry)
-                            (format " (%s) " (alist-get 'info-country entry))
-                          "")
-                        (let ((begin (alist-get 'begin (alist-get 'info-time 
entry)))
-                              (end (alist-get 'end (alist-get 'info-time 
entry))))
-                          (format "%s%s"
-                                  (if begin begin "")
-                                  (if end (format " - %s, " end) ""))))))
-       (t (insert (format  "%s\n" entry)))))
+
+       ((equal 'idapi-artist (alist-get 'type entry))
+        (insert (emms-idapi-browser-print-entry-artist entry)))
+
+       (t (insert (format  "unhandled entry:\n\n%s\n" entry)))))
 
 (defun emms-idapi-browser-show (response)
   "Display RESPONSE in a search buffer."
+  (emms-idapi-browser-write-debug response)
   (let ((buffer (emms-idapi-browser-get-buffer)))
     (pop-to-buffer buffer)
     (let ((inhibit-read-only t))
diff --git a/emms-idapi-musicbrainz.el b/emms-idapi-musicbrainz.el
index 4a5554979b..b07f1bc38f 100644
--- a/emms-idapi-musicbrainz.el
+++ b/emms-idapi-musicbrainz.el
@@ -39,7 +39,7 @@
 (defvar emms-idapi-musicbrainz-url-buffer nil
   "Buffer to store `url' response.")
 
-(defvar emms-idapi-musicbrainz-response-limit 30
+(defvar emms-idapi-musicbrainz-response-limit 100
   "Maximum number of responses to ask for. Maximum is 100.")
 
 (defconst emms-idapi-musicbrainz-root-url "https://musicbrainz.org/ws/2/";
@@ -49,6 +49,14 @@
   "Cross-call storage for search query.")
 (make-variable-buffer-local 'emms-idapi-query-local)
 
+(defvar emms-idapi-musicbrainz-debug-buffer-name
+  " *Emms MusicBrainz Debug Buffer*"
+  "Name of debug buffer for MusicBrainz url responses.")
+
+(defvar emms-idapi-musicbrainz-debug-buffer nil
+  "Debug buffer for MusicBrainz url responses.")
+
+
 (defconst emms-idapi-musicbrainz-search-string-map
   '((info-artist      . "artist")
     (info-albumartist . "artist")
@@ -72,23 +80,38 @@
   "Return a track from the MusicBrainz ARTIST."
   (when (not (alist-get 'id artist))
     (error "could not parse from: %s" artist))
-  `(*track* (search-backend . musicbrainz)
-            (type           . info-track-artist)
-           (name           . nil)
-           (info-arid      . ,(alist-get 'id artist))
-           (info-artist    . ,(alist-get 'name artist))
-           (info-type      . ,(alist-get 'type artist))
-           (info-country   . ,(alist-get 'country artist))
-           (info-time      . ,(alist-get 'life-span artist))))
+  `(*track* (search-backend    . musicbrainz)
+            (type              . idapi-artist)
+           (name              . nil)
+           (idapi-artist-id   . ,(list (cons 'musicbrainz (alist-get 'id 
artist))))
+           (info-artist       . ,(alist-get 'name artist))
+           (info-gender       . ,(alist-get 'gender artist))
+           (info-type         . ,(alist-get 'type artist))
+           (info-country      . ,(alist-get 'country artist))
+           (info-area-type    . ,(alist-get 'type (cddr (assoc 'area artist))))
+           (info-area-country . ,(alist-get 'name (cddr (assoc 'area artist))))
+           (info-aliases      . ,(list
+                                  (seq-map
+                                   (lambda (elt)
+                                     (mm-decode-string
+                                      (alist-get 'sort-name elt) 'utf-8))
+                                   (alist-get 'aliases artist))))
+           (info-tags         . ,(list
+                                  (seq-map
+                                   (lambda (elt)
+                                     (mm-decode-string
+                                      (alist-get 'name elt) 'utf-8))
+                                   (alist-get 'tags artist))))
+           (info-time         . ,(alist-get 'life-span artist))))
 
 (defun emms-idapi-musicbrainz-read-release (release)
   "Return a track from the MusicBrainz RELEASE."
   (when (not (alist-get 'id release))
     (error "could not parse from: %s" release))
   `(*track* (search-backend . musicbrainz)
-           (type                . info-release)
+           (type                . idapi-release)
            (name                . nil)
-           (info-release-id     . ,(alist-get 'id release))
+           (idapi-release-id    . ,(list (cons 'musicbrainz (alist-get 'id 
release))))
            (info-artist         . ,(alist-get 'name (elt (alist-get 
'artist-credit release) 0)))
            (info-album          . ,(alist-get 'title release))
            (info-status         . ,(alist-get 'status release))
@@ -102,15 +125,18 @@
   "Return a track from the MusicBrainz RECORDING."
   (when (not (alist-get 'id recording))
     (error "could not parse from: %s" recording))
-  (let ((length-ms (alist-get 'length recording)))
+  (let ((length-ms (or (alist-get 'length recording) 0)))
     `(*track* (search-backend . musicbrainz)
-             (type                  . info-recording)
+             (type                  . idapi-recording)
              (name                  . ,(alist-get 'title recording))
              (info-playing-time     . ,(floor (/ length-ms 1000)))
              (info-playing-time-min . ,(floor (/ (/ length-ms 1000) 60)))
              (info-playing-time-sec . ,(% (floor (/ length-ms 1000)) 60))
              (info-recording-id     . ,(alist-get 'id recording))
-             (info-album            . ,(alist-get 'title recording))
+             (idapi-releases        . ,(seq-map
+                                        (lambda (elt)
+                                          (emms-idapi-musicbrainz-read-release 
elt))
+                                        (alist-get 'releases recording)))
              (info-length-ms        . ,length-ms))))
 
 (defun emms-idapi-musicbrainz-process-type-dispatch (response)
@@ -120,7 +146,12 @@
                         ((alist-get 'recordings response) 
#'emms-idapi-musicbrainz-read-recording)
                         (t (error "unhandled response type %s" response))))
        ;; the actual items without header data
-       (elements (cdr (nth 3 response))))
+       (elements (cdr (nth 3 response)))
+       (debug-buffer (get-buffer-create 
emms-idapi-musicbrainz-debug-buffer-name)))
+    (setq emms-idapi-musicbrainz-debug-buffer debug-buffer)
+    (with-current-buffer debug-buffer
+      (erase-buffer)
+      (insert (format "%s" response)))
     (append (alist-get 'query response)
            (mapcar
             #'(lambda (e)
@@ -188,24 +219,32 @@
   (let ((artist  (or (alist-get 'info-artist term-alist)
                     (alist-get 'info-albumartist term-alist)))
        (release (alist-get 'info-album  term-alist))
-       (track   (alist-get 'info-title  term-alist))
+       (title   (alist-get 'info-title  term-alist))
        (reid    (alist-get 'reid        term-alist))
        (arid    (alist-get 'arid        term-alist)))
     (concat emms-idapi-musicbrainz-root-url
 
-           (cond ((and artist (not release))
+           (cond ((and title
+                       artist)
+                  (format "recording/?query=recording:%s%sartist:%s"
+                          (url-encode-url (concat "\"" title "\""))
+                          (url-encode-url " AND ")
+                          (url-encode-url (concat "\"" artist "\""))))
+
+                 ((and artist
+                       (not release)
+                       (not title))
                   (format "artist/?query=%s" (url-encode-url (concat "\"" 
artist "\""))))
-                 (release
-                  (format "release/?query=release:%s%s%s"
-                          (url-encode-url (concat "\"" release "\""))
-                          (if artist (url-encode-url (concat " AND artist:\"" 
artist "\"")) "")
-                          (if arid (concat (url-encode-url " AND ") "arid:" 
arid) "")))
-                 (track
-                  (format "recording?query=%sreid:%s"
-                          (url-encode-url (concat "\"" track "\""))
-                          reid))
-                 (t (error "unhandled field %s" term-alist)))
 
+                 ;; Will only work if the browser supplies a meaningful 
musicbrainz ARID
+                 ;;
+                 ;; (release
+                 ;;  (format "release/?query=release:%s%s%s"
+                 ;;       (url-encode-url (concat "\"" release "\""))
+                 ;;       (if artist (url-encode-url (concat " AND artist:\"" 
artist "\"")) "")
+                 ;;       (if arid (concat (url-encode-url " AND ") "arid:" 
arid) "")))
+
+                 (t (error "unhandled field %s" term-alist)))
            (format "&limit=%d&fmt=json" 
emms-idapi-musicbrainz-response-limit))))
 
 

Reply via email to