mirror of
https://github.com/beetbox/beets.git
synced 2025-12-28 11:32:30 +01:00
Merge pull request #5048 from mgoltzsche/smartplaylist-track-path-template
smartplaylist: add --uri-format option
This commit is contained in:
commit
3165d5dec0
4 changed files with 77 additions and 15 deletions
|
|
@ -45,6 +45,7 @@ class SmartPlaylistPlugin(BeetsPlugin):
|
|||
"playlist_dir": ".",
|
||||
"auto": True,
|
||||
"playlists": [],
|
||||
"uri_format": None,
|
||||
"forward_slash": False,
|
||||
"prefix": "",
|
||||
"urlencode": False,
|
||||
|
|
@ -109,6 +110,12 @@ class SmartPlaylistPlugin(BeetsPlugin):
|
|||
action="store_true",
|
||||
help="URL-encode all paths.",
|
||||
)
|
||||
spl_update.parser.add_option(
|
||||
"--uri-format",
|
||||
dest="uri_format",
|
||||
type="string",
|
||||
help="playlist item URI template, e.g. http://beets:8337/item/$id/file.",
|
||||
)
|
||||
spl_update.parser.add_option(
|
||||
"--output",
|
||||
type="string",
|
||||
|
|
@ -247,6 +254,8 @@ class SmartPlaylistPlugin(BeetsPlugin):
|
|||
|
||||
playlist_dir = self.config["playlist_dir"].as_filename()
|
||||
playlist_dir = bytestring_path(playlist_dir)
|
||||
tpl = self.config["uri_format"].get()
|
||||
prefix = bytestring_path(self.config["prefix"].as_str())
|
||||
relative_to = self.config["relative_to"].get()
|
||||
if relative_to:
|
||||
relative_to = normpath(relative_to)
|
||||
|
|
@ -275,18 +284,26 @@ class SmartPlaylistPlugin(BeetsPlugin):
|
|||
m3u_name = sanitize_path(m3u_name, lib.replacements)
|
||||
if m3u_name not in m3us:
|
||||
m3us[m3u_name] = []
|
||||
item_path = item.path
|
||||
if relative_to:
|
||||
item_path = os.path.relpath(item.path, relative_to)
|
||||
if item_path not in m3us[m3u_name]:
|
||||
m3us[m3u_name].append({"item": item, "path": item_path})
|
||||
item_uri = item.path
|
||||
if tpl:
|
||||
item_uri = tpl.replace("$id", str(item.id)).encode("utf-8")
|
||||
else:
|
||||
if relative_to:
|
||||
item_uri = os.path.relpath(item_uri, relative_to)
|
||||
if self.config["forward_slash"].get():
|
||||
item_uri = path_as_posix(item_uri)
|
||||
if self.config["urlencode"]:
|
||||
item_uri = bytestring_path(pathname2url(item_uri))
|
||||
item_uri = prefix + item_uri
|
||||
|
||||
if item_uri not in m3us[m3u_name]:
|
||||
m3us[m3u_name].append({"item": item, "uri": item_uri})
|
||||
if pretend and self.config["pretend_paths"]:
|
||||
print(displayable_path(item_path))
|
||||
print(displayable_path(item_uri))
|
||||
elif pretend:
|
||||
print(item)
|
||||
|
||||
if not pretend:
|
||||
prefix = bytestring_path(self.config["prefix"].as_str())
|
||||
# Write all of the accumulated track lists to files.
|
||||
for m3u in m3us:
|
||||
m3u_path = normpath(
|
||||
|
|
@ -303,18 +320,13 @@ class SmartPlaylistPlugin(BeetsPlugin):
|
|||
if m3u8:
|
||||
f.write(b"#EXTM3U\n")
|
||||
for entry in m3us[m3u]:
|
||||
path = entry["path"]
|
||||
item = entry["item"]
|
||||
if self.config["forward_slash"].get():
|
||||
path = path_as_posix(path)
|
||||
if self.config["urlencode"]:
|
||||
path = bytestring_path(pathname2url(path))
|
||||
comment = ""
|
||||
if m3u8:
|
||||
comment = "#EXTINF:{},{} - {}\n".format(
|
||||
int(item.length), item.artist, item.title
|
||||
)
|
||||
f.write(comment.encode("utf-8") + prefix + path + b"\n")
|
||||
f.write(comment.encode("utf-8") + entry["uri"] + b"\n")
|
||||
# Send an event when playlists were updated.
|
||||
send_event("smartplaylist_update")
|
||||
|
||||
|
|
|
|||
|
|
@ -148,8 +148,9 @@ New features:
|
|||
`synced` option to prefer synced lyrics over plain lyrics.
|
||||
* :ref:`import-cmd`: Expose import.quiet_fallback as CLI option.
|
||||
* :ref:`import-cmd`: Expose `import.incremental_skip_later` as CLI option.
|
||||
* :doc:`/plugins/smartplaylist`: Add new config option `smartplaylist.output`.
|
||||
* :doc:`/plugins/smartplaylist`: Expose config options as CLI options.
|
||||
* :doc:`/plugins/smartplaylist`: Add new option `smartplaylist.output`.
|
||||
* :doc:`/plugins/smartplaylist`: Add new option `smartplaylist.uri_format`.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
|
|
|
|||
|
|
@ -118,9 +118,13 @@ other configuration options are:
|
|||
- **urlencode**: URL-encode all paths. Default: ``no``.
|
||||
- **pretend_paths**: When running with ``--pretend``, show the actual file
|
||||
paths that will be written to the m3u file. Default: ``false``.
|
||||
- **uri_format**: Template with an ``$id`` placeholder used generate a
|
||||
playlist item URI, e.g. ``http://beets:8337/item/$id/file``.
|
||||
When this option is specified, the local path-related options ``prefix``,
|
||||
``relative_to``, ``forward_slash`` and ``urlencode`` are ignored.
|
||||
- **output**: Specify the playlist format: m3u|m3u8. Default ``m3u``.
|
||||
|
||||
For many configuration options, there is a corresponding CLI option, e.g.
|
||||
``--playlist-dir``, ``--relative-to``, ``--prefix``, ``--forward-slash``,
|
||||
``--urlencode``, ``--output``, ``--pretend-paths``.
|
||||
``--urlencode``, ``--uri-format``, ``--output``, ``--pretend-paths``.
|
||||
CLI options take precedence over those specified within the configuration file.
|
||||
|
|
|
|||
|
|
@ -241,6 +241,51 @@ class SmartPlaylistTest(_common.TestCase):
|
|||
+ b"http://beets:8337/files/tagada.mp3\n",
|
||||
)
|
||||
|
||||
def test_playlist_update_uri_format(self):
|
||||
spl = SmartPlaylistPlugin()
|
||||
|
||||
i = MagicMock()
|
||||
type(i).id = PropertyMock(return_value=3)
|
||||
type(i).path = PropertyMock(return_value=b"/tagada.mp3")
|
||||
i.evaluate_template.side_effect = lambda pl, _: pl.replace(
|
||||
b"$title", b"ta:ga:da"
|
||||
).decode()
|
||||
|
||||
lib = Mock()
|
||||
lib.replacements = CHAR_REPLACE
|
||||
lib.items.return_value = [i]
|
||||
lib.albums.return_value = []
|
||||
|
||||
q = Mock()
|
||||
a_q = Mock()
|
||||
pl = b"$title-my<playlist>.m3u", (q, None), (a_q, None)
|
||||
spl._matched_playlists = [pl]
|
||||
|
||||
dir = bytestring_path(mkdtemp())
|
||||
tpl = "http://beets:8337/item/$id/file"
|
||||
config["smartplaylist"]["uri_format"] = tpl
|
||||
config["smartplaylist"]["playlist_dir"] = py3_path(dir)
|
||||
# The following options should be ignored when uri_format is set
|
||||
config["smartplaylist"]["relative_to"] = "/data"
|
||||
config["smartplaylist"]["prefix"] = "/prefix"
|
||||
config["smartplaylist"]["urlencode"] = True
|
||||
try:
|
||||
spl.update_playlists(lib)
|
||||
except Exception:
|
||||
rmtree(syspath(dir))
|
||||
raise
|
||||
|
||||
lib.items.assert_called_once_with(q, None)
|
||||
lib.albums.assert_called_once_with(a_q, None)
|
||||
|
||||
m3u_filepath = path.join(dir, b"ta_ga_da-my_playlist_.m3u")
|
||||
self.assertExists(m3u_filepath)
|
||||
with open(syspath(m3u_filepath), "rb") as f:
|
||||
content = f.read()
|
||||
rmtree(syspath(dir))
|
||||
|
||||
self.assertEqual(content, b"http://beets:8337/item/3/file\n")
|
||||
|
||||
|
||||
class SmartPlaylistCLITest(_common.TestCase, TestHelper):
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue