Properly cache the actor

This commit is contained in:
Thomas Sileo 2018-07-20 01:12:02 +02:00
parent 11fcf2dfb0
commit 610262d7b6
3 changed files with 58 additions and 8 deletions

18
app.py
View file

@ -84,7 +84,7 @@ def save_cb(box: Box, iri: str) -> None:
if box == Box.INBOX: if box == Box.INBOX:
tasks.process_new_activity.delay(iri) tasks.process_new_activity.delay(iri)
else: else:
tasks.cache_attachments.delay(iri) tasks.cache_actor.delay(iri)
back.set_save_cb(save_cb) back.set_save_cb(save_cb)
@ -674,6 +674,14 @@ def tmp_migrate4():
return "Done" return "Done"
@app.route("/migration4")
@login_required
def tmp_migrate5():
for activity in DB.activities.find():
tasks.cache_actor.delay(activity["remote_id"], also_cache_attachments=False)
return "Done"
def paginated_query(db, q, limit=25, sort_key="_id"): def paginated_query(db, q, limit=25, sort_key="_id"):
older_than = newer_than = None older_than = newer_than = None
query_sort = -1 query_sort = -1
@ -822,6 +830,7 @@ def note_by_id(note_id):
DB.activities.find( DB.activities.find(
{ {
"meta.undo": False, "meta.undo": False,
"meta.deleted": False,
"type": ActivityType.LIKE.value, "type": ActivityType.LIKE.value,
"$or": [ "$or": [
{"activity.object.id": data["activity"]["object"]["id"]}, {"activity.object.id": data["activity"]["object"]["id"]},
@ -830,12 +839,13 @@ def note_by_id(note_id):
} }
) )
) )
likes = [get_backend().fetch_iri(doc["activity"]["actor"]) for doc in likes] likes = [doc["meta"]["actor"] for doc in likes]
shares = list( shares = list(
DB.activities.find( DB.activities.find(
{ {
"meta.undo": False, "meta.undo": False,
"meta.deleted": False,
"type": ActivityType.ANNOUNCE.value, "type": ActivityType.ANNOUNCE.value,
"$or": [ "$or": [
{"activity.object.id": data["activity"]["object"]["id"]}, {"activity.object.id": data["activity"]["object"]["id"]},
@ -844,7 +854,7 @@ def note_by_id(note_id):
} }
) )
) )
shares = [get_backend().fetch_iri(doc["activity"]["actor"]) for doc in shares] shares = [doc["meta"]["actor"] for doc in shares]
return render_template( return render_template(
"note.html", likes=likes, shares=shares, thread=thread, note=data "note.html", likes=likes, shares=shares, thread=thread, note=data
@ -1605,7 +1615,7 @@ def followers():
followers = [] followers = []
for doc in raw_followers: for doc in raw_followers:
try: try:
followers.append(get_backend().fetch_iri(doc["activity"]["actor"])) followers.append(doc["meta"]["actor"])
except Exception: except Exception:
pass pass
return render_template( return render_template(

View file

@ -2,6 +2,8 @@ import json
import logging import logging
import os import os
import random import random
from typing import Dict
from typing import Any
import requests import requests
from celery import Celery from celery import Celery
@ -54,14 +56,48 @@ def process_new_activity(self, iri: str) -> None:
) )
log.info(f"new activity {iri} processed") log.info(f"new activity {iri} processed")
cache_attachments.delay(iri) cache_actor.delay(iri)
except (ActivityGoneError, ActivityNotFoundError): except (ActivityGoneError, ActivityNotFoundError):
log.exception(f"dropping activity {iri}") log.exception(f"dropping activity {iri}, skip processing")
except Exception as err: except Exception as err:
log.exception(f"failed to process new activity {iri}") log.exception(f"failed to process new activity {iri}")
self.retry(exc=err, countdown=int(random.uniform(2, 4) ** self.request.retries)) self.retry(exc=err, countdown=int(random.uniform(2, 4) ** self.request.retries))
def _actor_to_meta(actor: ap.BaseActivity) -> Dict[str, Any]:
return {
"url": actor.url,
"icon": actor.icon,
"name": actor.name,
"preferredUsername": actor.preferredUsername,
}
@app.task(bind=True, max_retries=12)
def cache_actor(self, iri: str, also_cache_attachments: bool = True) -> None:
try:
activity = ap.fetch_remote_activity(iri)
log.info(f"activity={activity!r}")
actor = activity.get_actor()
# Cache the actor info
DB.activities.update_one(
{"remote_id": iri}, {"$set": {"meta.actor": _actor_to_meta(actor)}}
)
log.info(f"actor cached for {iri}")
if also_cache_attachments:
cache_attachments.delay(iri)
except (ActivityGoneError, ActivityNotFoundError):
DB.activities.update_one({"remote_id": iri}, {"$set": {"meta.deleted": True}})
log.exception(f"flagging activity {iri} as deleted, no actor caching")
except Exception as err:
log.exception(f"failed to cache actor for {iri}")
self.retry(exc=err, countdown=int(random.uniform(2, 4) ** self.request.retries))
@app.task(bind=True, max_retries=12) @app.task(bind=True, max_retries=12)
def cache_attachments(self, iri: str) -> None: def cache_attachments(self, iri: str) -> None:
try: try:
@ -88,9 +124,9 @@ def cache_attachments(self, iri: str) -> None:
log.info(f"attachments cached for {iri}") log.info(f"attachments cached for {iri}")
except (ActivityGoneError, ActivityNotFoundError): except (ActivityGoneError, ActivityNotFoundError):
log.exception(f"dropping activity {iri}") log.exception(f"dropping activity {iri}, no attachment caching")
except Exception as err: except Exception as err:
log.exception(f"failed to process new activity {iri}") log.exception(f"failed to cache attachments for {iri}")
self.retry(exc=err, countdown=int(random.uniform(2, 4) ** self.request.retries)) self.retry(exc=err, countdown=int(random.uniform(2, 4) ** self.request.retries))

View file

@ -16,7 +16,11 @@
{% macro display_note(obj, perma=False, ui=False, likes=[], shares=[], meta={}, no_color=False) -%} {% macro display_note(obj, perma=False, ui=False, likes=[], shares=[], meta={}, no_color=False) -%}
{% if meta.actor %}
{% set actor = meta.actor %}
{% else %}
{% set actor = obj.attributedTo | get_actor %} {% set actor = obj.attributedTo | get_actor %}
{% endif %}
<div class="note h-entry" id="activity-{{ obj.id | permalink_id }}"> <div class="note h-entry" id="activity-{{ obj.id | permalink_id }}">
<div class="h-card p-author"> <div class="h-card p-author">