1 #+date: <2025-01-25 Sat 23:50>
2 #+title: Using Lisp to submit listens.
3 #+filetags: :elisp:music:open_web:emacs:
7 ~cum mortuis in lingua mortua~
9 Tracking music listening habits doesn't need to be hard. My local radio station [[https://rtrfm.com.au/][RTRFM]] publishes playlists for most of its shows (subject to the presenter's interest in doing so of course - most of them are volunteers after all). It's trivial to copy-paste these into [[https://www.gnu.org/software/emacs/][an Emacs Lisp interpreter]], making everything possible.
11 A quick fork of [[http://git.vanrenterghem.biz/musicbrainz.git][listenbrainz.el]] and a few updates to its code later, we've got a tool to submit a playlist of a show we've listened to. In a Lisp dialect even, rumours of the language's demise notwithstanding.
14 First we adjust the time the tracks were originally aired to the time we're listening to the show - re-streaming is possible for some weeks after the original air date.
16 #+BEGIN_SRC emacs-lisp
17 (setq starttime (date-to-time "Sat 25 Jan 2025 15:10"))
20 We're grabbing the playlist from an org mode headline and put each line in a list (of course).
22 #+BEGIN_SRC emacs-lisp
23 (setq playlist (let ((playlist
25 (goto-char (search-forward "Playlist data" nil t))
26 (let ((el (org-element-at-point-no-context)))
28 (buffer-substring-no-properties
29 (org-element-property :contents-begin el)
30 (org-element-property :contents-end el))
35 And next we can parse and submit our listens. The data is provided in groups of 3 lines, with the first line the relative time in HH:MM after the show started, the second the track title and the third line the performer. I've included a basic rate limit of 30 calls per minute to not overload the ListenBrainz servers.
37 #+BEGIN_SRC emacs-lisp
39 (let* ((songrelstart (split-string (pop playlist) ":"))
40 (starthour (string-to-number (pop songrelstart)))
41 (startminute (string-to-number (pop songrelstart)))
42 (songrelstartf (format-time-string "%F %R" (time-add starttime (* (+ (* starthour 60) startminute) 60))))
43 (title (pop playlist))
44 (performer (pop playlist)))
46 (listenbrainz-submit-historic-listen performer title (listenbrainz-timestamp (date-to-time songrelstartf)))