Tags are not read while walking the import tree.

This makes skipping directories on incremental imports much faster and
fixes #158.
This commit is contained in:
Thomas Scholtes 2014-08-25 18:19:22 +02:00
parent b1f670ada3
commit 4835475fb7
2 changed files with 43 additions and 37 deletions

View file

@ -918,38 +918,41 @@ def read_tasks(session):
# A flat album import merges all items into one album.
if session.config['flat'] and not session.config['singletons']:
all_items = []
for _, items in albums_in_dir(toppath):
all_items += items
if all_items:
all_item_paths = []
for _, item_paths in albums_in_dir(toppath):
all_item_paths += item_paths
if all_item_paths:
if session.already_imported(toppath, [toppath]):
log.debug(u'Skipping previously-imported path: {0}'
.format(displayable_path(toppath)))
skipped += 1
continue
all_items = read_items(all_item_paths)
yield ImportTask(toppath, [toppath], all_items)
yield SentinelImportTask(toppath)
continue
# Produce paths under this directory.
for paths, items in albums_in_dir(toppath):
for dirs, paths in albums_in_dir(toppath):
if session.config['singletons']:
for item in items:
if session.already_imported(toppath, [item.path]):
for path in paths:
if session.already_imported(toppath, [path]):
log.debug(u'Skipping previously-imported path: {0}'
.format(displayable_path(paths)))
.format(displayable_path(path)))
skipped += 1
continue
yield SingletonImportTask(toppath, item)
yield SentinelImportTask(toppath, paths)
yield SingletonImportTask(toppath, read_items([path])[0])
yield SentinelImportTask(toppath, dirs)
else:
if session.already_imported(toppath, paths):
if session.already_imported(toppath, dirs):
log.debug(u'Skipping previously-imported path: {0}'
.format(displayable_path(paths)))
.format(displayable_path(dirs)))
skipped += 1
continue
yield ImportTask(toppath, paths, items)
print(paths)
print(read_items(paths))
yield ImportTask(toppath, dirs, read_items(paths))
# Indicate the directory is finished.
# FIXME hack to delete extracted archives
@ -1178,27 +1181,7 @@ def albums_in_dir(path):
ignore = config['ignore'].as_str_seq()
for root, dirs, files in sorted_walk(path, ignore=ignore, logger=log):
# Get a list of items in the directory.
items = []
for filename in files:
try:
i = library.Item.from_path(os.path.join(root, filename))
except library.ReadError as exc:
if isinstance(exc.reason, mediafile.FileTypeError):
# Silently ignore non-music files.
pass
elif isinstance(exc.reason, mediafile.UnreadableFileError):
log.warn(u'unreadable file: {0}'.format(
displayable_path(filename))
)
else:
log.error(u'error reading {0}: {1}'.format(
displayable_path(filename),
exc,
))
else:
items.append(i)
items = [os.path.join(root, f) for f in files]
# If we're currently collapsing the constituent directories in a
# multi-disc album, check whether we should continue collapsing
# and add the current directory. If so, just add the directory
@ -1284,3 +1267,27 @@ def albums_in_dir(path):
yield collapse_paths, collapse_items
def read_items(paths):
"""Return a list of items created from each path.
If an item could not be read it skips the item and logs an error.
"""
# TODO remove this method. Should be handled in ImportTask creation.
items = []
for path in paths:
try:
items.append(library.Item.from_path(path))
except library.ReadError as exc:
if isinstance(exc.reason, mediafile.FileTypeError):
# Silently ignore non-music files.
pass
elif isinstance(exc.reason, mediafile.UnreadableFileError):
log.warn(u'unreadable file: {0}'.format(
displayable_path(path))
)
else:
log.error(u'error reading {0}: {1}'.format(
displayable_path(path),
exc,
))
return items

View file

@ -1238,7 +1238,7 @@ class AlbumsInDirTest(_common.TestCase):
def test_separates_contents(self):
found = []
for _, album in albums_in_dir(self.base):
found.append(re.search(r'album(.)song', album[0].path).group(1))
found.append(re.search(r'album(.)song', album[0]).group(1))
self.assertTrue('1' in found)
self.assertTrue('2' in found)
self.assertTrue('3' in found)
@ -1246,7 +1246,7 @@ class AlbumsInDirTest(_common.TestCase):
def test_finds_multiple_songs(self):
for _, album in albums_in_dir(self.base):
n = re.search(r'album(.)song', album[0].path).group(1)
n = re.search(r'album(.)song', album[0]).group(1)
if n == '1':
self.assertEqual(len(album), 2)
else:
@ -1329,7 +1329,6 @@ class MultiDiscAlbumsInDirTest(_common.TestCase):
self.assertEquals(len(albums), 0)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)