Skip to content

Commit 1c5aaf5

Browse files
authored
smartplaylist: change encoding of additional field (#5563)
## Description URL-encode additional item `fields` within generated EXTM3U playlists instead of JSON-encoding them. This is because JSON-encoding additional fields/attributes made it difficult to parse the `EXTINF` line but using URL-encoding for these values makes parsing easy (because URL-encoded values cannot contain commas, quotation marks and spaces; see [here](https://github.com/mgoltzsche/beets-webm3u/blob/v0.6.4/beetsplug/webm3u/playlist.py#L102) and [here](https://github.com/mgoltzsche/beets-webm3u/blob/v0.6.4/beetsplug/webm3u/playlist.py#L122)). [I introduced the generation of additional EXTM3U item fields earlier this year](#5121) and I want to correct that now.
2 parents 044818a + f01707b commit 1c5aaf5

File tree

4 files changed

+11
-10
lines changed

4 files changed

+11
-10
lines changed

beetsplug/smartplaylist.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
"""Generates smart playlists based on beets queries."""
1616

17-
import json
1817
import os
18+
from urllib.parse import quote
1919
from urllib.request import pathname2url
2020

2121
from beets import ui
@@ -327,7 +327,8 @@ def update_playlists(self, lib, pretend=False):
327327
if extm3u:
328328
attr = [(k, entry.item[k]) for k in keys]
329329
al = [
330-
f" {a[0]}={json.dumps(str(a[1]))}" for a in attr
330+
f" {key}=\"{quote(str(value), safe='/:')}\""
331+
for key, value in attr
331332
]
332333
attrs = "".join(al)
333334
comment = "#EXTINF:{}{},{} - {}\n".format(

docs/changelog.rst

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Other changes:
8686
wrong (outdated) commit. Now the tag is created in the same workflow step
8787
right after committing the version update.
8888
:bug:`5539`
89+
* :doc:`/plugins/smartplaylist`: URL-encode additional item `fields` within generated
90+
EXTM3U playlists instead of JSON-encoding them.
8991

9092
2.2.0 (December 02, 2024)
9193
-------------------------

docs/plugins/smartplaylist.rst

+5-7
Original file line numberDiff line numberDiff line change
@@ -97,27 +97,25 @@ In case you want to export additional fields from the beets database into the
9797
generated playlists, you can do so by specifying them within the ``fields``
9898
configuration option and setting the ``output`` option to ``extm3u``.
9999
For instance the following configuration exports the ``id`` and ``genre``
100-
fields:
100+
fields::
101101

102102
smartplaylist:
103103
playlist_dir: /data/playlists
104104
relative_to: /data/playlists
105105
output: extm3u
106106
fields:
107-
108107
- id
109108
- genre
110-
111109
playlists:
112-
113110
- name: all.m3u
114111
query: ''
115112

116-
A resulting ``all.m3u`` file could look as follows:
113+
Values of additional fields are URL-encoded.
114+
A resulting ``all.m3u`` file could look as follows::
117115

118116
#EXTM3U
119-
#EXTINF:805 id="1931" genre="Jazz",Miles Davis - Autumn Leaves
120-
../music/Albums/Miles Davis/Autumn Leaves/02 Autumn Leaves.mp3
117+
#EXTINF:805 id="1931" genre="Progressive%20Rock",Led Zeppelin - Stairway to Heaven
118+
../music/singles/Led Zeppelin/Stairway to Heaven.mp3
121119

122120
To give a usage example, the `webm3u`_ and `Beetstream`_ plugins read the
123121
exported ``id`` field, allowing you to serve your local m3u playlists via HTTP.

test/plugins/test_smartplaylist.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def test_playlist_update_output_extm3u_fields(self):
283283
assert (
284284
content
285285
== b"#EXTM3U\n"
286-
+ b'#EXTINF:300 id="456" genre="Fake Genre",Fake Artist - fake Title\n'
286+
+ b'#EXTINF:300 id="456" genre="Fake%20Genre",Fake Artist - fake Title\n'
287287
+ b"/tagada.mp3\n"
288288
)
289289

0 commit comments

Comments
 (0)