diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index c892a6040d..56d9523b5f 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -45,6 +45,7 @@ def __init__(self): "playlist_dir": ".", "auto": True, "playlists": [], + "uri_template": None, "forward_slash": False, "prefix": "", "urlencode": False, @@ -72,6 +73,13 @@ def commands(self): action="store_true", help="display query results but don't write playlist files.", ) + spl_update.parser.add_option( + "--uri-template", + dest="uri_template", + metavar="TPL", + type="string", + help="playlist item URI template, e.g. http://beets/item/$id/file.", + ) spl_update.parser.add_option( "--extm3u", action="store_true", @@ -208,6 +216,7 @@ def update_playlists(self, lib, extm3u=None, pretend=False): "Updating {0} smart playlists...", len(self._matched_playlists) ) + tpl = self.config["uri_template"].get() playlist_dir = self.config["playlist_dir"].as_filename() playlist_dir = bytestring_path(playlist_dir) relative_to = self.config["relative_to"].get() @@ -238,13 +247,22 @@ def update_playlists(self, lib, extm3u=None, pretend=False): 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) @@ -261,18 +279,13 @@ def update_playlists(self, lib, extm3u=None, pretend=False): if extm3u: 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 extm3u: 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") diff --git a/docs/changelog.rst b/docs/changelog.rst index 9259b5933c..7b5e88c3ae 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -148,7 +148,8 @@ 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.extm3u`. +* :doc:`/plugins/smartplaylist`: Add new option `smartplaylist.extm3u`. +* :doc:`/plugins/smartplaylist`: Add new option `smartplaylist.uri_template`. Bug fixes: diff --git a/docs/plugins/smartplaylist.rst b/docs/plugins/smartplaylist.rst index 6a78124e1b..13cc1eb34a 100644 --- a/docs/plugins/smartplaylist.rst +++ b/docs/plugins/smartplaylist.rst @@ -119,3 +119,7 @@ other configuration options are: - **pretend_paths**: When running with ``--pretend``, show the actual file paths that will be written to the m3u file. Default: ``false``. - **extm3u**: Generate extm3u/m3u8 playlists. Default ``ǹo``. +- **uri_template**: Template with an ``$id`` placeholder used generate a + playlist item URI, e.g. ``http://beets/item/$id/file``. + When this option is specified, the local path-related options ``prefix``, + ``relative_to``, ``forward_slash`` and ``urlencode`` are ignored.