Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webfinger check #371

Merged
merged 4 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion common/management/commands/cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,7 @@ def handle(self, *args, **options):
if not run:
logger.error(f"Job not found: {job_id}")
if options["list"]:
all_jobs = [j.__name__ for j in JobManager.registry]
logger.info(f"{len(all_jobs)} available jobs: {' '.join(all_jobs)}")
jobs = JobManager.get_scheduled_job_ids()
logger.info(f"{len(jobs)} scheduled jobs: {jobs}")
logger.info(f"{len(jobs)} scheduled jobs: {' '.join(jobs)}")
14 changes: 14 additions & 0 deletions mastodon/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,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
Expand Down
3 changes: 2 additions & 1 deletion users/jobs/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ def run(self):
ttl_hours = 12
qs = (
User.objects.exclude(
preference__mastodon_skip_userinfo=True, mastodon_skip_relationship=True
preference__mastodon_skip_userinfo=True,
preference__mastodon_skip_relationship=True,
)
.filter(
mastodon_last_refresh__lt=timezone.now() - timedelta(hours=ttl_hours)
Expand Down
2 changes: 1 addition & 1 deletion users/migrations/0012_apidentity.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Migration(migrations.Migration):
# ]

dependencies = [
("users", "0011_preference_hidden_categories"),
("users", "0015_user_mastodon_last_reachable"),
("takahe", "0001_initial"),
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@


def migrate_relationships(apps, schema_editor):
from users.models import APIdentity, User

User = apps.get_model("users", "User")
APIdentity = apps.get_model("users", "APIdentity")
logger.info(f"Migrate user relationship")
for user in tqdm(User.objects.filter(is_active=True)):
identity = APIdentity.objects.get(user=user)
for target in user.local_following.all():
user.identity.follow(User.objects.get(pk=target).identity)
target_identity = APIdentity.objects.get(user=target)
identity.follow(target_identity)
for target in user.local_blocking.all():
user.identity.block(User.objects.get(pk=target).identity)
target_identity = APIdentity.objects.get(user=target)
identity.block(target_identity)
for target in user.local_muting.all():
user.identity.block(User.objects.get(pk=target).identity)
target_identity = APIdentity.objects.get(user=target)
identity.mute(target_identity)
user.sync_relationship()
for user in tqdm(User.objects.filter(is_active=True)):
for target_identity in user.identity.follow_requesting_identities:
target_identity.accept_follow_request(user.identity)
identity = APIdentity.objects.get(user=user)
for target_identity in identity.follow_requesting_identities:
target_identity.accept_follow_request(identity)


class Migration(migrations.Migration):
Expand Down
19 changes: 19 additions & 0 deletions users/migrations/0015_user_mastodon_last_reachable.py
Original file line number Diff line number Diff line change
@@ -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),
),
]
18 changes: 16 additions & 2 deletions users/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,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)
Expand Down Expand Up @@ -267,9 +268,14 @@ def sync_identity(self):
identity.save()

def refresh_mastodon_data(self):
"""Try refresh account data from mastodon server, return true if refreshed successfully, note it will not save to db"""
"""Try refresh account data from mastodon server, return True if refreshed successfully"""
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(
Expand Down Expand Up @@ -317,7 +323,15 @@ def refresh_mastodon_data(self):
elif code == 401:
logger.error(f"Refresh mastodon data error 401 for {self}")
self.mastodon_token = ""
self.save(update_fields=["mastodon_token"])
else:
logger.error(f"Refresh mastodon data error 401 for {self}")
self.save(
update_fields=[
"mastodon_token",
"mastodon_last_refresh",
"mastodon_last_reachable",
]
)
return False

@property
Expand Down