Skip to content
Snippets Groups Projects
Commit 59cead42 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '622-deezer-date' into 'develop'

Fix #622: More resilient date parsing during audio import, will not crash anymore on

Closes #622

See merge request !479
parents 0c64b14f 8e84e2bf
No related branches found
No related tags found
No related merge requests found
import datetime
import logging
import mutagen
import pendulum
from django import forms
logger = logging.getLogger(__name__)
NODEFAULT = object()
......@@ -14,6 +17,10 @@ class UnsupportedTag(KeyError):
pass
class ParseError(ValueError):
pass
def get_id3_tag(f, k):
if k == "pictures":
return f.tags.getall("APIC")
......@@ -103,8 +110,22 @@ class FirstUUIDField(forms.UUIDField):
def get_date(value):
parsed = pendulum.parse(str(value))
return datetime.date(parsed.year, parsed.month, parsed.day)
ADDITIONAL_FORMATS = ["%Y-%d-%m %H:%M"] # deezer date format
try:
parsed = pendulum.parse(str(value))
return datetime.date(parsed.year, parsed.month, parsed.day)
except pendulum.exceptions.ParserError:
pass
for date_format in ADDITIONAL_FORMATS:
try:
parsed = datetime.datetime.strptime(value, date_format)
except ValueError:
continue
else:
return datetime.date(parsed.year, parsed.month, parsed.day)
raise ParseError("{} cannot be parsed as a date".format(value))
def split_and_return_first(separator):
......@@ -275,7 +296,7 @@ class Metadata(object):
v = field.to_python(v)
return v
def all(self):
def all(self, ignore_parse_errors=True):
"""
Return a dict containing all metadata of the file
"""
......@@ -286,6 +307,11 @@ class Metadata(object):
data[field] = self.get(field, None)
except (TagNotFound, forms.ValidationError):
data[field] = None
except ParseError as e:
if not ignore_parse_errors:
raise
logger.warning("Unparsable field {}: {}".format(field, str(e)))
data[field] = None
return data
......
......@@ -196,7 +196,31 @@ def test_mbid_clean_keeps_only_first(field_name):
@pytest.mark.parametrize(
"raw,expected",
[("2017", datetime.date(2017, 1, 1)), ("2017-12-31", datetime.date(2017, 12, 31))],
[
("2017", datetime.date(2017, 1, 1)),
("2017-12-31", datetime.date(2017, 12, 31)),
("2017-14-01 01:32", datetime.date(2017, 1, 14)), # deezer format
],
)
def test_date_parsing(raw, expected):
assert metadata.get_date(raw) == expected
def test_date_parsing_failure():
with pytest.raises(metadata.ParseError):
metadata.get_date("noop")
def test_metadata_all_ignore_parse_errors_true(mocker):
path = os.path.join(DATA_DIR, "sample.flac")
data = metadata.Metadata(path)
mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
assert data.all()["date"] is None
def test_metadata_all_ignore_parse_errors_false(mocker):
path = os.path.join(DATA_DIR, "sample.flac")
data = metadata.Metadata(path)
mocker.patch.object(data, "get", side_effect=metadata.ParseError("Failure"))
with pytest.raises(metadata.ParseError):
data.all(ignore_parse_errors=False)
More resilient date parsing during audio import, will not crash anymore on
invalid dates (#622)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment