From 7383da127d1ef2a3d05bed268937ea6ed0e05833 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 16 Mar 2013 10:44:47 -0700 Subject: [PATCH 01/10] changelog summary/date for 1.1b3 --- docs/changelog.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index b00876395..b75c3728e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,9 +1,16 @@ Changelog ========= -1.1b3 (in development) +1.1b3 (March 16, 2013) ---------------------- +This third beta of beets 1.1 brings a hodgepodge of little new features (and +internal overhauls that will make improvements easier in the future). There +are new options for getting metadata in a particular language and seeing more +detail during the import process. There's also a new plugin for synchronizing +your metadata with MusicBrainz. Under the hood, plugins can now extend the +query syntax. + New configuration options: * :ref:`languages` controls the preferred languages when selecting an alias From a9ca438f82a24b1e951703bc5d5f6b418721de1f Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 16 Mar 2013 10:45:23 -0700 Subject: [PATCH 02/10] Added tag v1.1.0-beta.3 for changeset 8f070ce28a7b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2cf45afe0..914d3b40b 100644 --- a/.hgtags +++ b/.hgtags @@ -17,3 +17,4 @@ c84744f4519be7416dc1653142f1763f406d6896 1.0rc1 f3cd4c138c6f40dc324a23bf01c4c7d97766477e 1.0rc2 6f29c0f4dc7025e8d8216ea960000c353886c4f4 v1.1.0-beta.1 f28ea9e2ef8d39913d79dbba73db280ff0740c50 v1.1.0-beta.2 +8f070ce28a7b33d8509b29a8dbe937109bbdbd21 v1.1.0-beta.3 From 7b2ff4ae9b9ff091cc4262d268341eb199a6c878 Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Sun, 17 Mar 2013 02:50:32 -0300 Subject: [PATCH 03/10] fix mbsync bug This fixes a bug that only applied changes to the first item of an album --- beetsplug/mbsync.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 97ecee3ae..644c29978 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -111,8 +111,8 @@ def mbsync_albums(lib, query, move, pretend, write): autotag.apply_metadata(album_info, mapping) changed = False for item in items: - changed = changed or \ - _print_and_apply_changes(lib, item, move, pretend, write) + changed = _print_and_apply_changes(lib, item, move, pretend, + write) or changed if not changed: # No change to any item. continue From 0c53c0bc3ffeaf90d3a0058e37023f569df4063f Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Sun, 17 Mar 2013 22:52:51 -0300 Subject: [PATCH 04/10] option to embed current album arts (closes #182) --- beetsplug/embedart.py | 25 +++++++++++++++++++++---- docs/plugins/embedart.rst | 6 ++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 5fca4c367..a38daa0e7 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -71,11 +71,14 @@ class EmbedCoverArtPlugin(BeetsPlugin): # Embed command. embed_cmd = ui.Subcommand('embedart', help='embed an image file into file metadata') + embed_cmd.parser.add_option('-c', '--current', help='embed the current\ + album art into metadata', action='store_true') def embed_func(lib, opts, args): - if not args: - raise ui.UserError('specify an image file') - imagepath = normpath(args.pop(0)) - embed(lib, imagepath, decargs(args)) + if opts.current: + embed_current(lib, decargs(args)) + else: + imagepath = normpath(args.pop(0)) + embed(lib, imagepath, decargs(args)) embed_cmd.func = embed_func # Extract command. @@ -112,6 +115,20 @@ def embed(lib, imagepath, query): _embed(imagepath, album.items(), config['embedart']['maxwidth'].get(int)) + +def embed_current(lib, query): + albums = lib.albums(query) + for album in albums: + if not album.artpath: + log.info(u'No album art found: {0} - {1}'. + format(album.albumartist, album.album)) + continue + + log.info('Embedding album art into {0} - {1}'. + format(album.albumartist, album.album)) + _embed(album.artpath, album.items(), + config['embedart']['maxwidth'].get(int)) + # "extractart" command. def extract(lib, outpath, query): items = lib.items(query) diff --git a/docs/plugins/embedart.rst b/docs/plugins/embedart.rst index 9ce3f7257..b4dafcf3c 100644 --- a/docs/plugins/embedart.rst +++ b/docs/plugins/embedart.rst @@ -26,7 +26,9 @@ The ``embedart`` plugin provides a couple of commands for manually managing embedded album art: * ``beet embedart IMAGE QUERY``: given an image file and a query matching an - album, embed the image into the metadata of every track on the album. + album, embed the image into the metadata of every track on the album. Using + the ``-c`` or ``--current`` option and a query matching albums, the current + album art is embeded. * ``beet extractart [-o FILE] QUERY``: extracts the image from an item matching the query and stores it in a file. You can specify the destination file using @@ -40,7 +42,7 @@ embedded album art: Configuring ----------- -The ``auto`` option lets you disable automatic album art embedding. +The ``auto`` option lets you disable automatic album art embedding. To do so, add this to your ``config.yaml``:: embedart: From f8d6e845819ff7367915a20c94e69bcf67c2d8da Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 17 Mar 2013 22:50:28 -0700 Subject: [PATCH 05/10] invert new embedart switch (#182) The default behavior now does what most people probably expect, which is to run like the on-import handler for the embedart plugin. --- beetsplug/embedart.py | 22 +++++++++++----------- docs/plugins/embedart.rst | 8 ++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index a38daa0e7..22bb5364a 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -70,15 +70,15 @@ class EmbedCoverArtPlugin(BeetsPlugin): def commands(self): # Embed command. embed_cmd = ui.Subcommand('embedart', - help='embed an image file into file metadata') - embed_cmd.parser.add_option('-c', '--current', help='embed the current\ - album art into metadata', action='store_true') + help='embed image files into file metadata') + embed_cmd.parser.add_option('-f', '--file', metavar='PATH', + help='the image file to embed') def embed_func(lib, opts, args): - if opts.current: - embed_current(lib, decargs(args)) - else: - imagepath = normpath(args.pop(0)) + if opts.file: + imagepath = normpath(opts.file) embed(lib, imagepath, decargs(args)) + else: + embed_current(lib, decargs(args)) embed_cmd.func = embed_func # Extract command. @@ -100,7 +100,7 @@ class EmbedCoverArtPlugin(BeetsPlugin): return [embed_cmd, extract_cmd, clear_cmd] -# "embedart" command. +# "embedart" command with --file argument. def embed(lib, imagepath, query): albums = lib.albums(query) for i_album in albums: @@ -115,16 +115,16 @@ def embed(lib, imagepath, query): _embed(imagepath, album.items(), config['embedart']['maxwidth'].get(int)) - +# "embedart" command without explicit file. def embed_current(lib, query): albums = lib.albums(query) for album in albums: if not album.artpath: - log.info(u'No album art found: {0} - {1}'. + log.info(u'No album art present: {0} - {1}'. format(album.albumartist, album.album)) continue - log.info('Embedding album art into {0} - {1}'. + log.info(u'Embedding album art into {0} - {1}'. format(album.albumartist, album.album)) _embed(album.artpath, album.items(), config['embedart']['maxwidth'].get(int)) diff --git a/docs/plugins/embedart.rst b/docs/plugins/embedart.rst index b4dafcf3c..1200071cf 100644 --- a/docs/plugins/embedart.rst +++ b/docs/plugins/embedart.rst @@ -25,10 +25,10 @@ Manually Embedding and Extracting Art The ``embedart`` plugin provides a couple of commands for manually managing embedded album art: -* ``beet embedart IMAGE QUERY``: given an image file and a query matching an - album, embed the image into the metadata of every track on the album. Using - the ``-c`` or ``--current`` option and a query matching albums, the current - album art is embeded. +* ``beet embedart [-f IMAGE] QUERY``: embed images into the every track on the + albums matching the query. If the ``-f`` (``--file``) option is given, then + use a specific image file from the filesystem; otherwise, each album embeds + its own currently associated album art. * ``beet extractart [-o FILE] QUERY``: extracts the image from an item matching the query and stores it in a file. You can specify the destination file using From bb1507bd1ca5b0953d89599217e1ba9c131a5727 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 17 Mar 2013 22:52:33 -0700 Subject: [PATCH 06/10] version bump/changelog for #182 --- beets/__init__.py | 2 +- docs/changelog.rst | 7 +++++++ docs/conf.py | 2 +- setup.py | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/beets/__init__.py b/beets/__init__.py index dcd1a8f34..957bac223 100644 --- a/beets/__init__.py +++ b/beets/__init__.py @@ -12,7 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -__version__ = '1.1.0-beta.3' +__version__ = '1.1.0' __author__ = 'Adrian Sampson ' import beets.library diff --git a/docs/changelog.rst b/docs/changelog.rst index b75c3728e..9e270c21a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,13 @@ Changelog ========= +1.1.0 (in development) +---------------------- + +* :doc:`/plugins/embedart`: The ``embedart`` command now embeds each album's + associated art by default. The ``--file`` option invokes the old behavior, + in which a specific image file is used. + 1.1b3 (March 16, 2013) ---------------------- diff --git a/docs/conf.py b/docs/conf.py index ccd96e730..51e9f2056 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,7 +13,7 @@ project = u'beets' copyright = u'2012, Adrian Sampson' version = '1.1' -release = '1.1b3' +release = '1.1.0' pygments_style = 'sphinx' diff --git a/setup.py b/setup.py index 295759b94..09d95968a 100755 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ if 'sdist' in sys.argv: shutil.copytree(os.path.join(docdir, '_build', 'man'), mandir) setup(name='beets', - version='1.1.0-beta.3', + version='1.1.0', description='music tagger and library organizer', author='Adrian Sampson', author_email='adrian@radbox.org', From 56c53acbab2ad42a6753763b6b0642a37aad26df Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Mon, 25 Mar 2013 11:24:42 -0300 Subject: [PATCH 07/10] human-friendly error messages (#125) --- beets/ui/commands.py | 7 ++++++- beetsplug/embedart.py | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 3f76a8328..72382c89d 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -798,7 +798,12 @@ def update_items(lib, query, album, move, pretend): # Read new data. old_data = dict(item.record) - item.read() + try: + item.read() + except Exception as exc: + log.error(u'error reading {0}: {1}'.format( + repr(item.path), exc)) + continue # Special-case album artist when it matches track artist. (Hacky # but necessary for preserving album-level metadata for non- diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 22bb5364a..82b595c0c 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -140,7 +140,14 @@ def extract(lib, outpath, query): return # Extract the art. - mf = mediafile.MediaFile(syspath(item.path)) + try: + mf = mediafile.MediaFile(syspath(item.path)) + except mediafile.UnreadableFileError as exc: + log.error('Could not extract art from {0}: {1}'.format( + repr(item.path), exc + )) + return + art = mf.art if not art: log.error('No album art present in %s - %s.' % @@ -165,7 +172,13 @@ def clear(lib, query): log.info('Clearing album art from items:') for item in lib.items(query): log.info(u'%s - %s' % (item.artist, item.title)) - mf = mediafile.MediaFile(syspath(item.path)) + try: + mf = mediafile.MediaFile(syspath(item.path)) + except mediafile.UnreadableFileError as exc: + log.error('Could not clear art from {0}: {1}'.format( + repr(item.path), exc + )) + continue mf.art = None mf.save() From c682ac84b03899ebfd3a45c835a03aab4417f6d5 Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Mon, 25 Mar 2013 11:45:11 -0300 Subject: [PATCH 08/10] one more error message (#125) --- beetsplug/mbsync.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index 644c29978..b9cb51efb 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -47,7 +47,12 @@ def _print_and_apply_changes(lib, item, move, pretend, write): lib.move(item, with_album=False) if write: - item.write() + try: + item.write() + except Exception as exc: + log.error(u'could not sync {0}: {1}'.format( + repr(item.path), exc)) + return False lib.store(item) return True From 51ed0939d6f85f605af14c3b8f0419831b3002af Mon Sep 17 00:00:00 2001 From: Lucas Duailibe Date: Mon, 25 Mar 2013 15:20:38 -0300 Subject: [PATCH 09/10] fixing things --- beets/ui/commands.py | 2 +- beetsplug/embedart.py | 12 ++++++------ beetsplug/mbsync.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 72382c89d..f13232808 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -802,7 +802,7 @@ def update_items(lib, query, album, move, pretend): item.read() except Exception as exc: log.error(u'error reading {0}: {1}'.format( - repr(item.path), exc)) + displayable_path(item.path), exc)) continue # Special-case album artist when it matches track artist. (Hacky diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 82b595c0c..2b342c989 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -20,7 +20,7 @@ from beets.plugins import BeetsPlugin from beets import mediafile from beets import ui from beets.ui import decargs -from beets.util import syspath, normpath +from beets.util import syspath, normpath, displayable_path from beets.util.artresizer import ArtResizer from beets import config @@ -46,7 +46,7 @@ def _embed(path, items, maxwidth=0): f = mediafile.MediaFile(syspath(item.path)) except mediafile.UnreadableFileError as exc: log.warn('Could not embed art in {0}: {1}'.format( - repr(item.path), exc + displayable_path(item.path), exc )) continue f.art = data @@ -143,8 +143,8 @@ def extract(lib, outpath, query): try: mf = mediafile.MediaFile(syspath(item.path)) except mediafile.UnreadableFileError as exc: - log.error('Could not extract art from {0}: {1}'.format( - repr(item.path), exc + log.error(u'Could not extract art from {0}: {1}'.format( + displayable_path(item.path), exc )) return @@ -175,8 +175,8 @@ def clear(lib, query): try: mf = mediafile.MediaFile(syspath(item.path)) except mediafile.UnreadableFileError as exc: - log.error('Could not clear art from {0}: {1}'.format( - repr(item.path), exc + log.error(u'Could not clear art from {0}: {1}'.format( + displayable_path(item.path), exc )) continue mf.art = None diff --git a/beetsplug/mbsync.py b/beetsplug/mbsync.py index b9cb51efb..fa6a3abd5 100644 --- a/beetsplug/mbsync.py +++ b/beetsplug/mbsync.py @@ -51,7 +51,7 @@ def _print_and_apply_changes(lib, item, move, pretend, write): item.write() except Exception as exc: log.error(u'could not sync {0}: {1}'.format( - repr(item.path), exc)) + util.displayable_path(item.path), exc)) return False lib.store(item) From 461f43077dab8b5607b36b0f90b77c1d1351165f Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Mon, 25 Mar 2013 12:36:41 -0700 Subject: [PATCH 10/10] changelog note for #234/#125 --- docs/changelog.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 9e270c21a..21449ae1b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,9 @@ Changelog * :doc:`/plugins/embedart`: The ``embedart`` command now embeds each album's associated art by default. The ``--file`` option invokes the old behavior, in which a specific image file is used. +* Avoid some error cases in the ``update`` command and the ``embedart`` and + ``mbsync`` plugins. Invalid or missing files now cause error logs instead of + crashing beets. Thanks to Lucas Duailibe. 1.1b3 (March 16, 2013) ----------------------