Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
jovuit
funkwhale
Commits
b38cec3f
Verified
Commit
b38cec3f
authored
Feb 04, 2020
by
Eliot Berriot
Browse files
Fixed a federation issue related to images
parent
93c371fe
Changes
3
Hide whitespace changes
Inline
Side-by-side
api/funkwhale_api/federation/serializers.py
View file @
b38cec3f
...
...
@@ -31,17 +31,9 @@ class TruncatedCharField(serializers.CharField):
return
v
class
LinkSerializer
(
jsonld
.
JsonLdSerializer
):
type
=
serializers
.
ChoiceField
(
choices
=
[
contexts
.
AS
.
Link
,
contexts
.
AS
.
Image
])
href
=
serializers
.
URLField
(
max_length
=
500
)
class
MediaSerializer
(
jsonld
.
JsonLdSerializer
):
mediaType
=
serializers
.
CharField
()
class
Meta
:
jsonld_mapping
=
{
"href"
:
jsonld
.
first_id
(
contexts
.
AS
.
href
),
"mediaType"
:
jsonld
.
first_val
(
contexts
.
AS
.
mediaType
),
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
allowed_mimetypes
=
kwargs
.
pop
(
"allowed_mimetypes"
,
[])
super
().
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -62,6 +54,43 @@ class LinkSerializer(jsonld.JsonLdSerializer):
)
class
LinkSerializer
(
MediaSerializer
):
type
=
serializers
.
ChoiceField
(
choices
=
[
contexts
.
AS
.
Link
])
href
=
serializers
.
URLField
(
max_length
=
500
)
class
Meta
:
jsonld_mapping
=
{
"href"
:
jsonld
.
first_id
(
contexts
.
AS
.
href
),
"mediaType"
:
jsonld
.
first_val
(
contexts
.
AS
.
mediaType
),
}
class
ImageSerializer
(
MediaSerializer
):
type
=
serializers
.
ChoiceField
(
choices
=
[
contexts
.
AS
.
Image
,
contexts
.
AS
.
Link
])
href
=
serializers
.
URLField
(
max_length
=
500
,
required
=
False
)
url
=
serializers
.
URLField
(
max_length
=
500
,
required
=
False
)
class
Meta
:
jsonld_mapping
=
{
"url"
:
jsonld
.
first_id
(
contexts
.
AS
.
url
),
"href"
:
jsonld
.
first_id
(
contexts
.
AS
.
href
),
"mediaType"
:
jsonld
.
first_val
(
contexts
.
AS
.
mediaType
),
}
def
validate
(
self
,
data
):
validated_data
=
super
().
validate
(
data
)
if
"url"
not
in
validated_data
:
try
:
validated_data
[
"url"
]
=
validated_data
[
"href"
]
except
KeyError
:
if
self
.
required
:
raise
serializers
.
ValidationError
(
"You need to provide a url or href"
)
return
validated_data
class
EndpointsSerializer
(
jsonld
.
JsonLdSerializer
):
sharedInbox
=
serializers
.
URLField
(
max_length
=
500
,
required
=
False
)
...
...
@@ -95,7 +124,7 @@ class ActorSerializer(jsonld.JsonLdSerializer):
following
=
serializers
.
URLField
(
max_length
=
500
,
required
=
False
,
allow_null
=
True
)
publicKey
=
PublicKeySerializer
(
required
=
False
)
endpoints
=
EndpointsSerializer
(
required
=
False
)
icon
=
Link
Serializer
(
icon
=
Image
Serializer
(
allowed_mimetypes
=
[
"image/*"
],
allow_null
=
True
,
required
=
False
)
...
...
@@ -202,7 +231,7 @@ class ActorSerializer(jsonld.JsonLdSerializer):
common_utils
.
attach_file
(
actor
,
"attachment_icon"
,
{
"url"
:
new_value
[
"
href
"
],
"mimetype"
:
new_value
[
"mediaType"
]}
{
"url"
:
new_value
[
"
url
"
],
"mimetype"
:
new_value
[
"mediaType"
]}
if
new_value
else
None
,
)
...
...
@@ -853,7 +882,7 @@ def include_image(repr, attachment, field="image"):
if
attachment
:
repr
[
field
]
=
{
"type"
:
"Image"
,
"
href
"
:
attachment
.
download_url_original
,
"
url
"
:
attachment
.
download_url_original
,
"mediaType"
:
attachment
.
mimetype
or
"image/jpeg"
,
}
else
:
...
...
@@ -915,14 +944,14 @@ class MusicEntitySerializer(jsonld.JsonLdSerializer):
if
(
instance
.
attachment_cover
and
instance
.
attachment_cover
.
url
==
attachment_cover
[
"
href
"
]
and
instance
.
attachment_cover
.
url
==
attachment_cover
[
"
url
"
]
):
# we already have the proper attachment
return
validated_data
# create the attachment by hand so it can be attached as the cover
validated_data
[
"attachment_cover"
]
=
common_models
.
Attachment
.
objects
.
create
(
mimetype
=
attachment_cover
[
"mediaType"
],
url
=
attachment_cover
[
"
href
"
],
url
=
attachment_cover
[
"
url
"
],
actor
=
instance
.
attributed_to
,
)
return
validated_data
...
...
@@ -938,7 +967,7 @@ class MusicEntitySerializer(jsonld.JsonLdSerializer):
class
ArtistSerializer
(
MusicEntitySerializer
):
image
=
Link
Serializer
(
image
=
Image
Serializer
(
allowed_mimetypes
=
[
"image/*"
],
allow_null
=
True
,
required
=
False
)
updateable_fields
=
[
...
...
@@ -982,7 +1011,7 @@ class AlbumSerializer(MusicEntitySerializer):
released
=
serializers
.
DateField
(
allow_null
=
True
,
required
=
False
)
artists
=
serializers
.
ListField
(
child
=
ArtistSerializer
(),
min_length
=
1
)
# XXX: 1.0 rename to image
cover
=
Link
Serializer
(
cover
=
Image
Serializer
(
allowed_mimetypes
=
[
"image/*"
],
allow_null
=
True
,
required
=
False
)
updateable_fields
=
[
...
...
@@ -1045,7 +1074,7 @@ class TrackSerializer(MusicEntitySerializer):
album
=
AlbumSerializer
()
license
=
serializers
.
URLField
(
allow_null
=
True
,
required
=
False
)
copyright
=
serializers
.
CharField
(
allow_null
=
True
,
required
=
False
)
image
=
Link
Serializer
(
image
=
Image
Serializer
(
allowed_mimetypes
=
[
"image/*"
],
allow_null
=
True
,
required
=
False
)
...
...
api/funkwhale_api/music/tasks.py
View file @
b38cec3f
...
...
@@ -302,7 +302,12 @@ def process_upload(upload, update_denormalization=True):
def
get_cover
(
obj
,
field
):
cover
=
obj
.
get
(
field
)
if
cover
:
return
{
"mimetype"
:
cover
[
"mediaType"
],
"url"
:
cover
[
"href"
]}
try
:
url
=
cover
[
"url"
]
except
KeyError
:
url
=
cover
[
"href"
]
return
{
"mimetype"
:
cover
[
"mediaType"
],
"url"
:
url
}
def
federation_audio_track_to_metadata
(
payload
,
references
):
...
...
api/tests/federation/test_serializers.py
View file @
b38cec3f
...
...
@@ -39,7 +39,7 @@ def test_actor_serializer_from_ap(db):
"icon"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
"https://image.example/image.png"
,
"
url
"
:
"https://image.example/image.png"
,
},
}
...
...
@@ -65,7 +65,7 @@ def test_actor_serializer_from_ap(db):
assert
actor
.
private_key
is
None
assert
actor
.
public_key
==
payload
[
"publicKey"
][
"publicKeyPem"
]
assert
actor
.
domain_id
==
"test.federation"
assert
actor
.
attachment_icon
.
url
==
payload
[
"icon"
][
"
href
"
]
assert
actor
.
attachment_icon
.
url
==
payload
[
"icon"
][
"
url
"
]
assert
actor
.
attachment_icon
.
mimetype
==
payload
[
"icon"
][
"mediaType"
]
...
...
@@ -139,7 +139,7 @@ def test_actor_serializer_to_ap(factories):
expected
[
"icon"
]
=
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
utils
.
full_url
(
ac
.
attachment_icon
.
file
.
url
),
"
url
"
:
utils
.
full_url
(
ac
.
attachment_icon
.
file
.
url
),
}
serializer
=
serializers
.
ActorSerializer
(
ac
)
...
...
@@ -595,7 +595,7 @@ def test_activity_pub_artist_serializer_to_ap(factories):
"image"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
utils
.
full_url
(
artist
.
attachment_cover
.
file
.
url
),
"
url
"
:
utils
.
full_url
(
artist
.
attachment_cover
.
file
.
url
),
},
"tag"
:
[
{
"type"
:
"Hashtag"
,
"name"
:
"#Punk"
},
...
...
@@ -626,7 +626,7 @@ def test_activity_pub_album_serializer_to_ap(factories):
"image"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
utils
.
full_url
(
album
.
attachment_cover
.
file
.
url
),
"
url
"
:
utils
.
full_url
(
album
.
attachment_cover
.
file
.
url
),
},
"musicbrainzId"
:
album
.
mbid
,
"published"
:
album
.
creation_date
.
isoformat
(),
...
...
@@ -661,7 +661,7 @@ def test_activity_pub_artist_serializer_from_ap_update(factories, faker):
"attributedTo"
:
artist
.
attributed_to
.
fid
,
"mediaType"
:
"text/html"
,
"content"
:
common_utils
.
render_html
(
faker
.
sentence
(),
"text/html"
),
"image"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
faker
.
url
()},
"image"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
url
"
:
faker
.
url
()},
"tag"
:
[
{
"type"
:
"Hashtag"
,
"name"
:
"#Punk"
},
{
"type"
:
"Hashtag"
,
"name"
:
"#Rock"
},
...
...
@@ -677,7 +677,7 @@ def test_activity_pub_artist_serializer_from_ap_update(factories, faker):
assert
artist
.
name
==
payload
[
"name"
]
assert
str
(
artist
.
mbid
)
==
payload
[
"musicbrainzId"
]
assert
artist
.
attachment_cover
.
url
==
payload
[
"image"
][
"
href
"
]
assert
artist
.
attachment_cover
.
url
==
payload
[
"image"
][
"
url
"
]
assert
artist
.
attachment_cover
.
mimetype
==
payload
[
"image"
][
"mediaType"
]
assert
artist
.
description
.
text
==
payload
[
"content"
]
assert
artist
.
description
.
content_type
==
"text/html"
...
...
@@ -767,7 +767,7 @@ def test_activity_pub_track_serializer_to_ap(factories):
"image"
:
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
utils
.
full_url
(
track
.
attachment_cover
.
file
.
url
),
"
url
"
:
utils
.
full_url
(
track
.
attachment_cover
.
file
.
url
),
},
}
serializer
=
serializers
.
TrackSerializer
(
track
)
...
...
@@ -797,8 +797,8 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
"content"
:
"Hello there"
,
"attributedTo"
:
track_attributed_to
.
fid
,
"image"
:
{
"type"
:
"
Link
"
,
"
href
"
:
"https://cover.image/track.png"
,
"type"
:
"
Image
"
,
"
url
"
:
"https://cover.image/track.png"
,
"mediaType"
:
"image/png"
,
},
"album"
:
{
...
...
@@ -829,8 +829,8 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
"attributedTo"
:
album_artist_attributed_to
.
fid
,
"tag"
:
[{
"type"
:
"Hashtag"
,
"name"
:
"AlbumArtistTag"
}],
"image"
:
{
"type"
:
"
Link
"
,
"
href
"
:
"https://cover.image/album-artist.png"
,
"type"
:
"
Image
"
,
"
url
"
:
"https://cover.image/album-artist.png"
,
"mediaType"
:
"image/png"
,
},
}
...
...
@@ -848,8 +848,8 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
"published"
:
published
.
isoformat
(),
"tag"
:
[{
"type"
:
"Hashtag"
,
"name"
:
"ArtistTag"
}],
"image"
:
{
"type"
:
"
Link
"
,
"
href
"
:
"https://cover.image/artist.png"
,
"type"
:
"
Image
"
,
"
url
"
:
"https://cover.image/artist.png"
,
"mediaType"
:
"image/png"
,
},
}
...
...
@@ -877,7 +877,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
assert
str
(
track
.
mbid
)
==
data
[
"musicbrainzId"
]
assert
track
.
description
.
text
==
data
[
"content"
]
assert
track
.
description
.
content_type
==
"text/html"
assert
track
.
attachment_cover
.
url
==
data
[
"image"
][
"
href
"
]
assert
track
.
attachment_cover
.
url
==
data
[
"image"
][
"
url
"
]
assert
track
.
attachment_cover
.
mimetype
==
data
[
"image"
][
"mediaType"
]
assert
album
.
from_activity
==
activity
...
...
@@ -900,7 +900,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
assert
artist
.
attributed_to
==
artist_attributed_to
assert
artist
.
description
.
text
==
data
[
"artists"
][
0
][
"content"
]
assert
artist
.
description
.
content_type
==
data
[
"artists"
][
0
][
"mediaType"
]
assert
artist
.
attachment_cover
.
url
==
data
[
"artists"
][
0
][
"image"
][
"
href
"
]
assert
artist
.
attachment_cover
.
url
==
data
[
"artists"
][
0
][
"image"
][
"
url
"
]
assert
artist
.
attachment_cover
.
mimetype
==
data
[
"artists"
][
0
][
"image"
][
"mediaType"
]
assert
album_artist
.
from_activity
==
activity
...
...
@@ -915,8 +915,7 @@ def test_activity_pub_track_serializer_from_ap(factories, r_mock, mocker):
==
data
[
"album"
][
"artists"
][
0
][
"mediaType"
]
)
assert
(
album_artist
.
attachment_cover
.
url
==
data
[
"album"
][
"artists"
][
0
][
"image"
][
"href"
]
album_artist
.
attachment_cover
.
url
==
data
[
"album"
][
"artists"
][
0
][
"image"
][
"url"
]
)
assert
(
album_artist
.
attachment_cover
.
mimetype
...
...
@@ -949,7 +948,7 @@ def test_activity_pub_track_serializer_from_ap_update(factories, r_mock, mocker,
"attributedTo"
:
track_attributed_to
.
fid
,
"album"
:
serializers
.
AlbumSerializer
(
track
.
album
).
data
,
"artists"
:
[
serializers
.
ArtistSerializer
(
track
.
artist
).
data
],
"image"
:
{
"type"
:
"
Link
"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
faker
.
url
()},
"image"
:
{
"type"
:
"
Image
"
,
"mediaType"
:
"image/jpeg"
,
"
url
"
:
faker
.
url
()},
"tag"
:
[
{
"type"
:
"Hashtag"
,
"name"
:
"#Hello"
},
# Ensure we can handle tags without a leading #
...
...
@@ -970,7 +969,7 @@ def test_activity_pub_track_serializer_from_ap_update(factories, r_mock, mocker,
assert
track
.
description
.
content_type
==
"text/html"
assert
track
.
description
.
text
==
"hello there"
assert
str
(
track
.
mbid
)
==
data
[
"musicbrainzId"
]
assert
track
.
attachment_cover
.
url
==
data
[
"image"
][
"
href
"
]
assert
track
.
attachment_cover
.
url
==
data
[
"image"
][
"
url
"
]
assert
track
.
attachment_cover
.
mimetype
==
data
[
"image"
][
"mediaType"
]
set_tags
.
assert_called_once_with
(
track
,
*
[
"Hello"
,
"World"
])
...
...
@@ -1159,7 +1158,7 @@ def test_local_actor_serializer_to_ap(factories):
expected
[
"icon"
]
=
{
"type"
:
"Image"
,
"mediaType"
:
"image/jpeg"
,
"
href
"
:
utils
.
full_url
(
ac
.
attachment_icon
.
file
.
url
),
"
url
"
:
utils
.
full_url
(
ac
.
attachment_icon
.
file
.
url
),
}
serializer
=
serializers
.
ActorSerializer
(
ac
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment