diff --git a/picard/album.py b/picard/album.py index 89100701ce..23d2053505 100644 --- a/picard/album.py +++ b/picard/album.py @@ -856,6 +856,10 @@ def children_metadata_items(self): yield from track.files yield from self.unmatched_files.files + def delete_genres_from_tags(self): + for genre in self.genres: + del self.folksonomy_tags[genre] + class NatAlbum(Album): diff --git a/picard/item.py b/picard/item.py index 8874eadda7..a40f0d6fe3 100644 --- a/picard/item.py +++ b/picard/item.py @@ -200,6 +200,7 @@ def __init__(self, obj_id=None): self.iter_children_items_metadata_ignore_attrs = {} self.suspend_metadata_images_update = IgnoreUpdatesContext() self._genres = Counter() + self._folksonomy_tags = Counter() @property def tagger(self): @@ -309,17 +310,24 @@ def add_genre(self, name, count): if name: self._genres[name] += count + @property + def folksonomy_tags(self): + return self._folksonomy_tags + + def add_folksonomy_tag(self, name, count): + if name: + self._folksonomy_tags[name] += count + @staticmethod def set_genre_inc_params(inc, config=None): require_authentication = False config = config or get_config() if config.setting['use_genres']: - use_folksonomy = config.setting['folksonomy_tags'] if config.setting['only_my_genres']: require_authentication = True - inc |= {'user-tags'} if use_folksonomy else {'user-genres'} + inc |= {'user-tags', 'user-genres'} else: - inc |= {'tags'} if use_folksonomy else {'genres'} + inc |= {'tags', 'genres'} return require_authentication diff --git a/picard/mbjson.py b/picard/mbjson.py index be8380b9da..7dbbaf810c 100644 --- a/picard/mbjson.py +++ b/picard/mbjson.py @@ -636,14 +636,14 @@ def add_secondary_release_types(node, m): def add_genres_from_node(node, obj): if obj is None: return + if 'tags' in node: + add_tags(node['tags'], obj) + if 'user-tags' in node: + add_user_tags(node['user-tags'], obj) if 'genres' in node: add_genres(node['genres'], obj) - if 'tags' in node: - add_genres(node['tags'], obj) if 'user-genres' in node: add_user_genres(node['user-genres'], obj) - if 'user-tags' in node: - add_user_genres(node['user-tags'], obj) def add_genres(node, obj): @@ -656,6 +656,16 @@ def add_user_genres(node, obj): obj.add_genre(tag['name'], 1) +def add_tags(node, obj): + for tag in node: + obj.add_folksonomy_tag(tag['name'], tag['count']) + + +def add_user_tags(node, obj): + for tag in node: + obj.add_folksonomy_tag(tag['name'], 1) + + def add_isrcs_to_metadata(node, metadata): for isrc in node: metadata.add('isrc', isrc) diff --git a/picard/track.py b/picard/track.py index fbaae45601..d288c86fa1 100644 --- a/picard/track.py +++ b/picard/track.py @@ -314,6 +314,9 @@ def _customize_metadata(self): if config.setting['use_genres']: self._convert_folksonomy_tags_to_genre() + self.album.delete_genres_from_tags() + self._add_folksonomy_tags() + self._add_genres() # Convert Unicode punctuation if config.setting['convert_punctuation']: @@ -346,9 +349,13 @@ def _genres_to_metadata(genres, limit=None, minusage=0, filters='', join_with=No def _convert_folksonomy_tags_to_genre(self): config = get_config() - # Combine release and track genres genres = Counter(self.genres) - genres += self.album.genres + use_folksonomy = config.setting['folksonomy_tags'] + if use_folksonomy: + genres += self.album.folksonomy_tags + else: + genres += self.album.genres + # Combine release and track genres if self.album.release_group: genres += self.album.release_group.genres if not genres and config.setting['artists_genres']: @@ -368,6 +375,19 @@ def _convert_folksonomy_tags_to_genre(self): join_with=config.setting['join_genres'] ) + def _add_tags(self, tags, name): + self.metadata[name] = tags.keys() + + def _add_folksonomy_tags(self): + tags = Counter(self.folksonomy_tags) + tags += self.album.folksonomy_tags + self._add_tags(tags, '_folksonomy_tags') + + def _add_genres(self): + genre = Counter(self.genres) + genre += self.album.genres + self._add_tags(genre, '_genres') + class NonAlbumTrack(Track): diff --git a/test/test_mbjson.py b/test/test_mbjson.py index f466fc5450..7756c9d776 100644 --- a/test/test_mbjson.py +++ b/test/test_mbjson.py @@ -135,11 +135,14 @@ def test_release(self): self.assertEqual(m['~release_seriesid'], '7421b602-a413-4151-bcf4-d831debc3f27') self.assertEqual(m['~release_seriescomment'], 'Pink Floyed special editions') self.assertEqual(m['~release_seriesnumber'], '') - self.assertEqual(a.genres, { - 'genre1': 6, 'genre2': 3, - 'tag1': 6, 'tag2': 3}) + self.assertEqual(a._genres, { + 'genre1': 6, 'genre2': 3 + }) + self.assertEqual(a._folksonomy_tags, { + 'tag1': 6, 'tag2': 3 + }) for artist in a._album_artists: - self.assertEqual(artist.genres, { + self.assertEqual(artist._folksonomy_tags, { 'british': 2, 'progressive rock': 10}) @@ -167,10 +170,13 @@ def test_release_without_release_relationships(self): self.assertEqual(m['~releaselanguage'], 'eng') self.assertEqual(m.getall('~releasecountries'), ['GB', 'NZ']) self.assertEqual(a.genres, { - 'genre1': 6, 'genre2': 3, - 'tag1': 6, 'tag2': 3}) + 'genre1': 6, 'genre2': 3 + }) + self.assertEqual(a.folksonomy_tags, { + 'tag1': 6, 'tag2': 3 + }) for artist in a._album_artists: - self.assertEqual(artist.genres, { + self.assertEqual(artist.folksonomy_tags, { 'british': 2, 'progressive rock': 10}) @@ -293,11 +299,11 @@ def test_recording(self): self.assertEqual(m['~video'], '') self.assertNotIn('originaldate', m) self.assertNotIn('originalyear', m) - self.assertEqual(t.genres, { + self.assertEqual(t.folksonomy_tags, { 'blue-eyed soul': 1, 'pop': 3}) for artist in t._track_artists: - self.assertEqual(artist.genres, { + self.assertEqual(artist.folksonomy_tags, { 'dance-pop': 1, 'guitarist': 0}) @@ -770,7 +776,7 @@ def test_release_group(self): self.assertEqual(m['releasetype'], 'album') self.assertEqual(m['~primaryreleasetype'], 'album') self.assertEqual(m['~releasegroup'], 'The Dark Side of the Moon') - self.assertEqual(r.genres, {'test2': 3, 'test': 6}) + self.assertEqual(r.folksonomy_tags, {'test2': 3, 'test': 6}) class NullReleaseGroupTest(MBJSONTest):