From 6b99e3f48df1b47d07abb53301396eb6d33879fa Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Wed, 14 Jul 2010 14:58:17 -0700 Subject: [PATCH] importer now takes album art config options and switch (doesn't yet actually apply art) --- beets/library.py | 2 +- beets/ui/__init__.py | 6 +++++- beets/ui/commands.py | 31 ++++++++++++++++++++++++------- test/test_db.py | 17 +++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/beets/library.py b/beets/library.py index a816ee80e..330b39f2a 100644 --- a/beets/library.py +++ b/beets/library.py @@ -895,7 +895,7 @@ class Library(BaseLibrary): c = self._library.conn.execute(sql, (self._id,)) return c.fetchone()[0] else: - object.__getattr__(self, key) + raise AttributeError('no such field %s' % key) def __setattr__(self, key, value): """Set the value of an album attribute.""" diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index e504d187f..0f53595d4 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -31,6 +31,7 @@ CONFIG_FILE = os.path.expanduser('~/.beetsconfig') DEFAULT_LIBRARY = '~/.beetsmusic.blb' DEFAULT_DIRECTORY = '~/Music' DEFAULT_PATH_FORMAT = '$artist/$album/$track $title' +DEFAULT_ART_FILENAME = 'cover' # UI exception. Commands should throw this in order to display @@ -369,9 +370,12 @@ def main(): config_val(config, 'beets', 'directory', DEFAULT_DIRECTORY) path_format = options.path_format or \ config_val(config, 'beets', 'path_format', DEFAULT_PATH_FORMAT) + art_filename = \ + config_val(config, 'beets', 'art_filename', DEFAULT_ART_FILENAME) lib = library.Library(os.path.expanduser(libpath), directory, - path_format) + path_format, + art_filename) # Invoke the subcommand. try: diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 2c434c6e0..bae227be2 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -24,6 +24,7 @@ from beets.ui import print_ from beets import autotag from beets import library from beets.mediafile import UnreadableFileError, FileTypeError +import beets.autotag.art # Global logger. log = logging.getLogger('beets') @@ -35,9 +36,10 @@ default_commands = [] # import: Autotagger and importer. -DEFAULT_IMPORT_COPY = True +DEFAULT_IMPORT_COPY = True DEFAULT_IMPORT_WRITE = True DEFAULT_IMPORT_AUTOT = True +DEFAULT_IMPORT_ART = True def show_change(cur_artist, cur_album, items, info, dist): """Print out a representation of the changes that will be made if @@ -147,12 +149,13 @@ def tag_log(logfile, status, items): path = os.path.commonprefix([item.path for item in items]) print >>logfile, status, os.path.dirname(path) -def tag_album(items, lib, copy=True, write=True, logfile=None): +def tag_album(items, lib, copy=True, write=True, logfile=None, art=True): """Import items into lib, tagging them as an album. If copy, then items are copied into the destination directory. If write, then new metadata is written back to the files' tags. If logfile is provided, then a log message will be added there if the album is - untaggable. + untaggable. If art, then attempt to download cover art for the + album. """ # Try to get candidate metadata. search_artist, search_album = None, None @@ -229,13 +232,20 @@ def tag_album(items, lib, copy=True, write=True, logfile=None): for item in items: lib.add(item) -def import_files(lib, paths, copy=True, write=True, autot=True, logpath=None): + # Get album art if requested. + if art: + #fixme + beets.autotag.art.art_for_album(info) + +def import_files(lib, paths, copy=True, write=True, autot=True, + logpath=None, art=True): """Import the files in the given list of paths, tagging each leaf directory as an album. If copy, then the files are copied into the library folder. If write, then new metadata is written to the files themselves. If not autot, then just import the files without attempting to tag. If logpath is provided, then untaggable - albums will be logged there. + albums will be logged there. If art, then attempt to download + cover art for each album. """ if logpath: logfile = open(logpath, 'w') @@ -257,7 +267,7 @@ def import_files(lib, paths, copy=True, write=True, autot=True, logpath=None): first = False # Infer tags. - tag_album(album, lib, copy, write, logfile) + tag_album(album, lib, copy, write, logfile, art) # Write the database after each album. lib.save() @@ -314,6 +324,10 @@ import_cmd.parser.add_option('-a', '--autotag', action='store_true', import_cmd.parser.add_option('-A', '--noautotag', action='store_false', dest='autotag', help="don't infer tags for imported files (opposite of -a)") +import_cmd.parser.add_option('-r', '--art', action='store_true', + default=None, help="try to download album art") +import_cmd.parser.add_option('-R', '--noart', action='store_false', + dest='art', help="don't album art (opposite of -r)") import_cmd.parser.add_option('-l', '--log', dest='logpath', help='file to log untaggable albums for later review') def import_func(lib, config, opts, args): @@ -324,7 +338,10 @@ def import_func(lib, config, opts, args): ui.config_val(config, 'beets', 'import_write', DEFAULT_IMPORT_WRITE, bool) autot = opts.autotag if opts.autotag is not None else DEFAULT_IMPORT_AUTOT - import_files(lib, args, copy, write, autot, opts.logpath) + art = opts.art if opts.art is not None else \ + ui.config_val(config, 'beets', 'import_art', + DEFAULT_IMPORT_ART, bool) + import_files(lib, args, copy, write, autot, opts.logpath, art) import_cmd.func = import_func default_commands.append(import_cmd) diff --git a/test/test_db.py b/test/test_db.py index 912696c81..5ed8b0478 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -478,6 +478,23 @@ class ArtFileTest(unittest.TestCase): ai.set_art(newart) self.assertTrue(os.path.exists(ai.artpath)) +class ArtDestinationTest(unittest.TestCase): + def setUp(self): + self.lib = beets.library.Library(':memory:') + self.i = item() + self.i.path = self.lib.destination(self.i) + self.lib.art_filename = 'artimage' + self.ai = self.lib.add_album(self.i.artist, self.i.album, (self.i,)) + + def test_art_filename_respects_setting(self): + art = self.ai.art_destination('something.jpg') + self.assert_('/artimage.jpg' in art) + + def test_art_path_in_item_dir(self): + art = self.ai.art_destination('something.jpg') + track = self.lib.destination(self.i) + self.assertEqual(os.path.dirname(art), os.path.dirname(track)) + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)