From a119a5d90a1aad49c7b66d0604ad5ef2323486d0 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Fri, 13 Mar 2020 15:26:11 +0100
Subject: [PATCH] See #170: fixed several feed parsing issues

---
 api/funkwhale_api/audio/serializers.py        | 18 +++++++++++++-----
 api/funkwhale_api/common/utils.py             |  5 +++++
 api/funkwhale_api/music/utils.py              |  5 ++++-
 front/src/components/common/HumanDuration.vue |  2 +-
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/api/funkwhale_api/audio/serializers.py b/api/funkwhale_api/audio/serializers.py
index 2e412c3e98..a8ba29523d 100644
--- a/api/funkwhale_api/audio/serializers.py
+++ b/api/funkwhale_api/audio/serializers.py
@@ -589,13 +589,21 @@ def get_cached_upload(uploads, expected_track_uuid):
             return upload
 
 
+class PermissiveIntegerField(serializers.IntegerField):
+    def to_internal_value(self, v):
+        try:
+            return super().to_internal_value(v)
+        except serializers.ValidationError:
+            return self.default
+
+
 class RssFeedItemSerializer(serializers.Serializer):
     id = serializers.CharField()
     title = serializers.CharField()
     rights = serializers.CharField(required=False, allow_blank=True)
     itunes_season = serializers.IntegerField(required=False)
-    itunes_episode = serializers.IntegerField(required=False)
-    itunes_duration = ItunesDurationField()
+    itunes_episode = PermissiveIntegerField(required=False, default=None)
+    itunes_duration = ItunesDurationField(required=False)
     links = serializers.ListField()
     tags = serializers.ListField(required=False)
     summary_detail = serializers.DictField(required=False)
@@ -627,12 +635,12 @@ class RssFeedItemSerializer(serializers.Serializer):
             if row.get("rel") != "enclosure":
                 continue
             try:
-                size = int(row.get("length"))
+                size = int(row.get("length", 0)) or None
             except (TypeError, ValueError):
                 raise serializers.ValidationError("Invalid size")
 
             data["audio"] = {
-                "mimetype": row["type"],
+                "mimetype": common_utils.get_audio_mimetype(row["type"]),
                 "size": size,
                 "source": row["href"],
             }
@@ -703,7 +711,7 @@ class RssFeedItemSerializer(serializers.Serializer):
             "source": validated_data["links"]["audio"]["source"],
             "size": validated_data["links"]["audio"]["size"],
             "mimetype": validated_data["links"]["audio"]["mimetype"],
-            "duration": validated_data["itunes_duration"],
+            "duration": validated_data.get("itunes_duration"),
             "import_status": "finished",
             "library": channel.library,
         }
diff --git a/api/funkwhale_api/common/utils.py b/api/funkwhale_api/common/utils.py
index 49719e168e..917bc13b76 100644
--- a/api/funkwhale_api/common/utils.py
+++ b/api/funkwhale_api/common/utils.py
@@ -396,3 +396,8 @@ def get_mimetype_from_ext(path):
         "gif": "image/gif",
     }
     return match.get(ext)
+
+
+def get_audio_mimetype(mt):
+    aliases = {"audio/x-mp3": "audio/mpeg", "audio/mpeg3": "audio/mpeg"}
+    return aliases.get(mt, mt)
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index 5097db9ab9..599e4ae4d2 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -37,10 +37,13 @@ def compute_status(jobs):
 
 
 AUDIO_EXTENSIONS_AND_MIMETYPE = [
+    # keep the most correct mimetype for each extension at the bottom
+    ("mp3", "audio/mpeg3"),
+    ("mp3", "audio/x-mp3"),
+    ("mp3", "audio/mpeg"),
     ("ogg", "video/ogg"),
     ("ogg", "audio/ogg"),
     ("opus", "audio/opus"),
-    ("mp3", "audio/mpeg"),
     ("aac", "audio/x-m4a"),
     ("m4a", "audio/x-m4a"),
     ("flac", "audio/x-flac"),
diff --git a/front/src/components/common/HumanDuration.vue b/front/src/components/common/HumanDuration.vue
index ef70ff400f..3fc1ffdab3 100644
--- a/front/src/components/common/HumanDuration.vue
+++ b/front/src/components/common/HumanDuration.vue
@@ -1,6 +1,6 @@
 <template>
   <time :datetime="`${duration}s`">
-    <template v-if="durationObj.hours">{{ durationObj.hours|padDuration }}</template>{{ durationObj.minutes|padDuration }}:{{ durationObj.seconds|padDuration }}
+    <template v-if="durationObj.hours">{{ durationObj.hours|padDuration }}:</template>{{ durationObj.minutes|padDuration }}:{{ durationObj.seconds|padDuration }}
   </time>
 
 </template>
-- 
GitLab