diff --git a/beetsplug/smartplaylist.py b/beetsplug/smartplaylist.py index 4c921eccc..5693353c0 100644 --- a/beetsplug/smartplaylist.py +++ b/beetsplug/smartplaylist.py @@ -19,7 +19,7 @@ from beets.plugins import BeetsPlugin from beets import ui from beets.util import (mkdirall, normpath, sanitize_path, syspath, - bytestring_path, path_as_posix) + bytestring_path, path_as_posix, displayable_path) from beets.library import Item, Album, parse_query_string from beets.dbcore import OrQuery from beets.dbcore.query import MultipleSort, ParsingError @@ -44,6 +44,7 @@ class SmartPlaylistPlugin(BeetsPlugin): 'forward_slash': False, 'prefix': '', 'urlencode': False, + 'pretend_paths': False, }) self.config['prefix'].redact = True # May contain username/password. @@ -59,6 +60,10 @@ class SmartPlaylistPlugin(BeetsPlugin): help='update the smart playlists. Playlist names may be ' 'passed as arguments.' ) + spl_update.parser.add_option( + '-p', '--pretend', action='store_true', + help="display query results but don't write playlist files." + ) spl_update.func = self.update_cmd return [spl_update] @@ -84,7 +89,7 @@ class SmartPlaylistPlugin(BeetsPlugin): else: self._matched_playlists = self._unmatched_playlists - self.update_playlists(lib) + self.update_playlists(lib, opts.pretend) def build_queries(self): """ @@ -170,9 +175,13 @@ class SmartPlaylistPlugin(BeetsPlugin): self._unmatched_playlists -= self._matched_playlists - def update_playlists(self, lib): - self._log.info("Updating {0} smart playlists...", - len(self._matched_playlists)) + def update_playlists(self, lib, pretend=False): + if pretend: + self._log.info("Showing query results for {0} smart playlists...", + len(self._matched_playlists)) + else: + self._log.info("Updating {0} smart playlists...", + len(self._matched_playlists)) playlist_dir = self.config['playlist_dir'].as_filename() playlist_dir = bytestring_path(playlist_dir) @@ -185,7 +194,10 @@ class SmartPlaylistPlugin(BeetsPlugin): for playlist in self._matched_playlists: name, (query, q_sort), (album_query, a_q_sort) = playlist - self._log.debug("Creating playlist {0}", name) + if pretend: + self._log.info('Results for playlist {}:', name) + else: + self._log.debug("Creating playlist {0}", name) items = [] if query: @@ -206,19 +218,29 @@ class SmartPlaylistPlugin(BeetsPlugin): item_path = os.path.relpath(item.path, relative_to) if item_path not in m3us[m3u_name]: m3us[m3u_name].append(item_path) + if pretend and self.config['pretend_paths']: + print(displayable_path(item_path)) + elif pretend: + print(item) - prefix = bytestring_path(self.config['prefix'].as_str()) - # Write all of the accumulated track lists to files. - for m3u in m3us: - m3u_path = normpath(os.path.join(playlist_dir, - bytestring_path(m3u))) - mkdirall(m3u_path) - with open(syspath(m3u_path), 'wb') as f: - for path in m3us[m3u]: - if self.config['forward_slash'].get(): - path = path_as_posix(path) - if self.config['urlencode']: - path = bytestring_path(pathname2url(path)) - f.write(prefix + path + b'\n') + 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(os.path.join(playlist_dir, + bytestring_path(m3u))) + mkdirall(m3u_path) + with open(syspath(m3u_path), 'wb') as f: + for path in m3us[m3u]: + if self.config['forward_slash'].get(): + path = path_as_posix(path) + if self.config['urlencode']: + path = bytestring_path(pathname2url(path)) + f.write(prefix + path + b'\n') - self._log.info("{0} playlists updated", len(self._matched_playlists)) + if pretend: + self._log.info("Displayed results for {0} playlists", + len(self._matched_playlists)) + else: + self._log.info("{0} playlists updated", + len(self._matched_playlists)) diff --git a/docs/changelog.rst b/docs/changelog.rst old mode 100755 new mode 100644 index 27d49cb0f..f572fb26c --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -50,6 +50,10 @@ New features: :bug:`4438` * Add a new ``import.ignored_alias_types`` config option to allow for specific alias types to be skipped over when importing items/albums. +* :doc:`/plugins/smartplaylist`: A new ``--pretend`` option lets the user see + what a new or changed smart playlist saved in the config is actually + returning. + :bug:`4573` * :doc:`/plugins/fromfilename`: Add debug log messages that inform when the plugin replaced bad (missing) artist, title or tracknumber metadata. :bug:`4561` :bug:`4600` diff --git a/docs/plugins/smartplaylist.rst b/docs/plugins/smartplaylist.rst index 553ee48af..e687a68a4 100644 --- a/docs/plugins/smartplaylist.rst +++ b/docs/plugins/smartplaylist.rst @@ -82,6 +82,17 @@ automatically notify MPD of the playlist change, by adding ``mpdupdate`` to the ``plugins`` line in your config file *after* the ``smartplaylist`` plugin. +While changing existing playlists in the beets configuration it can help to use +the ``--pretend`` option to find out if the edits work as expected. The results +of the queries will be printed out instead of being written to the playlist +file. + + $ beet splupdate --pretend BeatlesUniverse.m3u + +The ``pretend_paths`` configuration option sets whether the items should be +displayed as per the user's ``format_item`` setting or what the file +paths as they would be written to the m3u file look like. + Configuration ------------- @@ -105,3 +116,5 @@ other configuration options are: example, you could use the URL for a server where the music is stored. Default: empty string. - **urlencoded**: 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``.