From fd25dc987d3ff030c72a999dbe6df3b27eda64fb Mon Sep 17 00:00:00 2001 From: Laurent Monin Date: Wed, 19 Feb 2020 00:47:50 +0100 Subject: [PATCH] PICARD-1748: limit number of countries displayed to 10 --- picard/releasegroup.py | 10 +++++++--- picard/util/__init__.py | 37 +++++++++++++++++++++++++++++++++++++ test/test_utils.py | 26 ++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/picard/releasegroup.py b/picard/releasegroup.py index 5256df2d9..d95444135 100644 --- a/picard/releasegroup.py +++ b/picard/releasegroup.py @@ -2,6 +2,7 @@ # # Picard, the next-generation MusicBrainz tagger # Copyright (C) 2012 Michael Wiencek +# Copyright (C) 2020 Laurent Monin # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -30,7 +31,10 @@ from picard.mbjson import ( media_formats_from_node, ) from picard.metadata import Metadata -from picard.util import uniqify +from picard.util import ( + limited_join, + uniqify, +) class ReleaseGroup(DataObject): @@ -86,8 +90,8 @@ class ReleaseGroup(DataObject): release = { "id": node['id'], "year": node['date'][:4] if "date" in node else "????", - "country": "+".join(countries) if countries - else node.get('country', '') or "??", + "country": limited_join(countries, 10, '+', '…') if countries + else node.get('country', '') or "??", "format": media_formats_from_node(node['media']), "label": ", ".join([' '.join(x.split(' ')[:2]) for x in set(labels)]), "catnum": ", ".join(set(catnums)), diff --git a/picard/util/__init__.py b/picard/util/__init__.py index 3e26d206f..8d6b9ec51 100644 --- a/picard/util/__init__.py +++ b/picard/util/__init__.py @@ -3,6 +3,7 @@ # Picard, the next-generation MusicBrainz tagger # Copyright (C) 2004 Robert Kaye # Copyright (C) 2006 Lukáš Lalinský +# Copyright (C) 2020 Laurent Monin # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -593,3 +594,39 @@ def get_qt_enum(cls, enum): if isinstance(value, enum): values.append(key) return values + + +def limited_join(a_list, limit, join_string='+', middle_string='…'): + """Join elements of a list with `join_string` + If list is longer than `limit`, middle elements will be dropped, + and replaced by `middle_string`. + + Args: + a_list: list of strings to join + limit: maximum number of elements to join before limiting + join_string: string used to join elements + middle_string: string to insert in the middle if limited + + Returns: + A string + + Example: + >>> limited_join(['a', 'b', 'c', 'd', 'e', 'f'], 2) + 'a+…+f' + >>> limited_join(['a', 'b', 'c', 'd', 'e', 'f'], 3) + 'a+…+f' + >>> limited_join(['a', 'b', 'c', 'd', 'e', 'f'], 4) + 'a+b+…+e+f' + >>> limited_join(['a', 'b', 'c', 'd', 'e', 'f'], 6) + 'a+b+c+d+e+f' + >>> limited_join(['a', 'b', 'c', 'd', 'e', 'f'], 2, ',', '?') + 'a,?,f' + """ + length = len(a_list) + if limit <= 1 or limit >= length: + return join_string.join(a_list) + + half = limit // 2 + start = a_list[:half] + end = a_list[-half:] + return join_string.join(start + [middle_string] + end) diff --git a/test/test_utils.py b/test/test_utils.py index 2889fde32..a3f7de329 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -12,6 +12,7 @@ from picard.const.sys import IS_WIN from picard.util import ( find_best_match, imageinfo, + limited_join, sort_by_similarity, ) @@ -342,3 +343,28 @@ class GetQtEnum(PicardTestCase): self.assertIn('LocateFile', values) self.assertIn('LocateDirectory', values) self.assertNotIn('DesktopLocation', values) + + +class LimitedJoin(PicardTestCase): + + def setUp(self): + self.list = [str(x) for x in range(0, 10)] + + def test_1(self): + expected = '0+1+...+8+9' + result = limited_join(self.list, 5, '+', '...') + self.assertEqual(result, expected) + + def test_2(self): + expected = '0+1+2+3+4+5+6+7+8+9' + result = limited_join(self.list, -1) + self.assertEqual(result, expected) + result = limited_join(self.list, len(self.list)) + self.assertEqual(result, expected) + result = limited_join(self.list, len(self.list) + 1) + self.assertEqual(result, expected) + + def test_3(self): + expected = '0,1,2,3,…,6,7,8,9' + result = limited_join(self.list, len(self.list) - 1, ',') + self.assertEqual(result, expected)