From a2c52abb4fa1befec5cf69412046b89af12ab6b8 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Wed, 24 Apr 2019 14:26:12 +0200
Subject: [PATCH] See #565: fixed path issues with external storage

---
 api/funkwhale_api/federation/serializers.py |  2 +-
 api/funkwhale_api/music/models.py           | 20 ++++++++++++++++++++
 api/funkwhale_api/users/models.py           | 10 ++++++++++
 api/tests/federation/test_serializers.py    |  2 +-
 api/tests/federation/test_tasks.py          | 10 +++++-----
 api/tests/music/test_music.py               |  4 ----
 api/tests/music/test_tasks.py               |  2 +-
 api/tests/music/test_views.py               |  2 +-
 8 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py
index 8a2fcefeaa..215df7b3a1 100644
--- a/api/funkwhale_api/federation/serializers.py
+++ b/api/funkwhale_api/federation/serializers.py
@@ -129,7 +129,7 @@ class ActorSerializer(jsonld.JsonLdSerializer):
             if instance.user.avatar:
                 ret["icon"] = {
                     "type": "Image",
-                    "mediaType": mimetypes.guess_type(instance.user.avatar.path)[0],
+                    "mediaType": mimetypes.guess_type(instance.user.avatar_path)[0],
                     "url": utils.full_url(instance.user.avatar.crop["400x400"].url),
                 }
         except ObjectDoesNotExist:
diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 5f42ed7a3b..fdc4f87f8b 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -840,6 +840,16 @@ class Upload(models.Model):
             return
         return self.source.lstrip("file://")
 
+    @property
+    def audio_file_path(self):
+        if not self.audio_file:
+            return None
+        try:
+            return self.audio_file.path
+        except NotImplementedError:
+            # external storage
+            return self.audio_file.name
+
 
 MIMETYPE_CHOICES = [(mt, ext) for ext, mt in utils.AUDIO_EXTENSIONS_AND_MIMETYPE]
 
@@ -862,6 +872,16 @@ class UploadVersion(models.Model):
     def filename(self):
         return self.upload.filename
 
+    @property
+    def audio_file_path(self):
+        if not self.audio_file:
+            return None
+        try:
+            return self.audio_file.path
+        except NotImplementedError:
+            # external storage
+            return self.audio_file.name
+
 
 IMPORT_STATUS_CHOICES = (
     ("pending", "Pending"),
diff --git a/api/funkwhale_api/users/models.py b/api/funkwhale_api/users/models.py
index d67dff4532..8ef06c8719 100644
--- a/api/funkwhale_api/users/models.py
+++ b/api/funkwhale_api/users/models.py
@@ -234,6 +234,16 @@ class User(AbstractUser):
     def full_username(self):
         return "{}@{}".format(self.username, settings.FEDERATION_HOSTNAME)
 
+    @property
+    def avatar_path(self):
+        if not self.avatar:
+            return None
+        try:
+            return self.avatar.path
+        except NotImplementedError:
+            # external storage
+            return self.avatar.name
+
 
 def generate_code(length=10):
     return "".join(
diff --git a/api/tests/federation/test_serializers.py b/api/tests/federation/test_serializers.py
index 6872947f7f..adab9b6ec0 100644
--- a/api/tests/federation/test_serializers.py
+++ b/api/tests/federation/test_serializers.py
@@ -701,7 +701,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
 
     assert album.from_activity == activity
     assert album.cover.read() == b"coucou"
-    assert album.cover.path.endswith(".png")
+    assert album.cover_path.endswith(".png")
     assert album.title == data["album"]["name"]
     assert album.fid == data["album"]["id"]
     assert str(album.mbid) == data["album"]["musicbrainzId"]
diff --git a/api/tests/federation/test_tasks.py b/api/tests/federation/test_tasks.py
index 5cfd228e5d..98b4eff879 100644
--- a/api/tests/federation/test_tasks.py
+++ b/api/tests/federation/test_tasks.py
@@ -26,10 +26,10 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
     # local upload, should not be cleaned
     upload4 = factories["music.Upload"](library__actor__local=True, accessed_date=None)
 
-    path1 = upload1.audio_file.path
-    path2 = upload2.audio_file.path
-    path3 = upload3.audio_file.path
-    path4 = upload4.audio_file.path
+    path1 = upload1.audio_file_path
+    path2 = upload2.audio_file_path
+    path3 = upload3.audio_file_path
+    path4 = upload4.audio_file_path
 
     tasks.clean_music_cache()
 
@@ -66,7 +66,7 @@ def test_clean_federation_music_cache_orphaned(settings, preferences, factories)
     upload.refresh_from_db()
 
     assert bool(upload.audio_file) is True
-    assert os.path.exists(upload.audio_file.path) is True
+    assert os.path.exists(upload.audio_file_path) is True
     assert os.path.exists(remove_path) is False
 
 
diff --git a/api/tests/music/test_music.py b/api/tests/music/test_music.py
index ab5853f14d..10d281071a 100644
--- a/api/tests/music/test_music.py
+++ b/api/tests/music/test_music.py
@@ -1,7 +1,5 @@
 import datetime
 
-import pytest
-
 from funkwhale_api.federation import utils as federation_utils
 from funkwhale_api.music import models
 
@@ -40,8 +38,6 @@ def test_can_create_album_from_api(artists, albums, mocker, db):
 
     assert album.mbid, data["id"]
     assert album.title, "Hypnotize"
-    with pytest.raises(ValueError):
-        assert album.cover.path is not None
     assert album.release_date, datetime.date(2005, 1, 1)
     assert album.artist.name, "System of a Down"
     assert album.artist.mbid, data["artist-credit"][0]["artist"]["id"]
diff --git a/api/tests/music/test_tasks.py b/api/tests/music/test_tasks.py
index 028b10b76f..78f4622bab 100644
--- a/api/tests/music/test_tasks.py
+++ b/api/tests/music/test_tasks.py
@@ -255,7 +255,7 @@ def test_can_create_track_from_file_metadata_federation(factories, mocker, r_moc
     assert track.creation_date == metadata["fdate"]
     assert track.position == 4
     assert track.album.cover.read() == b"coucou"
-    assert track.album.cover.path.endswith(".png")
+    assert track.album.cover_path.endswith(".png")
     assert track.album.fid == metadata["album"]["fid"]
     assert track.album.title == metadata["album"]["title"]
     assert track.album.creation_date == metadata["album"]["fdate"]
diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py
index ed38afcda5..32d95e14fc 100644
--- a/api/tests/music/test_views.py
+++ b/api/tests/music/test_views.py
@@ -402,7 +402,7 @@ def test_handle_serve_create_mp3_version(factories, now):
     assert version.mimetype == "audio/mpeg"
     assert version.accessed_date == now
     assert version.bitrate == upload.bitrate
-    assert version.audio_file.path.endswith(".mp3")
+    assert version.audio_file_path.endswith(".mp3")
     assert version.size == version.audio_file.size
     assert magic.from_buffer(version.audio_file.read(), mime=True) == "audio/mpeg"
 
-- 
GitLab