See the windows in your hand

This commit is contained in:
nik gaffney 2023-05-20 13:45:28 +02:00
parent 21ade49d85
commit 6a27268134
2 changed files with 311 additions and 100 deletions

View file

@ -1,7 +1,7 @@
# -*- mode: org; coding: utf-8; -*-
#+OPTIONS: toc:2 num:nil html-style:nil
#+author:
#+title: MusicBrainz & ListenBrainz & other
#+title: MusicBrainz & ListenBrainz & others
* MusicBrainz
@ -11,7 +11,7 @@ MusicBrainz is a community-maintained open source encyclopedia of [[https://musi
This code provides a simple, incomplete yet possibly useful interface to some of the MusicBrainz and ListenBrainz APIs from emacs for exploratory use in =org-mode= or behind the scenes sending listening metadata.
* MusicBrainz API
** MusicBrainz API
- Recording documentation: https://musicbrainz.org/doc/Recording
- Release documentation: https://musicbrainz.org/doc/Release
@ -54,11 +54,11 @@ The MBID can be used for specific lookups (and checked if needed using =musicbra
| Autechre | electronic music duo | Group | [[https://musicbrainz.org/artist/410c9baf-5469-44f6-9852-826524b80c61][410c9baf-5469-44f6-9852-826524b80c61]] |
#+BEGIN_SRC emacs-lisp
(musicbrainz-lookup-artist-releases "410c9baf-5469-44f6-9852-826524b80c61")
(musicbrainz-lookup-artist-releases "410c9baf-5469-44f6-9852-826524b80c61")
#+END_SRC
#+BEGIN_SRC emacs-lisp
(musicbrainz-lookup-artist-recordings "410c9baf-5469-44f6-9852-826524b80c61")
(musicbrainz-lookup-artist-recordings "410c9baf-5469-44f6-9852-826524b80c61")
#+END_SRC
#+BEGIN_SRC emacs-lisp
@ -92,9 +92,7 @@ The MBID can be used for specific lookups (and checked if needed using =musicbra
** MBID
“One of MusicBrainz' aims is to be the universal lingua franca for music by providing a reliable and unambiguous form of music identification; this music identification is performed through the use of MusicBrainz Identifiers (MBIDs). An MBID is a 36 character Universally Unique Identifier that is permanently assigned to each entity in the database, i.e. artists, release groups, releases, recordings, works, labels, areas, places and URLs. MBIDs are also assigned to Tracks, though tracks do not share many other properties of entities.”
https://musicbrainz.org/doc/MusicBrainz_Identifier
“One of MusicBrainz' aims is to be the universal lingua franca for music by providing a reliable and unambiguous form of music identification; this music identification is performed through the use of MusicBrainz Identifiers (MBIDs). An MBID is a 36 character Universally Unique Identifier that is permanently assigned to each entity in the database, i.e. artists, release groups, releases, recordings, works, labels, areas, places and URLs. MBIDs are also assigned to Tracks, though tracks do not share many other properties of entities.” https://musicbrainz.org/doc/MusicBrainz_Identifier
#+BEGIN_SRC emacs-lisp
(musicbrainz-artist-to-mbid "Autechre")
@ -136,7 +134,6 @@ Which returns the MBID =7feb02f2-51fa-422d-838e-2c14ecb4c7b8= for “Tomorrows B
(musicbrainz-disambiguate-artist "Bad Seeds" 7)
#+END_SRC
#+RESULTS:
| | Artist: Bad Seeds | MBID |
| 100 | Tomorrows Bad Seeds, nil | [[https://musicbrainz.org/artist/7feb02f2-51fa-422d-838e-2c14ecb4c7b8][7feb02f2-51fa-422d-838e-2c14ecb4c7b8]] |
| 98 | The Bad Seeds, 60s Texas rock band | [[https://musicbrainz.org/artist/3e593712-9f70-4b7a-b21b-466016998a3d][3e593712-9f70-4b7a-b21b-466016998a3d]] |
@ -146,6 +143,64 @@ Which returns the MBID =7feb02f2-51fa-422d-838e-2c14ecb4c7b8= for “Tomorrows B
| 50 | The Lightning Seeds, nil | [[https://musicbrainz.org/artist/1ba601a0-3401-4b28-8ddd-9af8203661e8][1ba601a0-3401-4b28-8ddd-9af8203661e8]] |
| 49 | Seeds, UK dancehall | [[https://musicbrainz.org/artist/a03cf587-a3d3-4847-ac41-e488f779a313][a03cf587-a3d3-4847-ac41-e488f779a313]] |
#+BEGIN_SRC emacs-lisp
(musicbrainz-lookup-artist "172e1f1a-504d-4488-b053-6344ba63e6d0")
#+END_SRC
** incompleteness
general, specific and partial API coverage
*** Searching & browsing
Search supports the full [[https://lucene.apache.org/core/7_7_2/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package.description][Lucene search syntax]] in queries.
| (musicbrainz-search /type/ /query/ &optional /limit/ /offset/) | see =musicbrainz-search-types= |
| (musicbrainz-browse /entity/ /link/ /query/ &optional /type/) | and =musicbrainz-entities-*= |
| (musicbrainz-search-artist /artist/ &optional /limit/) | |
| (musicbrainz-artist-to-mbid /artist/) | |
| (musicbrainz-disambiguate-artist /artist/ &optional /limit/) | |
| (musicbrainz-search-label /label/ &optional /limit/) | |
| (musicbrainz-search-recording /query/ &optional /limit/) | |
| (musicbrainz-search-release /query/ &optional /limit/) | |
*** Lookup queries & subqueries
| (musicbrainz-lookup /entity/ /MBID/ &optional /inc/) | valid entities listed in =musicbrainz-entities-core= |
| *Functions & formatted output* | example MBID |
| (musicbrainz-lookup-area /MBID/) | [[https://musicbrainz.org/area/c9ac1239-e832-41bc-9930-e252a1fd1105][c9ac1239-e832-41bc-9930-e252a1fd1105]] |
| (musicbrainz-lookup-artist /MBID/) | [[https://musicbrainz.org/artist/410c9baf-5469-44f6-9852-826524b80c61][410c9baf-5469-44f6-9852-826524b80c61]] |
| (musicbrainz-lookup-artist-recordings /MBID/) | … |
| (musicbrainz-lookup-artist-releases /MBID/) | … |
| (musicbrainz-lookup-artist-release-groups /MBID/) | … |
| (musicbrainz-lookup-artist-works /MBID/) | … |
| (musicbrainz-lookup-collection /MBID/) | … |
| (musicbrainz-lookup-collection-user-collections /MBID/) | … |
| (musicbrainz-lookup-event /MBID/) | [[https://musicbrainz.org/event/7c132556-e902-4481-b9cb-ec76a175628a][7c132556-e902-4481-b9cb-ec76a175628a]] |
| (musicbrainz-lookup-genre /MBID/) | [[https://musicbrainz.org/genre/68c81274-5770-4e7b-a4bf-ab0d7d425d99][68c81274-5770-4e7b-a4bf-ab0d7d425d99]] |
| (musicbrainz-lookup-instrument /MBID/) | [[https://musicbrainz.org/instrument/303d4f1a-f799-4c42-9bac-dbedd9139e91][303d4f1a-f799-4c42-9bac-dbedd9139e91]] |
| (musicbrainz-lookup-label /MBID/) | [[https://musicbrainz.org/label/8943d408-940c-403b-a01d-9036c227d50f][8943d408-940c-403b-a01d-9036c227d50f]] |
| (musicbrainz-lookup-label-releases /MBID/) | … |
| (musicbrainz-lookup-place /MBID/) | [[https://musicbrainz.org/place/73cba8a4-cacb-45b9-8e02-654f716e2e7a][73cba8a4-cacb-45b9-8e02-654f716e2e7a]] |
| (musicbrainz-lookup-recording /MBID/) | [[https://musicbrainz.org/recording/ef8b34c1-8548-472c-872f-03e0d8d3bb37][ef8b34c1-8548-472c-872f-03e0d8d3bb37]] |
| (musicbrainz-lookup-recording-artists /MBID/) | … |
| (musicbrainz-lookup-recording-releases /MBID/) | … |
| (musicbrainz-lookup-recording-isrcs /MBID/) | … |
| (musicbrainz-lookup-recording-url-rels /MBID/) | … |
| (musicbrainz-lookup-release /MBID/) | … |
| (musicbrainz-lookup-release-artists /MBID/) | … |
| (musicbrainz-lookup-release-collections /MBID/) | … |
| (musicbrainz-lookup-release-labels /MBID/) | … |
| (musicbrainz-lookup-release-recordings /MBID/) | … |
| (musicbrainz-lookup-release-release-groups /MBID/) | … |
| (musicbrainz-lookup-release-group /MBID/) | [[https://musicbrainz.org/release-group/fe4acfe9-6d1e-3565-8857-fb16ddc492ab][fe4acfe9-6d1e-3565-8857-fb16ddc492ab]] |
| (musicbrainz-lookup-release-group-artists /MBID/) | … |
| (musicbrainz-lookup-release-group-releases /MBID/) | … |
| (musicbrainz-lookup-series /MBID/) | … |
| (musicbrainz-lookup-work /MBID/) | … |
| (musicbrainz-lookup-url /MBID/) | … |
* ListenBrainz
@ -153,12 +208,12 @@ Which returns the MBID =7feb02f2-51fa-422d-838e-2c14ecb4c7b8= for “Tomorrows B
[[file:img/listenbrainz-logo.svg]]
* listening
** listening
- https://listenbrainz.org
- https://listenbrainz.readthedocs.io/
* examples
** examples
#+BEGIN_SRC emacs-lisp
(setq listenbrainz-api-token "000-000-000")
@ -204,9 +259,8 @@ Which returns the MBID =7feb02f2-51fa-422d-838e-2c14ecb4c7b8= for “Tomorrows B
(listenbrainz-stats-recordings "zzzkt" 13 "month")
#+END_SRC
* incompleteness
** Core API endpoints
** incompleteness
*** Core API endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#core-api-endpoints
@ -227,7 +281,7 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#core-api-endpoints
| GET /1/latest-import | - |
| POST /1/latest-import | - |
** Feedback API Endpoints
*** Feedback API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#feedback-api-endpoints
@ -236,13 +290,13 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#feedback-api-endpoint
| GET /1/feedback/user/(user_name)/get-feedback-for-recordings | |
| GET /1/feedback/user/(user_name)/get-feedback | - |
** Recording Recommendation API Endpoints
*** Recording Recommendation API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#core-api-endpoints
| GET /1/cf/recommendation/user/(user_name)/recording | - |
** Recording Recommendation Feedback API Endpoints
*** Recording Recommendation Feedback API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#recording-recommendation-feedback-api-endpoints
@ -251,7 +305,7 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#recording-recommendat
| GET /1/recommendation/feedback/user/(user_name)/recordings | - |
| GET /1/recommendation/feedback/user/(user_name) | - |
** Statistics API Endpoints
*** Statistics API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#statistics-api-endpoints
@ -263,13 +317,13 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#statistics-api-endpoi
| GET /1/stats/user/(user_name)/releases | listenbrainz-stats-releases |
| GET /1/stats/user/(user_name)/artists | listenbrainz-stats-artists |
** Status API Endpoints
*** Status API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#status-api-endpoints
| GET /1/status/get-dump-info | - |
** User Timeline API Endpoints
*** User Timeline API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#user-timeline-api-endpoints
@ -278,7 +332,7 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#user-timeline-api-end
| POST /1/user/(user_name)/feed/events/delete | - |
| GET /1/user/(user_name)/feed/events | - |
** Social API Endpoints
*** Social API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#social-api-endpoints
@ -287,7 +341,7 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#social-api-endpoints
| POST /1/user/(user_name)/unfollow | - |
| POST /1/user/(user_name)/follow | - |
** Pinned Recording API Endpoints
*** Pinned Recording API Endpoints
https://listenbrainz.readthedocs.io/en/production/dev/api/#pinned-recording-api-endpoints
@ -305,5 +359,7 @@ https://listenbrainz.readthedocs.io/en/production/dev/api/#pinned-recording-api-
- [[https://coverartarchive.org/][Cover art archive]]
* further
- https://labs.api.listenbrainz.org/
- https://troi.readthedocs.io/en/latest/
- https://listenbrainz.org/user/troi-bot/playlists/
- https://github.com/metabrainz/bono-data-sets/blob/main/top_discoveries.py

View file

@ -38,6 +38,10 @@
(require 'request)
(require 'json)
;; debug level for http requests
(setq request-log-level 'warn
request-message-level 'warn)
;;; ;; ;; ; ; ; ; ; ;
;;
@ -56,6 +60,12 @@ Documentation available at https://musicbrainz.org/doc/MusicBrainz_API"
:type 'string
:group 'musicbrainz)
(defcustom musicbrainz-user-agent "musicbrainz.el/0.1"
"A User-Agent header to identify source of API requests.
As seen in https://wiki.musicbrainz.org/MusicBrainz_API/Rate_Limiting"
:type 'string
:group 'musicbrainz)
;;; ; ; ;;; ; ;
;;
;; API entities
@ -159,7 +169,7 @@ An MBID is a 36 character Universally Unique Identifier, see https://musicbrainz
(string-match-p
(rx (repeat 8 hex) ;; [A-F0-9]{8}
"-" (repeat 4 hex) ;; -[A-F0-9]{4}
"-4" (repeat 3 hex) ;; -4[A-F0-9]{3}
"-" (repeat 4 hex) ;; -[34][A-F0-9]{3}
"-" (repeat 4 hex) ;; -[89AB][A-F0-9]{3}
"-" (repeat 12 hex)) ;; -[A-F0-9]{12}
mbid))
@ -171,6 +181,11 @@ An MBID is a 36 character Universally Unique Identifier, see https://musicbrainz
(format "%s" (pp response)))
(defun musicbrainz--unwrap-0 (entity)
"Unwrap (fragile) .artist-credit ENTITY -> .name more or less."
(format "%s" (cdar (aref entity 0))))
;;; ;; ;; ; ; ; ; ; ;
;;
;; Search API
@ -212,7 +227,7 @@ The QUERY field supports the full Lucene Search syntax, some details
can be found near https://musicbrainz.org/doc/MusicBrainz_API/Search
or in the Lucene docs."
(message "musicbrainz: searching %s=%s" type query)
(message "MusicBrainz: searching %s=%s" type query)
(let* ((max (if limit limit 1))
(from (if offset offset ""))
(response
@ -222,6 +237,7 @@ or in the Lucene docs."
(format "%s/%s?query=%s&fmt=json&limit=%s&offset=%s"
musicbrainz-api-url type query max from))
:type "GET"
:headers (list `("User-Agent" . ,musicbrainz-user-agent))
:parser 'json-read
:sync t
:success (cl-function
@ -230,38 +246,30 @@ or in the Lucene docs."
response))
;;;###autoload
(defun musicbrainz-find (query &rest extras)
"Search the MusicBrainz database for QUERY or recommend a more specific search.
MusicBrainz makes a distinction between `search' and `browse' this a more general
entry point to searching/browsing the database.
"Search MusicBrainz for QUERY (and EXTRAS) or recommend a more specific search.
MusicBrainz makes a distinction between `search', `lookup' and `browse' this
provides a more general entry point to searching/browsing the database.
Heuristics.
- not yet
- if QUERY is an MBID, check artist, recording, etc
- if QUERY is text, search for artists or recordings, etc"
(message "musicbrainz: finding: %s" query)
(message "MusicBrainz: query %s" query)
(if (musicbrainz-mbid-p query)
;; search (lookup) for things that could have an mbid
(let ((mbid query))
(message "searching mbid: %s" mbid))
;; search (query) for other things
;; search (search/browse/query) for other things
(progn
(message "searching other: %s" mbid)
;; (message "searching artist: %s" query)
;; (musicbrainz-format (musicbrainz-search "artist" query))
;; (message "searching label: %s" query)
;; (musicbrainz-format (musicbrainz-search "label" query))
;; (message "searching release: %s" query)
;; (musicbrainz-format (musicbrainz-search "release" query))
)))
;; various specific searches
;;;###autoload
(defun musicbrainz-search-artist (artist &optional limit)
"Search for an ARTIST and show matches.
Optionally return LIMIT number of results."
@ -278,7 +286,6 @@ Optionally return LIMIT number of results."
.artists))))
;;;###autoload
(defun musicbrainz-artist-to-mbid (artist)
"Find an MBID for ARTIST (with 100% match).
See `musicbrainz-disambiguate-artist' if there are multiple matches."
@ -292,7 +299,6 @@ See `musicbrainz-disambiguate-artist' if there are multiple matches."
.artists))))))
;;;###autoload
(defun musicbrainz-disambiguate-artist (artist &optional limit)
"More ARTIST data. less ambiguity (with optional LIMIT).
Outputs an `org-mode' table with descriptions and MBID link to artists pages."
@ -308,7 +314,6 @@ Outputs an `org-mode' table with descriptions and MBID link to artists pages."
.artists)))))
;;;###autoload
(defun musicbrainz-search-label (label &optional limit)
"Search for a LABEL and show matches.
Optionally return LIMIT number of results."
@ -332,7 +337,6 @@ Optionally return LIMIT number of results."
.labels))))
;;;###autoload
(defun musicbrainz-search-recording (query &optional limit)
"Search for a recording using QUERY and show matches.
Optionally return LIMIT number of results."
@ -347,11 +351,6 @@ Optionally return LIMIT number of results."
.recordings))))
(defun musicbrainz--unwrap-0 (entity)
"Unwrap (fragile) .artist-credit ENTITY -> .name more or less."
(format "%s" (cdar (aref entity 0))))
;;;###autoload
(defun musicbrainz-search-release (query &optional limit)
"Search for a release using QUERY and show matches.
Optionally return LIMIT number of results."
@ -375,26 +374,26 @@ Optionally return LIMIT number of results."
;;;###autoload
(defun musicbrainz-lookup (entity mbid &optional inc)
"Search (lookup not browse) the MusicBrainz database for ENTITY with MBID.
"Search (lookup not browse) MusicBrainz for ENTITY with MBID.
Optionally add an INC list.
Subqueries
/ws/2/area
/ws/2/artist recordings, releases, release-groups, works
/ws/2/collection user-collections (includes private collections, requires authentication)
/ws/2/artist recordings, releases, release-groups, works
/ws/2/collection user-collections (requires authentication)
/ws/2/event
/ws/2/genre
/ws/2/instrument
/ws/2/label releases
/ws/2/label releases
/ws/2/place
/ws/2/recording artists, releases, isrcs, url-rels
/ws/2/release artists, collections, labels, recordings, release-groups
/ws/2/release-group artists, releases
/ws/2/recording artists, releases, isrcs, url-rels
/ws/2/release artists, collections, labels, recordings, release-groups
/ws/2/release-group artists, releases
/ws/2/series
/ws/2/work
/ws/2/url"
(message "musicbrainz: lookup: %s/%s" entity mbid)
(message "MusicBrainz: lookup: %s/%s" entity mbid)
(if (and (musicbrainz-core-entity-p entity)
(musicbrainz-mbid-p mbid))
(let* ((add (if inc inc ""))
@ -415,58 +414,213 @@ Subqueries
musicbrainz-entities-core)))
;; specific MBID subrequests (limited to 25 results?)
;; specific MBID lookup requests & subrequests (limited to 25 results?)
(defun musicbrainz-lookup-artist (mbid)
"MusicBrainz lookup for artist with MBID."
(let ((response
(musicbrainz-lookup "artist" mbid)))
(let-alist response
(format "| %s | %s | %s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
.name .disambiguation .type .id .id))))
(defmacro musicbrainz--deflookup-1 (name format-string format-args)
"Generate lookup function to format a single item.
NAME FORMAT-STRING FORMAT-ARGS
See listenbrainz--deformatter for details."
(let ((f (intern (concat "musicbrainz-lookup-" name)))
(doc "MusicBrainz lookup."))
`(defun ,f (mbid) ,doc
(let ((response
(musicbrainz-lookup ,name mbid)))
(let-alist response
(format ,format-string ,@format-args))))))
(defun musicbrainz-lookup-release (mbid)
"MusicBrainz lookup for release with MBID."
(let ((response
(musicbrainz-lookup "release" mbid)))
(let-alist response
(format "| %s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
.date .title .packaging .id .id))))
(defun musicbrainz-lookup-recording (mbid)
"MusicBrainz lookup for recording with MBID."
(let ((response
(musicbrainz-lookup "recording" mbid)))
(let-alist response
(format "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
.title .id .id))))
(defmacro musicbrainz--deflookup-2 (query subquery format-string format-args alist)
"Generate lookup function to format multiple items.
QUERY SUBQUERY FORMAT-STRING FORMAT-ARGS ALIST
See listenbrainz--deformatter for details."
(let ((f (intern (format "musicbrainz-lookup-%s-%s" query subquery)))
(doc "MusicBrainz lookup."))
`(defun ,f (mbid) ,doc
(let ((response
(musicbrainz-lookup ,query mbid ,subquery)))
(let-alist response
(seq-map
(lambda (i)
(let-alist i
(format ,format-string ,@format-args)))
,alist))))))
(defun musicbrainz-lookup-artist-releases (mbid)
"MusicBrainz lookup for releases from artist with MBID."
(let ((response
(musicbrainz-lookup "artist" mbid "releases")))
(let-alist response
(seq-map
(lambda (i)
(let-alist i
(format "%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
.date .title .packaging .id .id)))
.releases))))
;; (defun musicbrainz-lookup-artist (mbid)
;; "MusicBrainz lookup for artist with MBID."
;; (let ((response
;; (musicbrainz-lookup "artist" mbid)))
;; (let-alist response
;; (format "| %s | %s | %s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
;; .name .disambiguation .type .id .id))))
(defun musicbrainz-lookup-artist-recordings (mbid)
"MusicBrainz lookup for recordings from artist with MBID."
(let ((response
(musicbrainz-lookup "artist" mbid "recordings")))
(let-alist response
(seq-map
(lambda (i)
(let-alist i
(format "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
.title .id .id)))
.recordings))))
;; (defun musicbrainz-lookup-artist-recordings (mbid)
;; "MusicBrainz lookup for recordings from artist with MBID."
;; (let ((response
;; (musicbrainz-lookup "artist" mbid "recordings")))
;; (let-alist response
;; (seq-map
;; (lambda (i)
;; (let-alist i
;; (format "%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
;; .title .id .id)))
;; .recordings))))
;; lookup -> musicbrainz-lookup-area
(musicbrainz--deflookup-1 "area"
"| %s | [[https://musicbrainz.org/area/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-artist
(musicbrainz--deflookup-1 "artist"
"| %s | %s | %s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
(.name .disambiguation .type .id .id))
;; lookup -> musicbrainz-lookup-artist-recordings
(musicbrainz--deflookup-2 "artist" "recordings"
"%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
(.title .id .id)
.recordings)
;; lookup -> musicbrainz-lookup-artist-releases
(musicbrainz--deflookup-2 "artist" "releases"
"%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
(.date .title .packaging .id .id)
.releases)
;; lookup -> musicbrainz-lookup-artist-release-groups
(musicbrainz--deflookup-2 "artist" "release-groups"
"%s | %s | %s | [[https://musicbrainz.org/release-group/%s][%s]] |\n"
(.first-release-date .title .primary-type .id .id)
.release-groups)
;; lookup -> musicbrainz-lookup-artist-works
(musicbrainz--deflookup-2 "artist" "works"
" %s | [[https://musicbrainz.org/work/%s][%s]] |\n"
(.title .id .id)
.works)
;; lookup -> musicbrainz-lookup-collection
(musicbrainz--deflookup-1 "collection"
"| %s | [[https://musicbrainz.org/collection/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-collection-user-collections (requires authentication)
(musicbrainz--deflookup-2 "collection" "user-collections"
" %s | [[https://musicbrainz.org/collection/%s][%s]] |\n"
(.name .id .id)
.collection)
;; lookup -> musicbrainz-lookup-event
(musicbrainz--deflookup-1 "event"
"| %s | [[https://musicbrainz.org/event/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-genre
(musicbrainz--deflookup-1 "genre"
"| %s | [[https://musicbrainz.org/genre/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-instrument
(musicbrainz--deflookup-1 "instrument"
"| %s | %s | [[https://musicbrainz.org/instrument/%s][%s]] |\n"
(.name .type .id .id))
;; lookup -> musicbrainz-lookup-label
(musicbrainz--deflookup-1 "label"
"| %s | %s | [[https://musicbrainz.org/label/%s][%s]] |\n"
(.name .disambiguation .id .id))
;; lookup -> musicbrainz-lookup-label-releases
(musicbrainz--deflookup-2 "label" "releases"
"%s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
(.date .title .id .id)
.releases)
;; lookup -> musicbrainz-lookup-place
(musicbrainz--deflookup-1 "place"
"| %s | [[https://musicbrainz.org/place/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-recording
(musicbrainz--deflookup-1 "recording"
"| %s | %s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
(.first-release-date .title .id .id))
;; lookup -> musicbrainz-lookup-recording-artists
(musicbrainz--deflookup-2 "recording" "artists"
"%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
(.artist.name .artist.id .artist.id)
.artist-credit)
;; lookup -> musicbrainz-lookup-recording-releases
(musicbrainz--deflookup-2 "recording" "releases"
"%s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
(.date .title .packaging .id .id)
.releases)
;; lookup -> musicbrainz-lookup-recording-isrcs
(musicbrainz--deflookup-2 "recording" "isrcs"
"%s | [[https://musicbrainz.org/isrc/%s][%s]] |\n"
(.name .id .id)
.isrcs)
;; lookup -> musicbrainz-lookup-recording-url-rels
(musicbrainz--deflookup-2 "recording" "url-rels"
"%s | [[https://musicbrainz.org/recording/%s][%s]] |\n"
(.name .id .id)
.relations)
;; lookup -> musicbrainz-lookup-release
(musicbrainz--deflookup-1 "release"
"| %s | %s | %s | [[https://musicbrainz.org/release/%s][%s]] |\n"
(.date .title .packaging .id .id))
;; lookup -> musicbrainz-lookup-release-artists
(musicbrainz--deflookup-2 "release" "artists"
"%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
(.artist.name .artist.id .artist.id)
.artist-credit)
;; lookup -> musicbrainz-lookup-release-collections
;; lookup -> musicbrainz-lookup-release-labels
;; lookup -> musicbrainz-lookup-release-recordings
;; lookup -> musicbrainz-lookup-release-release-groups
;; lookup -> musicbrainz-lookup-release-group
(musicbrainz--deflookup-1 "release-group"
"| %s | %s | %s | [[https://musicbrainz.org/release-group/%s][%s]] |\n"
(.first-release-date .title .primary-type .id .id))
;; lookup -> musicbrainz-lookup-release-group-artists
(musicbrainz--deflookup-2 "release-group" "artists"
"%s | [[https://musicbrainz.org/artist/%s][%s]] |\n"
(.artist.name .artist.id .artist.id)
.artist-credit)
;; lookup -> musicbrainz-lookup-release-group-releases
;; lookup -> musicbrainz-lookup-series
(musicbrainz--deflookup-1 "series"
"| %s | [[https://musicbrainz.org/series/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-work
(musicbrainz--deflookup-1 "work"
"| %s | [[https://musicbrainz.org/work/%s][%s]] |\n"
(.name .id .id))
;; lookup -> musicbrainz-lookup-url
(musicbrainz--deflookup-1 "url"
"| %s | [[https://musicbrainz.org/url/%s][%s]] |\n"
(.name .id .id))
@ -501,7 +655,7 @@ Subqueries
(defun musicbrainz-browse (entity link query &optional type)
"Search the MusicBrainz database for ENTITY with LINK matching QUERY.
Optionally limit the search to TYPE results for ENTITY."
(message "musicbrainz: browsing %s linked to %s" entity link)
(message "MusicBrainz: browsing %s linked to %s" entity link)
(message "url: %s/%s?%s=%s&type=%s&fmt=json" musicbrainz-api-url entity link query type)
(let ((response
(request-response-data
@ -509,6 +663,7 @@ Optionally limit the search to TYPE results for ENTITY."
(url-encode-url
(format "%s/%s?%s=%s&type=%s&fmt=json" musicbrainz-api-url entity link query type))
:type "GET"
:header (list `("User-Agent" . ,musicbrainz-user-agent))
:parser 'json-read
:sync t
:success (cl-function