From a2404e01cdbeef2ba332e147a5f2f1ca0a0310d7 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Sat, 5 Nov 2022 22:49:25 -0600 Subject: Queuing system and lazy profile fetch --- users/models/identity.py | 26 ++++++++++++++++++++++++++ users/views/identity.py | 5 ++++- 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'users') diff --git a/users/models/identity.py b/users/models/identity.py index c20ef60..5586f27 100644 --- a/users/models/identity.py +++ b/users/models/identity.py @@ -59,6 +59,19 @@ class Identity(models.Model): fetched = models.DateTimeField(null=True, blank=True) deleted = models.DateTimeField(null=True, blank=True) + @classmethod + def by_handle(cls, handle, create=True): + if handle.startswith("@"): + raise ValueError("Handle must not start with @") + if "@" not in handle: + raise ValueError("Handle must contain domain") + try: + return cls.objects.filter(handle=handle).get() + except cls.DoesNotExist: + if create: + return cls.objects.create(handle=handle, local=False) + return None + @property def short_handle(self): if self.handle.endswith("@" + settings.DEFAULT_DOMAIN): @@ -69,6 +82,17 @@ class Identity(models.Model): def domain(self): return self.handle.split("@", 1)[1] + @property + def data_age(self) -> float: + """ + How old our copy of this data is, in seconds + """ + if self.local: + return 0 + if self.fetched is None: + return 10000000000 + return (timezone.now() - self.fetched).total_seconds() + def generate_keypair(self): private_key = rsa.generate_private_key( public_exponent=65537, @@ -104,6 +128,7 @@ class Identity(models.Model): response = await client.get( f"https://{self.domain}/.well-known/webfinger?resource=acct:{self.handle}", headers={"Accept": "application/json"}, + follow_redirects=True, ) if response.status_code >= 400: return False @@ -126,6 +151,7 @@ class Identity(models.Model): response = await client.get( self.actor_uri, headers={"Accept": "application/json"}, + follow_redirects=True, ) if response.status_code >= 400: return False diff --git a/users/views/identity.py b/users/views/identity.py index fff521b..456fead 100644 --- a/users/views/identity.py +++ b/users/views/identity.py @@ -10,6 +10,7 @@ from django.views.decorators.csrf import csrf_exempt from django.views.generic import FormView, TemplateView, View from core.forms import FormHelper +from miniq.models import Task from users.models import Identity from users.shortcuts import by_handle_or_404 @@ -19,8 +20,10 @@ class ViewIdentity(TemplateView): template_name = "identity/view.html" def get_context_data(self, handle): - identity = by_handle_or_404(self.request, handle, local=False) + identity = Identity.by_handle(handle=handle) statuses = identity.statuses.all()[:100] + if identity.data_age > settings.IDENTITY_MAX_AGE: + Task.submit("identity_fetch", identity.handle) return { "identity": identity, "statuses": statuses, -- cgit v1.2.3