mirror of
https://git.linux-kernel.at/oliver/ivatar.git
synced 2025-11-20 06:58:02 +00:00
Add BlueskyProxy + handle requests
This commit is contained in:
136
ivatar/views.py
136
ivatar/views.py
@@ -5,7 +5,7 @@ views under /
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from os import path
|
from os import path
|
||||||
import hashlib
|
import hashlib
|
||||||
from ivatar.utils import urlopen
|
from ivatar.utils import urlopen, Bluesky
|
||||||
from urllib.error import HTTPError, URLError
|
from urllib.error import HTTPError, URLError
|
||||||
from ssl import SSLError
|
from ssl import SSLError
|
||||||
from django.views.generic.base import TemplateView, View
|
from django.views.generic.base import TemplateView, View
|
||||||
@@ -121,7 +121,8 @@ class AvatarImageView(TemplateView):
|
|||||||
if CACHE_RESPONSE:
|
if CACHE_RESPONSE:
|
||||||
centry = caches["filesystem"].get(uri)
|
centry = caches["filesystem"].get(uri)
|
||||||
if centry:
|
if centry:
|
||||||
# For DEBUG purpose only print('Cached entry for %s' % uri)
|
# For DEBUG purpose only
|
||||||
|
# print('Cached entry for %s' % uri)
|
||||||
return HttpResponse(
|
return HttpResponse(
|
||||||
centry["content"],
|
centry["content"],
|
||||||
content_type=centry["content_type"],
|
content_type=centry["content_type"],
|
||||||
@@ -190,6 +191,12 @@ class AvatarImageView(TemplateView):
|
|||||||
except Exception: # pylint: disable=bare-except
|
except Exception: # pylint: disable=bare-except
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Handle the special case of Bluesky
|
||||||
|
if obj:
|
||||||
|
if obj.bluesky_handle:
|
||||||
|
return HttpResponseRedirect(
|
||||||
|
reverse_lazy("blueskyproxy", args=[kwargs["digest"]])
|
||||||
|
)
|
||||||
# If that mail/openid doesn't exist, or has no photo linked to it
|
# If that mail/openid doesn't exist, or has no photo linked to it
|
||||||
if not obj or not obj.photo or forcedefault:
|
if not obj or not obj.photo or forcedefault:
|
||||||
gravatar_url = (
|
gravatar_url = (
|
||||||
@@ -448,6 +455,131 @@ class GravatarProxyView(View):
|
|||||||
return redir_default(default)
|
return redir_default(default)
|
||||||
|
|
||||||
|
|
||||||
|
class BlueskyProxyView(View):
|
||||||
|
"""
|
||||||
|
Proxy request to Bluesky and return the image from there
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get(
|
||||||
|
self, request, *args, **kwargs
|
||||||
|
): # pylint: disable=too-many-branches,too-many-statements,too-many-locals,no-self-use,unused-argument,too-many-return-statements
|
||||||
|
"""
|
||||||
|
Override get from parent class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def redir_default(default=None):
|
||||||
|
url = (
|
||||||
|
reverse_lazy("avatar_view", args=[kwargs["digest"]])
|
||||||
|
+ "?s=%i" % size
|
||||||
|
+ "&forcedefault=y"
|
||||||
|
)
|
||||||
|
if default is not None:
|
||||||
|
url += "&default=%s" % default
|
||||||
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
|
size = get_size(request)
|
||||||
|
print(size)
|
||||||
|
blueskyimagedata = None
|
||||||
|
default = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
if str(request.GET["default"]) != "None":
|
||||||
|
default = request.GET["default"]
|
||||||
|
except Exception: # pylint: disable=bare-except
|
||||||
|
pass
|
||||||
|
|
||||||
|
identity = None
|
||||||
|
|
||||||
|
# First check for email, as this is the most common
|
||||||
|
try:
|
||||||
|
identity = ConfirmedEmail.objects.filter(
|
||||||
|
Q(digest=kwargs["digest"]) | Q(digest_sha256=kwargs["digest"])
|
||||||
|
).first()
|
||||||
|
except Exception as exc:
|
||||||
|
print(exc)
|
||||||
|
|
||||||
|
# If no identity is found in the email table, try the openid table
|
||||||
|
if not identity:
|
||||||
|
try:
|
||||||
|
identity = ConfirmedOpenId.objects.filter(
|
||||||
|
Q(digest=kwargs["digest"])
|
||||||
|
| Q(alt_digest1=kwargs["digest"])
|
||||||
|
| Q(alt_digest2=kwargs["digest"])
|
||||||
|
| Q(alt_digest3=kwargs["digest"])
|
||||||
|
).first()
|
||||||
|
except Exception as exc:
|
||||||
|
print(exc)
|
||||||
|
|
||||||
|
# If still no identity is found, redirect to the default
|
||||||
|
if not identity:
|
||||||
|
return redir_default(default)
|
||||||
|
|
||||||
|
bs = Bluesky()
|
||||||
|
bluesky_url = None
|
||||||
|
# Try with the cache first
|
||||||
|
try:
|
||||||
|
if cache.get(identity.bluesky_handle):
|
||||||
|
bluesky_url = cache.get(identity.bluesky_handle)
|
||||||
|
except Exception: # pylint: disable=bare-except
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not bluesky_url:
|
||||||
|
try:
|
||||||
|
bluesky_url = bs.get_avatar(identity.bluesky_handle)
|
||||||
|
cache.set(identity.bluesky_handle, bluesky_url)
|
||||||
|
except Exception: # pylint: disable=bare-except
|
||||||
|
return redir_default(default)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if cache.get(bluesky_url) == "err":
|
||||||
|
print("Cached Bluesky fetch failed with URL error: %s" % bluesky_url)
|
||||||
|
return redir_default(default)
|
||||||
|
|
||||||
|
blueskyimagedata = urlopen(bluesky_url)
|
||||||
|
except HTTPError as exc:
|
||||||
|
if exc.code != 404 and exc.code != 503:
|
||||||
|
print(
|
||||||
|
"Bluesky fetch failed with an unexpected %s HTTP error: %s"
|
||||||
|
% (exc.code, bluesky_url)
|
||||||
|
)
|
||||||
|
cache.set(bluesky_url, "err", 30)
|
||||||
|
return redir_default(default)
|
||||||
|
except URLError as exc:
|
||||||
|
print("Bluesky fetch failed with URL error: %s" % exc.reason)
|
||||||
|
cache.set(bluesky_url, "err", 30)
|
||||||
|
return redir_default(default)
|
||||||
|
except SSLError as exc:
|
||||||
|
print("Bluesky fetch failed with SSL error: %s" % exc.reason)
|
||||||
|
cache.set(bluesky_url, "err", 30)
|
||||||
|
return redir_default(default)
|
||||||
|
try:
|
||||||
|
data = BytesIO(blueskyimagedata.read())
|
||||||
|
img = Image.open(data)
|
||||||
|
format = img.format
|
||||||
|
if max(img.size) > size:
|
||||||
|
aspect = img.size[0] / float(img.size[1])
|
||||||
|
if aspect > 1:
|
||||||
|
new_size = (size, int(size / aspect))
|
||||||
|
else:
|
||||||
|
new_size = (int(size * aspect), size)
|
||||||
|
img = img.resize(new_size)
|
||||||
|
data = BytesIO()
|
||||||
|
img.save(data, format=format)
|
||||||
|
|
||||||
|
data.seek(0)
|
||||||
|
response = HttpResponse(
|
||||||
|
data.read(), content_type="image/%s" % file_format(format)
|
||||||
|
)
|
||||||
|
response["Cache-Control"] = "max-age=%i" % CACHE_IMAGES_MAX_AGE
|
||||||
|
return response
|
||||||
|
except ValueError as exc:
|
||||||
|
print("Value error: %s" % exc)
|
||||||
|
return redir_default(default)
|
||||||
|
|
||||||
|
# We shouldn't reach this point... But make sure we do something
|
||||||
|
return redir_default(default)
|
||||||
|
|
||||||
|
|
||||||
class StatsView(TemplateView, JsonResponse):
|
class StatsView(TemplateView, JsonResponse):
|
||||||
"""
|
"""
|
||||||
Return stats
|
Return stats
|
||||||
|
|||||||
Reference in New Issue
Block a user