diff --git a/beets/ui/commands.py b/beets/ui/commands.py index 5d29093c9..4b1248add 100644 --- a/beets/ui/commands.py +++ b/beets/ui/commands.py @@ -426,8 +426,6 @@ def summarize_items(items, singleton): this is an album or single-item import (if the latter, them `items` should only have one element). """ - assert items, "summarizing zero items" - summary_parts = [] if not singleton: summary_parts.append("{0} items".format(len(items))) @@ -439,16 +437,18 @@ def summarize_items(items, singleton): # A single format. summary_parts.append(items[0].format) else: - # Enumerate all the formats. - for fmt, count in format_counts.iteritems(): + # Enumerate all the formats by decreasing frequencies: + for fmt, count in sorted(format_counts.items(), + key=lambda (f, c): (-c, f)): summary_parts.append('{0} {1}'.format(fmt, count)) - average_bitrate = sum([item.bitrate for item in items]) / len(items) - total_duration = sum([item.length for item in items]) - total_filesize = sum([item.filesize for item in items]) - summary_parts.append('{0}kbps'.format(int(average_bitrate / 1000))) - summary_parts.append(ui.human_seconds_short(total_duration)) - summary_parts.append(ui.human_bytes(total_filesize)) + if items: + average_bitrate = sum([item.bitrate for item in items]) / len(items) + total_duration = sum([item.length for item in items]) + total_filesize = sum([item.filesize for item in items]) + summary_parts.append('{0}kbps'.format(int(average_bitrate / 1000))) + summary_parts.append(ui.human_seconds_short(total_duration)) + summary_parts.append(ui.human_bytes(total_filesize)) return ', '.join(summary_parts) @@ -778,6 +778,16 @@ class TerminalImportSession(importer.ImportSession): log.warn(u"This {0} is already in the library!", ("album" if task.is_album else "item")) + # skip empty albums (coming from a previous failed import session) + if task.is_album: + real_duplicates = filter(len, found_duplicates) + if not real_duplicates: + log.info("All duplicates are empty, we ignore them") + task.should_remove_duplicates = True + return + else: + real_duplicates = found_duplicates + if config['import']['quiet']: # In quiet mode, don't prompt -- just skip. log.info(u'Skipping.') @@ -785,11 +795,17 @@ class TerminalImportSession(importer.ImportSession): else: # Print some detail about the existing and new items so the # user can make an informed decision. - for duplicate in found_duplicates: + for duplicate in real_duplicates: print("Old: " + summarize_items( list(duplicate.items()) if task.is_album else [duplicate], not task.is_album, )) + + if real_duplicates != found_duplicates: # there's empty albums + count = len(found_duplicates) - len(real_duplicates) + print("Old: {0} empty album{1}".format( + count, "s" if count > 1 else "")) + print("New: " + summarize_items( task.imported_items(), not task.is_album, diff --git a/test/test_ui.py b/test/test_ui.py index 0f8bb6306..14cb4081f 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -22,7 +22,9 @@ import shutil import re import subprocess import platform +from copy import deepcopy +from mock import patch from test import _common from test._common import unittest from test.helper import capture_stdout, has_program, TestHelper, control_stdin @@ -972,6 +974,43 @@ class ShowChangeTest(_common.TestCase): u'caf.mp3 ->' in msg) +class SummarizeItemsTest(_common.TestCase): + def setUp(self): + super(SummarizeItemsTest, self).setUp() + item = library.Item() + item.bitrate = 4321 + item.length = 10 * 60 + 54 + item.format = "F" + self.item = item + fsize_mock = patch('beets.library.Item.try_filesize').start() + fsize_mock.return_value = 987 + + def test_summarize_item(self): + summary = commands.summarize_items([], True) + self.assertEqual(summary, "") + + summary = commands.summarize_items([self.item], True) + self.assertEqual(summary, "F, 4kbps, 10:54, 987.0 B") + + def test_summarize_items(self): + summary = commands.summarize_items([], False) + self.assertEqual(summary, "0 items") + + summary = commands.summarize_items([self.item], False) + self.assertEqual(summary, "1 items, F, 4kbps, 10:54, 987.0 B") + + i2 = deepcopy(self.item) + summary = commands.summarize_items([self.item, i2], False) + self.assertEqual(summary, "2 items, F, 4kbps, 21:48, 1.9 KB") + + i2.format = "G" + summary = commands.summarize_items([self.item, i2], False) + self.assertEqual(summary, "2 items, F 1, G 1, 4kbps, 21:48, 1.9 KB") + + summary = commands.summarize_items([self.item, i2, i2], False) + self.assertEqual(summary, "3 items, G 2, F 1, 4kbps, 32:42, 2.9 KB") + + class PathFormatTest(_common.TestCase): def test_custom_paths_prepend(self): default_formats = ui.get_path_formats()