Add webfinger support for the lookup, fix forwarding

This commit is contained in:
Thomas Sileo 2018-07-21 11:41:49 +02:00
parent f05eb559f0
commit 4a22ac12a8
4 changed files with 61 additions and 5 deletions

View file

@ -32,13 +32,24 @@ logger = logging.getLogger(__name__)
ACTORS_CACHE = LRUCache(maxsize=256) ACTORS_CACHE = LRUCache(maxsize=256)
def _actor_to_meta(actor: ap.BaseActivity) -> Dict[str, Any]: def _actor_to_meta(actor: ap.BaseActivity, with_inbox=False) -> Dict[str, Any]:
return { meta = {
"id": actor.id,
"url": actor.url, "url": actor.url,
"icon": actor.icon, "icon": actor.icon,
"name": actor.name, "name": actor.name,
"preferredUsername": actor.preferredUsername, "preferredUsername": actor.preferredUsername,
} }
if with_inbox:
meta.update(
{
"inbox": actor.inbox,
"sharedInbox": actor._data.get("endpoints", {}).get("sharedInbox"),
}
)
logger.debug(f"meta={meta}")
return meta
def _remove_id(doc: ap.ObjectType) -> ap.ObjectType: def _remove_id(doc: ap.ObjectType) -> ap.ObjectType:
@ -120,6 +131,20 @@ class MicroblogPubBackend(Backend):
} }
return [doc["activity"]["actor"] for doc in DB.activities.find(q)] return [doc["activity"]["actor"] for doc in DB.activities.find(q)]
def followers_as_recipients(self) -> List[str]:
q = {
"box": Box.INBOX.value,
"type": ap.ActivityType.FOLLOW.value,
"meta.undo": False,
}
recipients = []
for doc in DB.activities.find(q):
recipients.append(
doc["meta"]["actor"]["sharedInbox"] or doc["meta"]["actor"]["inbox"]
)
return list(set(recipients))
def following(self) -> List[str]: def following(self) -> List[str]:
q = { q = {
"box": Box.OUTBOX.value, "box": Box.OUTBOX.value,

1
app.py
View file

@ -689,6 +689,7 @@ def tmp_migrate5():
def tmp_migrate6(): def tmp_migrate6():
for activity in DB.activities.find(): for activity in DB.activities.find():
# tasks.cache_actor.delay(activity["remote_id"], also_cache_attachments=False) # tasks.cache_actor.delay(activity["remote_id"], also_cache_attachments=False)
try: try:
a = ap.parse_activity(activity["activity"]) a = ap.parse_activity(activity["activity"])
if a.has_type([ActivityType.LIKE, ActivityType.FOLLOW]): if a.has_type([ActivityType.LIKE, ActivityType.FOLLOW]):

View file

@ -54,7 +54,7 @@ def process_new_activity(self, iri: str) -> None:
) and activity.is_public(): ) and activity.is_public():
# The reply is public "local reply", forward the reply (i.e. the original activity) to the original # The reply is public "local reply", forward the reply (i.e. the original activity) to the original
# recipients # recipients
activity.forward(back.followers()) activity.forward(back.followers_as_recipients())
# (partial) Ghost replies handling # (partial) Ghost replies handling
# [X] This is the first time the server has seen this Activity. # [X] This is the first time the server has seen this Activity.
@ -70,7 +70,7 @@ def process_new_activity(self, iri: str) -> None:
should_forward = False should_forward = False
if should_forward: if should_forward:
activity.forward(back.followers()) activity.forward(back.followers_as_recipients())
else: else:
tag_stream = True tag_stream = True
@ -96,10 +96,34 @@ def cache_actor(self, iri: str, also_cache_attachments: bool = True) -> None:
actor = activity.get_actor() actor = activity.get_actor()
cache_actor_with_inbox = False
if activity.has_type(ap.ActivityType.FOLLOW):
if actor.id != ID:
# It's a Follow from the Inbox
cache_actor_with_inbox = True
else:
# It's a new following, cache the "object" (which is the actor we follow)
DB.activities.update_one(
{"remote_id": iri},
{
"$set": {
"meta.object": activitypub._actor_to_meta(
activity.get_object()
)
}
},
)
# Cache the actor info # Cache the actor info
DB.activities.update_one( DB.activities.update_one(
{"remote_id": iri}, {"remote_id": iri},
{"$set": {"meta.actor": activitypub._actor_to_meta(actor)}}, {
"$set": {
"meta.actor": activitypub._actor_to_meta(
actor, cache_actor_with_inbox
)
}
},
) )
log.info(f"actor cached for {iri}") log.info(f"actor cached for {iri}")

View file

@ -3,10 +3,16 @@ import json
import little_boxes.activitypub as ap import little_boxes.activitypub as ap
import mf2py import mf2py
import requests import requests
from little_boxes.webfinger import get_actor_url
def lookup(url: str) -> ap.BaseActivity: def lookup(url: str) -> ap.BaseActivity:
"""Try to find an AP object related to the given URL.""" """Try to find an AP object related to the given URL."""
try:
return ap.fetch_remote_activity(get_actor_url(url))
except Exception:
pass
backend = ap.get_backend() backend = ap.get_backend()
resp = requests.get( resp = requests.get(
url, url,