mirror of
https://github.com/beetbox/beets.git
synced 2025-12-24 17:43:52 +01:00
Merge pull request #2422 from Stunner/master
Embedart plugin asks for confirmation before making changes to item’s…
This commit is contained in:
commit
5ed2798a76
4 changed files with 76 additions and 13 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue