mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
refresh stale user profiles
This commit is contained in:
parent
6ac8aca227
commit
71289b9435
3 changed files with 51 additions and 6 deletions
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
from random import randint
|
from random import randint
|
||||||
from typing import Union, Tuple
|
from typing import Union, Tuple
|
||||||
from flask import current_app, request, g
|
from flask import current_app, request, g
|
||||||
|
@ -205,6 +206,8 @@ def find_actor_or_create(actor: str) -> Union[User, Community, None]:
|
||||||
user = Community.query.filter_by(ap_profile_id=actor).first()
|
user = Community.query.filter_by(ap_profile_id=actor).first()
|
||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
|
if not user.is_local() and user.ap_fetched_at < utcnow() - timedelta(days=7):
|
||||||
|
refresh_user_profile(user.id)
|
||||||
return user
|
return user
|
||||||
else: # User does not exist in the DB, it's going to need to be created from it's remote home instance
|
else: # User does not exist in the DB, it's going to need to be created from it's remote home instance
|
||||||
if actor.startswith('https://'):
|
if actor.startswith('https://'):
|
||||||
|
@ -247,11 +250,53 @@ def extract_domain_and_actor(url_string: str):
|
||||||
return server_domain, actor
|
return server_domain, actor
|
||||||
|
|
||||||
|
|
||||||
|
def refresh_user_profile(user_id):
|
||||||
|
if current_app.debug:
|
||||||
|
refresh_user_profile_task(user_id)
|
||||||
|
else:
|
||||||
|
refresh_user_profile_task.apply_async(args=(user_id), countdown=randint(1, 10))
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task
|
||||||
|
def refresh_user_profile_task(user_id):
|
||||||
|
user = User.query.get(user_id)
|
||||||
|
if user:
|
||||||
|
actor_data = get_request(user.ap_profile_id, headers={'Accept': 'application/activity+json'})
|
||||||
|
if actor_data.status_code == 200:
|
||||||
|
activity_json = actor_data.json()
|
||||||
|
actor_data.close()
|
||||||
|
user.user_name = activity_json['preferredUsername']
|
||||||
|
user.about_html = parse_summary(activity_json)
|
||||||
|
user.ap_fetched_at = utcnow()
|
||||||
|
user.public_key=activity_json['publicKey']['publicKeyPem']
|
||||||
|
|
||||||
|
avatar_changed = cover_changed = False
|
||||||
|
if 'icon' in activity_json:
|
||||||
|
if activity_json['icon']['url'] != user.avatar.source_url:
|
||||||
|
user.avatar.delete_from_disk()
|
||||||
|
avatar = File(source_url=activity_json['icon']['url'])
|
||||||
|
user.avatar = avatar
|
||||||
|
db.session.add(avatar)
|
||||||
|
avatar_changed = True
|
||||||
|
if 'image' in activity_json:
|
||||||
|
if activity_json['image']['url'] != user.cover.source_url:
|
||||||
|
user.cover.delete_from_disk()
|
||||||
|
cover = File(source_url=activity_json['image']['url'])
|
||||||
|
user.cover = cover
|
||||||
|
db.session.add(cover)
|
||||||
|
cover_changed = True
|
||||||
|
db.session.commit()
|
||||||
|
if user.avatar_id and avatar_changed:
|
||||||
|
make_image_sizes(user.avatar_id, 40, 250, 'users')
|
||||||
|
if user.cover_id and cover_changed:
|
||||||
|
make_image_sizes(user.cover_id, 700, 1600, 'users')
|
||||||
|
|
||||||
|
|
||||||
def actor_json_to_model(activity_json, address, server):
|
def actor_json_to_model(activity_json, address, server):
|
||||||
if activity_json['type'] == 'Person':
|
if activity_json['type'] == 'Person':
|
||||||
user = User(user_name=activity_json['preferredUsername'],
|
user = User(user_name=activity_json['preferredUsername'],
|
||||||
email=f"{address}@{server}",
|
email=f"{address}@{server}",
|
||||||
about=parse_summary(activity_json),
|
about_html=parse_summary(activity_json),
|
||||||
created=activity_json['published'] if 'published' in activity_json else utcnow(),
|
created=activity_json['published'] if 'published' in activity_json else utcnow(),
|
||||||
ap_id=f"{address}@{server}",
|
ap_id=f"{address}@{server}",
|
||||||
ap_public_url=activity_json['id'],
|
ap_public_url=activity_json['id'],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from sqlalchemy.sql.operators import or_
|
from sqlalchemy.sql.operators import or_
|
||||||
|
|
||||||
from app import db, cache
|
from app import db, cache
|
||||||
from app.activitypub.util import default_context, make_image_sizes_async
|
from app.activitypub.util import default_context, make_image_sizes_async, refresh_user_profile
|
||||||
from app.constants import SUBSCRIPTION_PENDING, SUBSCRIPTION_MEMBER, POST_TYPE_IMAGE, POST_TYPE_LINK, SUBSCRIPTION_OWNER
|
from app.constants import SUBSCRIPTION_PENDING, SUBSCRIPTION_MEMBER, POST_TYPE_IMAGE, POST_TYPE_LINK, SUBSCRIPTION_OWNER
|
||||||
from app.main import bp
|
from app.main import bp
|
||||||
from flask import g, session, flash, request, current_app, url_for, redirect, make_response, jsonify
|
from flask import g, session, flash, request, current_app, url_for, redirect, make_response, jsonify
|
||||||
|
@ -99,9 +99,7 @@ def robots():
|
||||||
|
|
||||||
@bp.route('/test')
|
@bp.route('/test')
|
||||||
def test():
|
def test():
|
||||||
make_image_sizes_async(159, 60, 250, 'communities')
|
refresh_user_profile(12)
|
||||||
make_image_sizes_async(140, 60, 250, 'communities')
|
|
||||||
make_image_sizes_async(141, 700, 1600, 'communities')
|
|
||||||
return 'done'
|
return 'done'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ class User(UserMixin, db.Model):
|
||||||
search_vector = db.Column(TSVectorType('user_name', 'bio', 'keywords'))
|
search_vector = db.Column(TSVectorType('user_name', 'bio', 'keywords'))
|
||||||
activity = db.relationship('ActivityLog', backref='account', lazy='dynamic', cascade="all, delete-orphan")
|
activity = db.relationship('ActivityLog', backref='account', lazy='dynamic', cascade="all, delete-orphan")
|
||||||
posts = db.relationship('Post', lazy='dynamic', cascade="all, delete-orphan")
|
posts = db.relationship('Post', lazy='dynamic', cascade="all, delete-orphan")
|
||||||
post_replies = db.relationship('PostReply', backref='author', lazy='dynamic', cascade="all, delete-orphan")
|
post_replies = db.relationship('PostReply', lazy='dynamic', cascade="all, delete-orphan")
|
||||||
|
|
||||||
roles = db.relationship('Role', secondary=user_role, lazy='dynamic', cascade="all, delete")
|
roles = db.relationship('Role', secondary=user_role, lazy='dynamic', cascade="all, delete")
|
||||||
|
|
||||||
|
@ -586,6 +586,8 @@ class PostReply(db.Model):
|
||||||
|
|
||||||
search_vector = db.Column(TSVectorType('body'))
|
search_vector = db.Column(TSVectorType('body'))
|
||||||
|
|
||||||
|
author = db.relationship('User', lazy='joined', foreign_keys=[user_id], single_parent=True)
|
||||||
|
|
||||||
def is_local(self):
|
def is_local(self):
|
||||||
return self.ap_id is None or self.ap_id.startswith('https://' + current_app.config['SERVER_NAME'])
|
return self.ap_id is None or self.ap_id.startswith('https://' + current_app.config['SERVER_NAME'])
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue