From 08ce00e3cd854b4ab83f45daff5ffc6b85a60da6 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Mon, 14 Jan 2019 14:50:33 +0100 Subject: [PATCH] Fixed #469: parsing of embedded file cover for ogg files tagged with MusicBrainz Picard --- api/funkwhale_api/music/metadata.py | 81 +++++++++++++++++++++++++--- api/tests/music/test_metadata.py | 23 +++++++- api/tests/music/with_cover.ogg | Bin 0 -> 40414 bytes changes/changelog.d/469.bugfix | 1 + 4 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 api/tests/music/with_cover.ogg create mode 100644 changes/changelog.d/469.bugfix diff --git a/api/funkwhale_api/music/metadata.py b/api/funkwhale_api/music/metadata.py index 9a61e67e1..ad8a6b6a5 100644 --- a/api/funkwhale_api/music/metadata.py +++ b/api/funkwhale_api/music/metadata.py @@ -1,8 +1,13 @@ +import base64 import datetime import logging -import mutagen import pendulum +import mutagen._util +import mutagen.oggtheora +import mutagen.oggvorbis +import mutagen.flac + from django import forms logger = logging.getLogger(__name__) @@ -83,6 +88,31 @@ def clean_flac_pictures(apic): return pictures +def clean_ogg_pictures(metadata_block_picture): + pictures = [] + for b64_data in [metadata_block_picture]: + + try: + data = base64.b64decode(b64_data) + except (TypeError, ValueError): + continue + + try: + picture = mutagen.flac.Picture(data) + except mutagen.flac.FLACError: + continue + + pictures.append( + { + "mimetype": picture.mime, + "content": picture.data, + "description": "", + "type": picture.type.real, + } + ) + return pictures + + def get_mp3_recording_id(f, k): try: return [t for t in f.tags.getall("UFID") if "musicbrainz.org" in t.owner][ @@ -197,6 +227,10 @@ CONF = { "musicbrainz_recordingid": {"field": "musicbrainz_trackid"}, "license": {}, "copyright": {}, + "pictures": { + "field": "metadata_block_picture", + "to_application": clean_ogg_pictures, + }, }, }, "OggTheora": { @@ -216,9 +250,8 @@ CONF = { "musicbrainz_artistid": {"field": "MusicBrainz Artist Id"}, "musicbrainz_albumartistid": {"field": "MusicBrainz Album Artist Id"}, "musicbrainz_recordingid": {"field": "MusicBrainz Track Id"}, - # somehow, I cannot successfully create an ogg theora file - # with the proper license field - # "license": {"field": "license"}, + "license": {}, + "copyright": {}, }, }, "MP3": { @@ -288,10 +321,11 @@ ALL_FIELDS = [ class Metadata(object): - def __init__(self, path): - self._file = mutagen.File(path) + def __init__(self, filething, kind=mutagen.File): + self._file = kind(filething) if self._file is None: - raise ValueError("Cannot parse metadata from {}".format(path)) + raise ValueError("Cannot parse metadata from {}".format(filething)) + self.fallback = self.load_fallback(filething, self._file) ft = self.get_file_type(self._file) try: self._conf = CONF[ft] @@ -301,7 +335,40 @@ class Metadata(object): def get_file_type(self, f): return f.__class__.__name__ + def load_fallback(self, filething, parent): + """ + In some situations, such as Ogg Theora files tagged with MusicBrainz Picard, + part of the tags are only available in the ogg vorbis comments + """ + try: + filething.seek(0) + except AttributeError: + pass + if isinstance(parent, mutagen.oggtheora.OggTheora): + try: + return Metadata(filething, kind=mutagen.oggvorbis.OggVorbis) + except (ValueError, mutagen._util.MutagenError): + raise + pass + def get(self, key, default=NODEFAULT): + try: + return self._get_from_self(key) + except TagNotFound: + if not self.fallback: + if default != NODEFAULT: + return default + else: + raise + else: + return self.fallback.get(key, default=default) + except UnsupportedTag: + if not self.fallback: + raise + else: + return self.fallback.get(key, default=default) + + def _get_from_self(self, key, default=NODEFAULT): try: field_conf = self._conf["fields"][key] except KeyError: diff --git a/api/tests/music/test_metadata.py b/api/tests/music/test_metadata.py index 4413f3a3b..5e5590d7d 100644 --- a/api/tests/music/test_metadata.py +++ b/api/tests/music/test_metadata.py @@ -1,9 +1,11 @@ import datetime import os import uuid - import pytest +import mutagen.oggtheora +import mutagen.oggvorbis + from funkwhale_api.music import metadata DATA_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -145,7 +147,7 @@ def test_can_get_metadata_from_id3_mp3_file(field, value): assert data.get(field) == value -@pytest.mark.parametrize("name", ["test.mp3", "sample.flac"]) +@pytest.mark.parametrize("name", ["test.mp3", "sample.flac", "with_cover.ogg"]) def test_can_get_pictures(name): path = os.path.join(DATA_DIR, name) data = metadata.Metadata(path) @@ -243,3 +245,20 @@ def test_metadata_all_ignore_parse_errors_false(mocker): mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure")) with pytest.raises(metadata.ParseError): data.all(ignore_parse_errors=False) + + +def test_metadata_fallback_ogg_theora(mocker): + path = os.path.join(DATA_DIR, "with_cover.ogg") + data = metadata.Metadata(path) + + assert isinstance(data._file, mutagen.oggtheora.OggTheora) + assert isinstance(data.fallback, metadata.Metadata) + assert isinstance(data.fallback._file, mutagen.oggvorbis.OggVorbis) + + expected_result = data.fallback.get("pictures") + fallback_get = mocker.spy(data.fallback, "get") + + assert expected_result is not None + assert data.get("pictures", "default") == expected_result + + fallback_get.assert_called_once_with("pictures", "default") diff --git a/api/tests/music/with_cover.ogg b/api/tests/music/with_cover.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ddd3ab7009e108474d6d15d08640672775b463a1 GIT binary patch literal 40414 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 literal 0 HcmV?d00001 diff --git a/changes/changelog.d/469.bugfix b/changes/changelog.d/469.bugfix new file mode 100644 index 000000000..0754dac6d --- /dev/null +++ b/changes/changelog.d/469.bugfix @@ -0,0 +1 @@ +Fixed parsing of embedded file cover for ogg files tagged with MusicBrainz (#469)