kopia lustrzana https://gitlab.com/jaywink/federation
Merge branch 'jaywink/set-activitypub-profile-icon' into 'master'
Set profile icon properly for ActivityPub profiles See merge request jaywink/federation!147merge-requests/149/head
commit
14116923be
|
@ -2,11 +2,14 @@ import logging
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
import attr
|
||||||
|
|
||||||
from federation.entities.activitypub.constants import (
|
from federation.entities.activitypub.constants import (
|
||||||
CONTEXTS_DEFAULT, CONTEXT_MANUALLY_APPROVES_FOLLOWERS, CONTEXT_SENSITIVE, CONTEXT_HASHTAG,
|
CONTEXTS_DEFAULT, CONTEXT_MANUALLY_APPROVES_FOLLOWERS, CONTEXT_SENSITIVE, CONTEXT_HASHTAG,
|
||||||
CONTEXT_LD_SIGNATURES)
|
CONTEXT_LD_SIGNATURES)
|
||||||
from federation.entities.activitypub.enums import ActorType, ObjectType, ActivityType
|
from federation.entities.activitypub.enums import ActorType, ObjectType, ActivityType
|
||||||
from federation.entities.activitypub.mixins import ActivitypubObjectMixin, ActivitypubActorMixin
|
from federation.entities.activitypub.mixins import ActivitypubObjectMixin, ActivitypubActorMixin
|
||||||
|
from federation.entities.activitypub.objects import ImageObject
|
||||||
from federation.entities.base import Profile, Post, Follow, Accept
|
from federation.entities.base import Profile, Post, Follow, Accept
|
||||||
from federation.outbound import handle_send
|
from federation.outbound import handle_send
|
||||||
from federation.types import UserType
|
from federation.types import UserType
|
||||||
|
@ -168,5 +171,8 @@ class ActivitypubProfile(ActivitypubActorMixin, Profile):
|
||||||
if self.raw_content:
|
if self.raw_content:
|
||||||
as2['summary'] = self.raw_content
|
as2['summary'] = self.raw_content
|
||||||
if self.image_urls.get('large'):
|
if self.image_urls.get('large'):
|
||||||
as2['icon'] = self.image_urls.get('large')
|
try:
|
||||||
|
as2['icon'] = attr.asdict(ImageObject(url=self.image_urls.get('large')))
|
||||||
|
except Exception as ex:
|
||||||
|
logger.warning("ActivitypubProfile.to_as2 - failed to set profile icon: %s", ex)
|
||||||
return as2
|
return as2
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import attr
|
||||||
|
|
||||||
|
from federation.utils.network import fetch_content_type
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class ImageObject:
|
||||||
|
"""
|
||||||
|
An Image object for AS2 serialization.
|
||||||
|
"""
|
||||||
|
_allowed_types = (
|
||||||
|
"image/jpeg",
|
||||||
|
"image/png",
|
||||||
|
"image/gif",
|
||||||
|
)
|
||||||
|
url: str = attr.ib()
|
||||||
|
type: str = attr.ib(default="Image")
|
||||||
|
mediaType: str = attr.ib()
|
||||||
|
|
||||||
|
@mediaType.default
|
||||||
|
def cache_media_type(self):
|
||||||
|
content_type = fetch_content_type(self.url)
|
||||||
|
if content_type in self._allowed_types:
|
||||||
|
return content_type
|
||||||
|
return ""
|
|
@ -79,7 +79,8 @@ class TestEntitiesConvertToAS2:
|
||||||
'published': '2019-04-27T00:00:00',
|
'published': '2019-04-27T00:00:00',
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_profile_to_as2(self, activitypubprofile):
|
@patch("federation.entities.activitypub.objects.fetch_content_type", return_value="image/jpeg")
|
||||||
|
def test_profile_to_as2(self, mock_fetch, activitypubprofile):
|
||||||
result = activitypubprofile.to_as2()
|
result = activitypubprofile.to_as2()
|
||||||
assert result == {
|
assert result == {
|
||||||
"@context": CONTEXTS_DEFAULT + [
|
"@context": CONTEXTS_DEFAULT + [
|
||||||
|
@ -104,7 +105,11 @@ class TestEntitiesConvertToAS2:
|
||||||
"type": "Person",
|
"type": "Person",
|
||||||
"url": "https://example.com/bob-bobertson",
|
"url": "https://example.com/bob-bobertson",
|
||||||
"summary": "foobar",
|
"summary": "foobar",
|
||||||
"icon": "urllarge",
|
"icon": {
|
||||||
|
"type": "Image",
|
||||||
|
"url": "urllarge",
|
||||||
|
"mediaType": "image/jpeg",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import datetime
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
from typing import Tuple
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from ipdata import ipdata
|
from ipdata import ipdata
|
||||||
|
@ -18,6 +18,18 @@ logger = logging.getLogger("federation")
|
||||||
USER_AGENT = "python/federation/%s" % __version__
|
USER_AGENT = "python/federation/%s" % __version__
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_content_type(url: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Fetch the HEAD of the remote url to determine the content type.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
response = requests.head(url, headers={'user-agent': USER_AGENT}, timeout=10)
|
||||||
|
except RequestException as ex:
|
||||||
|
logger.warning("fetch_content_type - %s when fetching url %s", ex, url)
|
||||||
|
else:
|
||||||
|
return response.headers.get('Content-Type')
|
||||||
|
|
||||||
|
|
||||||
def fetch_country_by_ip(ip):
|
def fetch_country_by_ip(ip):
|
||||||
"""
|
"""
|
||||||
Fetches country code by IP
|
Fetches country code by IP
|
||||||
|
|
Ładowanie…
Reference in New Issue