diff --git a/mastodon/api.py b/mastodon/api.py index 0a43e048..f978ae28 100644 --- a/mastodon/api.py +++ b/mastodon/api.py @@ -133,6 +133,20 @@ def create_app(domain_name): return response +def webfinger(site, username) -> dict | None: + url = f"https://{site}/.well-known/webfinger?resource=acct:{username}@{site}" + try: + response = get(url, headers={"User-Agent": USER_AGENT}) + if response.status_code != 200: + logger.error(f"Error webfinger {username}@{site} {response.status_code}") + return None + j = response.json() + return j + except Exception: + logger.error(f"Error webfinger {username}@{site}") + return None + + # utils below def random_string_generator(n): s = string.ascii_letters + string.punctuation + string.digits diff --git a/users/migrations/0015_user_mastodon_last_reachable.py b/users/migrations/0015_user_mastodon_last_reachable.py new file mode 100644 index 00000000..7bdb1d39 --- /dev/null +++ b/users/migrations/0015_user_mastodon_last_reachable.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.7 on 2023-11-11 05:34 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("users", "0011_preference_hidden_categories"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="mastodon_last_reachable", + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/users/models/user.py b/users/models/user.py index e67cc46a..ba9cbe37 100644 --- a/users/models/user.py +++ b/users/models/user.py @@ -120,6 +120,7 @@ class User(AbstractUser): mastodon_domain_blocks = models.JSONField(default=list) mastodon_account = models.JSONField(default=dict) mastodon_last_refresh = models.DateTimeField(default=timezone.now) + mastodon_last_reachable = models.DateTimeField(default=timezone.now) # store the latest read announcement id, # every time user read the announcement update this field read_announcement_index = models.PositiveIntegerField(default=0) @@ -362,7 +363,13 @@ def merge_rejected_by(cls): def refresh_mastodon_data(self): """Try refresh account data from mastodon server, return true if refreshed successfully, note it will not save to db""" + logger.debug(f"Refreshing Mastodon data for {self}") self.mastodon_last_refresh = timezone.now() + if not webfinger(self.mastodon_site, self.mastodon_username): + logger.error(f"Unable to fetch web finger for {self}") + self.save(update_fields=["mastodon_last_refresh"]) + return False + self.mastodon_last_reachable = timezone.now() code, mastodon_account = verify_account(self.mastodon_site, self.mastodon_token) if code == 401 and self.mastodon_refresh_token: self.mastodon_token = refresh_access_token(