def test_do_not_yield_empty_album(self): # Remove all the MP3s. for path in self.files: os.remove(path) albums = list(autotag.albums_in_dir(self.base)) self.assertEquals(len(albums), 0)
def test_finds_multiple_songs(self): for _, album in autotag.albums_in_dir(self.base): n = re.search(r"album(.)song", album[0].path).group(1) if n == "1": self.assertEqual(len(album), 2) else: self.assertEqual(len(album), 1)
def test_finds_multiple_songs(self): for _, album in autotag.albums_in_dir(self.base): n = re.search(r'album(.)song', album[0].path).group(1) if n == '1': self.assertEqual(len(album), 2) else: self.assertEqual(len(album), 1)
def test_separates_contents(self): found = [] for _, album in autotag.albums_in_dir(self.base): found.append(re.search(r'album(.)song', album[0].path).group(1)) self.assertTrue('1' in found) self.assertTrue('2' in found) self.assertTrue('3' in found) self.assertTrue('4' in found)
def test_separates_contents(self): found = [] for _, album in autotag.albums_in_dir(self.base): found.append(re.search(r"album(.)song", album[0].path).group(1)) self.assertTrue("1" in found) self.assertTrue("2" in found) self.assertTrue("3" in found) self.assertTrue("4" in found)
def read_items(config): """Reads individual items by recursively descending into a set of directories. Generates ImportTask objects, each of which contains a single item. """ for toppath in config.paths: for path, items in autotag.albums_in_dir(toppath): for item in items: yield ImportTask.item_task(item)
def read_albums(paths, resume): """A generator yielding all the albums (as sets of Items) found in the user-specified list of paths. `progress` specifies whether the resuming feature should be used. It may be True (resume if possible), False (never resume), or None (ask). """ # Use absolute paths. paths = [library._normpath(path) for path in paths] # Check the user-specified directories. for path in paths: if not os.path.isdir(library._syspath(path)): raise ui.UserError('not a directory: ' + path) # Look for saved progress. progress = resume is not False if progress: resume_dirs = {} for path in paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if resume: do_resume = True ui.print_('Resuming interrupted import of %s' % path) else: do_resume = ui.input_yn("Import of the directory:\n%s" "\nwas interrupted. Resume (Y/n)?" % path) ui.print_() if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) for toppath in paths: # Produce each path. if progress: resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(os.path.expanduser(toppath)): if progress and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue yield toppath, path, items # Indicate the directory is finished. yield toppath, DONE_SENTINEL, None
def read_albums(config): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. `progress` specifies whether the resuming feature should be used. It may be True (resume if possible), False (never resume), or None (ask). """ # Look for saved progress. progress = config.resume is not False if progress: resume_dirs = {} for path in config.paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if config.resume: do_resume = True log.warn('Resuming interrupted import of %s' % path) else: do_resume = config.should_resume_func(config, path) if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) for toppath in config.paths: # Produce each path. if progress: resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(toppath): if progress and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue yield ImportTask(toppath, path, items) # Indicate the directory is finished. yield ImportTask.done_sentinel(toppath)
def read_albums(paths): """A generator yielding all the albums (as sets of Items) found in the user-specified list of paths. """ # Use absolute paths. paths = [library._normpath(path) for path in paths] # Check the user-specified directories. for path in paths: if not os.path.isdir(library._syspath(path)): raise ui.UserError('not a directory: ' + path) # Look for saved progress. resume_dirs = {} for path in paths: resume_dir = progress_get(path) if resume_dir: resume = ui.input_yn("Import of the directory:\n%s" "\nwas interrupted. Resume (Y/n)? " % path) if resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) ui.print_() for toppath in paths: # Produce each path. resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(os.path.expanduser(toppath)): if resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue yield toppath, path, items # Indicate the directory is finished. yield toppath, DONE_SENTINEL, None
def test_coalesce_nested_album_multiple_subdirs(self): albums = list(autotag.albums_in_dir(self.base)) self.assertEquals(len(albums), 4) root, items = albums[0] self.assertEquals(root, self.dirs[0:3]) self.assertEquals(len(items), 3)
def read_tasks(config): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved progress. progress = config.resume is not False if progress: resume_dirs = {} for path in config.paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if config.resume: do_resume = True log.warn('Resuming interrupted import of %s' % path) else: do_resume = config.should_resume_func(config, path) if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) # Look for saved incremental directories. if config.incremental: history_dirs = history_get() for toppath in config.paths: # Check whether the path is to a file. if config.singletons and not os.path.isdir(syspath(toppath)): item = library.Item.from_path(toppath) yield ImportTask.item_task(item) continue # Produce paths under this directory. if progress: resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(toppath, config.ignore): # Skip according to progress. if progress and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if config.incremental and path in history_dirs: continue # Yield all the necessary tasks. if config.singletons: for item in items: yield ImportTask.item_task(item) yield ImportTask.progress_sentinel(toppath, path) else: yield ImportTask(toppath, path, items) # Indicate the directory is finished. yield ImportTask.done_sentinel(toppath)
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved incremental directories. if session.config['incremental']: incremental_skipped = 0 history_dirs = history_get() for toppath in session.paths: # Extract archives. archive_task = None if ArchiveImportTask.is_archive(syspath(toppath)): if not (session.config['move'] or session.config['copy']): log.warn("Archive importing requires either " "'copy' or 'move' to be enabled.") continue log.debug('extracting archive {0}' .format(displayable_path(toppath))) archive_task = ArchiveImportTask(toppath) try: archive_task.extract() except Exception as exc: log.error('extraction failed: {0}'.format(exc)) continue # Continue reading albums from the extracted directory. toppath = archive_task.toppath # Check whether the path is to a file. if not os.path.isdir(syspath(toppath)): try: item = library.Item.from_path(toppath) except mediafile.UnreadableFileError: log.warn(u'unreadable file: {0}'.format( util.displayable_path(toppath) )) continue if session.config['singletons']: yield SingletonImportTask(item) else: yield ImportTask(toppath, [toppath], [item]) continue # A flat album import merges all items into one album. if session.config['flat'] and not session.config['singletons']: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items yield ImportTask(toppath, [toppath], all_items) yield SentinelImportTask(toppath) continue resume_dir = None if session.want_resume: resume_dir = progress_get(toppath) if resume_dir: # Either accept immediately or prompt for input to decide. if session.want_resume is True or \ session.should_resume(toppath): log.warn('Resuming interrupted import of %s' % toppath) else: # Clear progress; we're starting from the top. resume_dir = None progress_set(toppath, None) # Produce paths under this directory. for paths, items in autotag.albums_in_dir(toppath): # Skip according to progress. if session.want_resume and resume_dir: # We're fast-forwarding to resume a previous tagging. if paths == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if session.config['incremental'] \ and tuple(paths) in history_dirs: log.debug(u'Skipping previously-imported path: %s' % displayable_path(paths)) incremental_skipped += 1 continue # Yield all the necessary tasks. if session.config['singletons']: for item in items: yield SingletonImportTask(item) yield SentinelImportTask(toppath, paths) else: yield ImportTask(toppath, paths, items) # Indicate the directory is finished. # FIXME hack to delete extracted archives if archive_task is None: yield SentinelImportTask(toppath) else: yield archive_task # Show skipped directories. if session.config['incremental'] and incremental_skipped: log.info(u'Incremental import: skipped %i directories.' % incremental_skipped)
def test_finds_all_albums(self): albums = list(autotag.albums_in_dir(self.base)) self.assertEqual(len(albums), 4)
def test_coalesce_multi_disc_album(self): albums = list(autotag.albums_in_dir(self.base)) self.assertEquals(len(albums), 3) root, items = albums[0] self.assertEquals(root, os.path.join(self.base, "album1")) self.assertEquals(len(items), 3)
def test_separate_red_herring(self): albums = list(autotag.albums_in_dir(self.base)) root, items = albums[1] self.assertEquals(root, os.path.join(self.base, "dir2", "disc 1")) root, items = albums[2] self.assertEquals(root, os.path.join(self.base, "dir2", "something"))
def test_coalesce_flattened_album_case_typo(self): albums = list(autotag.albums_in_dir(self.base)) root, items = albums[2] self.assertEquals(root, self.dirs[6:8]) self.assertEquals(len(items), 2)
def test_coalesce_nested_album_single_subdir(self): albums = list(autotag.albums_in_dir(self.base)) root, items = albums[1] self.assertEquals(root, self.dirs[3:5]) self.assertEquals(len(items), 1)
def test_single_disc_album(self): albums = list(autotag.albums_in_dir(self.base)) root, items = albums[3] self.assertEquals(root, self.dirs[8:]) self.assertEquals(len(items), 1)
def read_tasks(config): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved progress. progress = config.resume is not False if progress: resume_dirs = {} for path in config.paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if config.resume: do_resume = True log.warn('Resuming interrupted import of %s' % path) else: do_resume = config.should_resume_func(config, path) if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) # Look for saved incremental directories. if config.incremental: incremental_skipped = 0 history_dirs = history_get() for toppath in config.paths: # Check whether the path is to a file. if config.singletons and not os.path.isdir(syspath(toppath)): item = library.Item.from_path(toppath) yield ImportTask.item_task(item) continue # Produce paths under this directory. if progress: resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(toppath, config.ignore): # Skip according to progress. if progress and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if config.incremental and path in history_dirs: log.debug(u'Skipping previously-imported path: %s' % displayable_path(path)) incremental_skipped += 1 continue # Yield all the necessary tasks. if config.singletons: for item in items: yield ImportTask.item_task(item) yield ImportTask.progress_sentinel(toppath, path) else: yield ImportTask(toppath, path, items) # Indicate the directory is finished. yield ImportTask.done_sentinel(toppath) # Show skipped directories. if config.incremental and incremental_skipped: log.info(u'Incremental import: skipped %i directories.' % incremental_skipped)
def test_coalesce_multi_disc_album(self): albums = list(autotag.albums_in_dir(self.base)) self.assertEquals(len(albums), 3) root, items = albums[0] self.assertEquals(root, os.path.join(self.base, 'album1')) self.assertEquals(len(items), 3)
def test_separate_red_herring(self): albums = list(autotag.albums_in_dir(self.base)) root, items = albums[1] self.assertEquals(root, os.path.join(self.base, 'dir2', 'disc 1')) root, items = albums[2] self.assertEquals(root, os.path.join(self.base, 'dir2', 'something'))
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ skipped = 0 for toppath in session.paths: # Determine if we want to resume import of the toppath session.ask_resume(toppath) # Extract archives. archive_task = None if ArchiveImportTask.is_archive(syspath(toppath)): if not (session.config['move'] or session.config['copy']): log.warn("Archive importing requires either " "'copy' or 'move' to be enabled.") continue log.debug('extracting archive {0}' .format(displayable_path(toppath))) archive_task = ArchiveImportTask(toppath) try: archive_task.extract() except Exception as exc: log.error('extraction failed: {0}'.format(exc)) continue # Continue reading albums from the extracted directory. toppath = archive_task.toppath # Check whether the path is to a file. if not os.path.isdir(syspath(toppath)): # FIXME remove duplicate code. We could put the debug # statement into `session.alread_imported` but I don't feel # comfortable triggering an action in a query. if session.already_imported(toppath, toppath): log.debug(u'Skipping previously-imported path: {0}' .format(displayable_path(toppath))) skipped += 1 continue try: item = library.Item.from_path(toppath) except mediafile.UnreadableFileError: log.warn(u'unreadable file: {0}'.format( util.displayable_path(toppath) )) continue if session.config['singletons']: yield SingletonImportTask(toppath, item) else: yield ImportTask(toppath, [toppath], [item]) continue # A flat album import merges all items into one album. if session.config['flat'] and not session.config['singletons']: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items if all_items: if session.already_imported(toppath, [toppath]): log.debug(u'Skipping previously-imported path: {0}' .format(displayable_path(toppath))) skipped += 1 continue yield ImportTask(toppath, [toppath], all_items) yield SentinelImportTask(toppath) continue # Produce paths under this directory. for paths, items in autotag.albums_in_dir(toppath): if session.config['singletons']: for item in items: if session.already_imported(toppath, [item.path]): log.debug(u'Skipping previously-imported path: {0}' .format(displayable_path(paths))) skipped += 1 continue yield SingletonImportTask(toppath, item) yield SentinelImportTask(toppath, paths) else: if session.already_imported(toppath, paths): log.debug(u'Skipping previously-imported path: {0}' .format(displayable_path(paths))) skipped += 1 continue yield ImportTask(toppath, paths, items) # Indicate the directory is finished. # FIXME hack to delete extracted archives if archive_task is None: yield SentinelImportTask(toppath) else: yield archive_task # Show skipped directories. if skipped: log.info(u'Skipped {0} directories.'.format(skipped))
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved incremental directories. if session.config["incremental"]: incremental_skipped = 0 history_dirs = history_get() for toppath in session.paths: # Determine if we want to resume import of the toppath resuming = False if session.want_resume and has_progress(toppath): # Either accept immediately or prompt for input to decide. if session.want_resume is True or session.should_resume(toppath): log.warn("Resuming interrupted import of %s" % toppath) resuming = True else: # Clear progress; we're starting from the top. progress_reset(toppath) # Extract archives. archive_task = None if ArchiveImportTask.is_archive(syspath(toppath)): if not (session.config["move"] or session.config["copy"]): log.warn("Archive importing requires either " "'copy' or 'move' to be enabled.") continue log.debug("extracting archive {0}".format(displayable_path(toppath))) archive_task = ArchiveImportTask(toppath) try: archive_task.extract() except Exception as exc: log.error("extraction failed: {0}".format(exc)) continue # Continue reading albums from the extracted directory. toppath = archive_task.toppath # Check whether the path is to a file. if not os.path.isdir(syspath(toppath)): if resuming and progress_element(toppath, toppath): continue try: item = library.Item.from_path(toppath) except mediafile.UnreadableFileError: log.warn(u"unreadable file: {0}".format(util.displayable_path(toppath))) continue if session.config["singletons"]: yield SingletonImportTask(toppath, item) else: yield ImportTask(toppath, [toppath], [item]) continue # A flat album import merges all items into one album. if session.config["flat"] and not session.config["singletons"]: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items if all_items: yield ImportTask(toppath, [toppath], all_items) yield SentinelImportTask(toppath) continue # Produce paths under this directory. for paths, items in autotag.albums_in_dir(toppath): # Skip according to progress. if resuming and all(map(lambda p: progress_element(toppath, p), paths)): continue # When incremental, skip paths in the history. if session.config["incremental"] and tuple(paths) in history_dirs: log.debug(u"Skipping previously-imported path: %s" % displayable_path(paths)) incremental_skipped += 1 continue # Yield all the necessary tasks. if session.config["singletons"]: for item in items: if not (resuming and progress_element(toppath, item.path)): yield SingletonImportTask(toppath, item) yield SentinelImportTask(toppath, paths) else: yield ImportTask(toppath, paths, items) # Indicate the directory is finished. # FIXME hack to delete extracted archives if archive_task is None: yield SentinelImportTask(toppath) else: yield archive_task # Show skipped directories. if session.config["incremental"] and incremental_skipped: log.info(u"Incremental import: skipped %i directories." % incremental_skipped)
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved incremental directories. if session.config['incremental']: incremental_skipped = 0 history_dirs = history_get() for toppath in session.paths: # Extract archives. archive_task = None if ArchiveImportTask.is_archive(syspath(toppath)): if not (session.config['move'] or session.config['copy']): log.warn("Archive importing requires either " "'copy' or 'move' to be enabled.") continue log.debug('extracting archive {0}' .format(displayable_path(toppath))) archive_task = ArchiveImportTask(toppath) try: archive_task.extract() except Exception as exc: log.error('extraction failed: {0}'.format(exc)) continue # Continue reading albums from the extracted directory. toppath = archive_task.toppath # Check whether the path is to a file. if not os.path.isdir(syspath(toppath)): try: item = library.Item.from_path(toppath) except mediafile.UnreadableFileError: log.warn(u'unreadable file: {0}'.format( util.displayable_path(toppath) )) continue if session.config['singletons']: yield SingletonImportTask(item) else: yield ImportTask(toppath, [toppath], [item]) continue # A flat album import merges all items into one album. if session.config['flat'] and not session.config['singletons']: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items if all_items: yield ImportTask(toppath, [toppath], all_items) yield SentinelImportTask(toppath) continue resume_dir = None if session.want_resume: resume_dir = progress_get(toppath) if resume_dir: # Either accept immediately or prompt for input to decide. if session.want_resume is True or \ session.should_resume(toppath): log.warn('Resuming interrupted import of %s' % toppath) else: # Clear progress; we're starting from the top. resume_dir = None progress_set(toppath, None) # Produce paths under this directory. for paths, items in autotag.albums_in_dir(toppath): # Skip according to progress. if session.want_resume and resume_dir: # We're fast-forwarding to resume a previous tagging. if paths == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if session.config['incremental'] \ and tuple(paths) in history_dirs: log.debug(u'Skipping previously-imported path: %s' % displayable_path(paths)) incremental_skipped += 1 continue # Yield all the necessary tasks. if session.config['singletons']: for item in items: yield SingletonImportTask(item) yield SentinelImportTask(toppath, paths) else: yield ImportTask(toppath, paths, items) # Indicate the directory is finished. # FIXME hack to delete extracted archives if archive_task is None: yield SentinelImportTask(toppath) else: yield archive_task # Show skipped directories. if session.config['incremental'] and incremental_skipped: log.info(u'Incremental import: skipped %i directories.' % incremental_skipped)
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved progress. if _resume(): resume_dirs = {} for path in session.paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if _resume() == True: do_resume = True log.warn('Resuming interrupted import of %s' % path) else: do_resume = session.should_resume(path) if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) # Look for saved incremental directories. if config['import']['incremental']: incremental_skipped = 0 history_dirs = history_get() for toppath in session.paths: # Check whether the path is to a file. if config['import']['singletons'] and \ not os.path.isdir(syspath(toppath)): try: item = library.Item.from_path(toppath) except UnreadableFileError: log.warn(u'unreadable file: {0}'.format( util.displayable_path(toppath))) continue yield ImportTask.item_task(item) continue # A flat album import merges all items into one album. if config['import']['flat'] and not config['import']['singletons']: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items yield ImportTask(toppath, toppath, all_items) yield ImportTask.done_sentinel(toppath) continue # Produce paths under this directory. if _resume(): resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(toppath): # Skip according to progress. if _resume() and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if config['import']['incremental'] and tuple(path) in history_dirs: log.debug(u'Skipping previously-imported path: %s' % displayable_path(path)) incremental_skipped += 1 continue # Yield all the necessary tasks. if config['import']['singletons']: for item in items: yield ImportTask.item_task(item) yield ImportTask.progress_sentinel(toppath, path) else: yield ImportTask(toppath, path, items) # Indicate the directory is finished. yield ImportTask.done_sentinel(toppath) # Show skipped directories. if config['import']['incremental'] and incremental_skipped: log.info(u'Incremental import: skipped %i directories.' % incremental_skipped)
def read_tasks(session): """A generator yielding all the albums (as ImportTask objects) found in the user-specified list of paths. In the case of a singleton import, yields single-item tasks instead. """ # Look for saved progress. if _resume(): resume_dirs = {} for path in session.paths: resume_dir = progress_get(path) if resume_dir: # Either accept immediately or prompt for input to decide. if _resume() == True: do_resume = True log.warn('Resuming interrupted import of %s' % path) else: do_resume = session.should_resume(path) if do_resume: resume_dirs[path] = resume_dir else: # Clear progress; we're starting from the top. progress_set(path, None) # Look for saved incremental directories. if config['import']['incremental']: incremental_skipped = 0 history_dirs = history_get() for toppath in session.paths: # Check whether the path is to a file. if config['import']['singletons'] and \ not os.path.isdir(syspath(toppath)): try: item = library.Item.from_path(toppath) except UnreadableFileError: log.warn(u'unreadable file: {0}'.format( util.displayable_path(toppath) )) continue yield ImportTask.item_task(item) continue # A flat album import merges all items into one album. if config['import']['flat'] and not config['import']['singletons']: all_items = [] for _, items in autotag.albums_in_dir(toppath): all_items += items yield ImportTask(toppath, toppath, all_items) yield ImportTask.done_sentinel(toppath) continue # Produce paths under this directory. if _resume(): resume_dir = resume_dirs.get(toppath) for path, items in autotag.albums_in_dir(toppath): # Skip according to progress. if _resume() and resume_dir: # We're fast-forwarding to resume a previous tagging. if path == resume_dir: # We've hit the last good path! Turn off the # fast-forwarding. resume_dir = None continue # When incremental, skip paths in the history. if config['import']['incremental'] and tuple(path) in history_dirs: log.debug(u'Skipping previously-imported path: %s' % displayable_path(path)) incremental_skipped += 1 continue # Yield all the necessary tasks. if config['import']['singletons']: for item in items: yield ImportTask.item_task(item) yield ImportTask.progress_sentinel(toppath, path) else: yield ImportTask(toppath, path, items) # Indicate the directory is finished. yield ImportTask.done_sentinel(toppath) # Show skipped directories. if config['import']['incremental'] and incremental_skipped: log.info(u'Incremental import: skipped %i directories.' % incremental_skipped)