mirror of
https://github.com/beetbox/beets.git
synced 2026-02-02 05:21:45 +01:00
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:
parent
b1f670ada3
commit
4835475fb7
2 changed files with 43 additions and 37 deletions
|
|
@ -918,38 +918,41 @@ def read_tasks(session):
|
||||||
|
|
||||||
# A flat album import merges all items into one album.
|
# A flat album import merges all items into one album.
|
||||||
if session.config['flat'] and not session.config['singletons']:
|
if session.config['flat'] and not session.config['singletons']:
|
||||||
all_items = []
|
all_item_paths = []
|
||||||
for _, items in albums_in_dir(toppath):
|
for _, item_paths in albums_in_dir(toppath):
|
||||||
all_items += items
|
all_item_paths += item_paths
|
||||||
if all_items:
|
if all_item_paths:
|
||||||
if session.already_imported(toppath, [toppath]):
|
if session.already_imported(toppath, [toppath]):
|
||||||
log.debug(u'Skipping previously-imported path: {0}'
|
log.debug(u'Skipping previously-imported path: {0}'
|
||||||
.format(displayable_path(toppath)))
|
.format(displayable_path(toppath)))
|
||||||
skipped += 1
|
skipped += 1
|
||||||
continue
|
continue
|
||||||
|
all_items = read_items(all_item_paths)
|
||||||
yield ImportTask(toppath, [toppath], all_items)
|
yield ImportTask(toppath, [toppath], all_items)
|
||||||
yield SentinelImportTask(toppath)
|
yield SentinelImportTask(toppath)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Produce paths under this directory.
|
# 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']:
|
if session.config['singletons']:
|
||||||
for item in items:
|
for path in paths:
|
||||||
if session.already_imported(toppath, [item.path]):
|
if session.already_imported(toppath, [path]):
|
||||||
log.debug(u'Skipping previously-imported path: {0}'
|
log.debug(u'Skipping previously-imported path: {0}'
|
||||||
.format(displayable_path(paths)))
|
.format(displayable_path(path)))
|
||||||
skipped += 1
|
skipped += 1
|
||||||
continue
|
continue
|
||||||
yield SingletonImportTask(toppath, item)
|
yield SingletonImportTask(toppath, read_items([path])[0])
|
||||||
yield SentinelImportTask(toppath, paths)
|
yield SentinelImportTask(toppath, dirs)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if session.already_imported(toppath, paths):
|
if session.already_imported(toppath, dirs):
|
||||||
log.debug(u'Skipping previously-imported path: {0}'
|
log.debug(u'Skipping previously-imported path: {0}'
|
||||||
.format(displayable_path(paths)))
|
.format(displayable_path(dirs)))
|
||||||
skipped += 1
|
skipped += 1
|
||||||
continue
|
continue
|
||||||
yield ImportTask(toppath, paths, items)
|
print(paths)
|
||||||
|
print(read_items(paths))
|
||||||
|
yield ImportTask(toppath, dirs, read_items(paths))
|
||||||
|
|
||||||
# Indicate the directory is finished.
|
# Indicate the directory is finished.
|
||||||
# FIXME hack to delete extracted archives
|
# FIXME hack to delete extracted archives
|
||||||
|
|
@ -1178,27 +1181,7 @@ def albums_in_dir(path):
|
||||||
ignore = config['ignore'].as_str_seq()
|
ignore = config['ignore'].as_str_seq()
|
||||||
|
|
||||||
for root, dirs, files in sorted_walk(path, ignore=ignore, logger=log):
|
for root, dirs, files in sorted_walk(path, ignore=ignore, logger=log):
|
||||||
# Get a list of items in the directory.
|
items = [os.path.join(root, f) for f in files]
|
||||||
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)
|
|
||||||
|
|
||||||
# If we're currently collapsing the constituent directories in a
|
# If we're currently collapsing the constituent directories in a
|
||||||
# multi-disc album, check whether we should continue collapsing
|
# multi-disc album, check whether we should continue collapsing
|
||||||
# and add the current directory. If so, just add the directory
|
# 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
|
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
|
||||||
|
|
|
||||||
|
|
@ -1238,7 +1238,7 @@ class AlbumsInDirTest(_common.TestCase):
|
||||||
def test_separates_contents(self):
|
def test_separates_contents(self):
|
||||||
found = []
|
found = []
|
||||||
for _, album in albums_in_dir(self.base):
|
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('1' in found)
|
||||||
self.assertTrue('2' in found)
|
self.assertTrue('2' in found)
|
||||||
self.assertTrue('3' in found)
|
self.assertTrue('3' in found)
|
||||||
|
|
@ -1246,7 +1246,7 @@ class AlbumsInDirTest(_common.TestCase):
|
||||||
|
|
||||||
def test_finds_multiple_songs(self):
|
def test_finds_multiple_songs(self):
|
||||||
for _, album in albums_in_dir(self.base):
|
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':
|
if n == '1':
|
||||||
self.assertEqual(len(album), 2)
|
self.assertEqual(len(album), 2)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1329,7 +1329,6 @@ class MultiDiscAlbumsInDirTest(_common.TestCase):
|
||||||
self.assertEquals(len(albums), 0)
|
self.assertEquals(len(albums), 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue