diff --git a/beets/importer.py b/beets/importer.py index 060a188c9..76c90dbea 100644 --- a/beets/importer.py +++ b/beets/importer.py @@ -250,7 +250,7 @@ class ImportSession(object): def choose_match(self, task): raise NotImplementedError - def resolve_duplicate(self, task): + def resolve_duplicate(self, task, found_duplicates): raise NotImplementedError def choose_item(self, task): @@ -1056,8 +1056,9 @@ def resolve_duplicates(session, task): """ if task.choice_flag in (action.ASIS, action.APPLY): ident = task.chosen_ident() - if ident in session.seen_idents or task.find_duplicates(session.lib): - session.resolve_duplicate(task) + found_duplicates = task.find_duplicates(session.lib) + if ident in session.seen_idents or found_duplicates: + session.resolve_duplicate(task, found_duplicates) session.log_choice(task, True) session.seen_idents.add(ident) diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py index 1e64cd89c..993964291 100644 --- a/beets/ui/__init__.py +++ b/beets/ui/__init__.py @@ -989,3 +989,29 @@ def main(args=None): except KeyboardInterrupt: # Silently ignore ^C except in verbose mode. log.debug(traceback.format_exc()) + + + +def summarize_items(items): + """Produces a brief summary line for manually resolving duplicates during import. + Accepts a list of tuples, one per item containing: + (path, format, bitrate, duration) + """ + + summary_text = "" + summary_text += "%d items. " % len(items) + format_counts = {} + for item in items: + format_counts[item[1]] = format_counts.get(item[1],0) + 1; + + for format, count in format_counts.iteritems(): + summary_text += '{count} {format}. '.format(format=format, count=count) + + average_bitrate = sum([item[2] for item in items]) / len(items) + total_duration = sum([item[3] for item in items]) + summary_text += '{bitrate}kbps average bitrate. '.format(bitrate=int(average_bitrate/1000)) + summary_text += '{length} total length. '.format(length=human_seconds_short(total_duration)) + + return summary_text + + diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 14f2bf0a4..0cc3bcf9d 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -741,7 +741,7 @@ class TerminalImportSession(importer.ImportSession): assert isinstance(choice, autotag.TrackMatch) return choice - def resolve_duplicate(self, task): + def resolve_duplicate(self, task, found_duplicates): """Decide what to do when a new album or item seems similar to one that's already in the library. """ @@ -753,6 +753,13 @@ class TerminalImportSession(importer.ImportSession): log.info('Skipping.') sel = 's' else: + # print some detail about the existing and new items so it can be an informed decision + for duplicate in found_duplicates: + old_items = [(item.path, item.format, item.bitrate, item.length) for item in duplicate.items()] + print("OLD: " + ui.summarize_items(old_items)) + new_items = [(item.path, item.format, item.bitrate, item.length) for item in task.items] + print("NEW: " + ui.summarize_items(new_items)) + sel = ui.input_options( ('Skip new', 'Keep both', 'Remove old') ) diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 428de312a..ec3a3c1bc 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -25,7 +25,6 @@ import traceback import subprocess import platform - MAX_FILENAME_LENGTH = 200 WINDOWS_MAGIC_PREFIX = u'\\\\?\\'