Merge pull request #2422 from Stunner/master

Embedart plugin asks for confirmation before making changes to item’s…
This commit is contained in:
Adrian Sampson 2017-03-12 11:34:36 -04:00 committed by GitHub
commit 5ed2798a76
4 changed files with 76 additions and 13 deletions

View file

@ -20,13 +20,35 @@ import os.path
from beets.plugins import BeetsPlugin
from beets import ui
from beets.ui import decargs
from beets.ui import print_, decargs
from beets.util import syspath, normpath, displayable_path, bytestring_path
from beets.util.artresizer import ArtResizer
from beets import config
from beets import art
def _confirm(objs, album):
"""Show the list of affected objects (items or albums) and confirm
that the user wants to modify their artwork.
`album` is a Boolean indicating whether these are albums (as opposed
to items).
"""
noun = u'album' if album else u'file'
prompt = u'Modify artwork for {} {}{} (Y/n)?'.format(
len(objs),
noun,
u's' if len(objs) > 1 else u''
)
# Show all the items or albums.
for obj in objs:
print_(format(obj))
# Confirm with user.
return ui.input_yn(prompt)
class EmbedCoverArtPlugin(BeetsPlugin):
"""Allows albumart to be embedded into the actual files.
"""
@ -60,6 +82,9 @@ class EmbedCoverArtPlugin(BeetsPlugin):
embed_cmd.parser.add_option(
u'-f', u'--file', metavar='PATH', help=u'the image file to embed'
)
embed_cmd.parser.add_option(
u"-y", u"--yes", action="store_true", help=u"skip confirmation"
)
maxwidth = self.config['maxwidth'].get(int)
compare_threshold = self.config['compare_threshold'].get(int)
ifempty = self.config['ifempty'].get(bool)
@ -71,11 +96,24 @@ class EmbedCoverArtPlugin(BeetsPlugin):
raise ui.UserError(u'image file {0} not found'.format(
displayable_path(imagepath)
))
for item in lib.items(decargs(args)):
items = lib.items(decargs(args))
# Confirm with user.
if not opts.yes and not _confirm(items, not opts.file):
return
for item in items:
art.embed_item(self._log, item, imagepath, maxwidth, None,
compare_threshold, ifempty)
else:
for album in lib.albums(decargs(args)):
albums = lib.albums(decargs(args))
# Confirm with user.
if not opts.yes and not _confirm(albums, not opts.file):
return
for album in albums:
art.embed_album(self._log, album, maxwidth, False,
compare_threshold, ifempty)
self.remove_artfile(album)

View file

@ -31,6 +31,9 @@ New features:
* A new :ref:`hardlink` config option instructs the importer to create hard
links on filesystems that support them. Thanks to :user:`jacobwgillespie`.
:bug:`2445`
* :doc:`/plugins/embedart`: The explicit ``embedart`` command now asks for
confirmation before embedding art into music files. Thanks to
:user:`Stunner`. :bug:`1999`
* You can now run beets by typing `python -m beets`. :bug:`2453`
* A new :doc:`/plugins/kodiupdate` lets you keep your Kodi library in sync
with beets. Thanks to :user:`Pauligrinder`. :bug:`2411`

View file

@ -81,7 +81,8 @@ embedded album art:
* ``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.
its own currently associated album art. The command prompts for confirmation
before making the change unless you specify the ``-y`` (``--yes``) option.
* ``beet extractart [-a] [-n FILE] QUERY``: extracts the images for all albums
matching the query. The images are placed inside the album folder. You can

View file

@ -51,6 +51,8 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
abbey_differentpath = os.path.join(_common.RSRC, b'abbey-different.jpg')
def setUp(self):
super(EmbedartCliTest, self).setUp()
self.io.install()
self.setup_beets() # Converter is threaded
self.load_plugins('embedart')
@ -64,11 +66,30 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
self.unload_plugins()
self.teardown_beets()
def test_embed_art_from_file_with_yes_input(self):
self._setup_data()
album = self.add_album_fixture()
item = album.items()[0]
self.io.addinput('y')
self.run_command('embedart', '-f', self.small_artpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
def test_embed_art_from_file_with_no_input(self):
self._setup_data()
album = self.add_album_fixture()
item = album.items()[0]
self.io.addinput('n')
self.run_command('embedart', '-f', self.small_artpath)
mediafile = MediaFile(syspath(item.path))
# make sure that images array is empty (nothing embedded)
self.assertEqual(len(mediafile.images), 0)
def test_embed_art_from_file(self):
self._setup_data()
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.small_artpath)
self.run_command('embedart', '-y', '-f', self.small_artpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
@ -78,7 +99,7 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
item = album.items()[0]
album.artpath = self.small_artpath
album.store()
self.run_command('embedart')
self.run_command('embedart', '-y')
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
@ -96,7 +117,7 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
album.store()
config['embedart']['remove_art_file'] = True
self.run_command('embedart')
self.run_command('embedart', '-y')
if os.path.isfile(tmp_path):
os.remove(tmp_path)
@ -106,7 +127,7 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
self.add_album_fixture()
logging.getLogger('beets.embedart').setLevel(logging.DEBUG)
with self.assertRaises(ui.UserError):
self.run_command('embedart', '-f', '/doesnotexist')
self.run_command('embedart', '-y', '-f', '/doesnotexist')
def test_embed_non_image_file(self):
album = self.add_album_fixture()
@ -117,7 +138,7 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
os.close(handle)
try:
self.run_command('embedart', '-f', tmp_path)
self.run_command('embedart', '-y', '-f', tmp_path)
finally:
os.remove(tmp_path)
@ -129,9 +150,9 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
self._setup_data(self.abbey_artpath)
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.abbey_artpath)
self.run_command('embedart', '-y', '-f', self.abbey_artpath)
config['embedart']['compare_threshold'] = 20
self.run_command('embedart', '-f', self.abbey_differentpath)
self.run_command('embedart', '-y', '-f', self.abbey_differentpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data,
@ -143,9 +164,9 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
self._setup_data(self.abbey_similarpath)
album = self.add_album_fixture()
item = album.items()[0]
self.run_command('embedart', '-f', self.abbey_artpath)
self.run_command('embedart', '-y', '-f', self.abbey_artpath)
config['embedart']['compare_threshold'] = 20
self.run_command('embedart', '-f', self.abbey_similarpath)
self.run_command('embedart', '-y', '-f', self.abbey_similarpath)
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data,