def _meta(activity: ap.BaseActivity) -> _NewMeta: visibility = ap.get_visibility(activity) is_public = False if visibility in [ap.Visibility.PUBLIC, ap.Visibility.UNLISTED]: is_public = True object_id = None try: object_id = activity.get_object_id() except Exception: # TODO(tsileo): should be ValueError, but replies trigger a KeyError on object pass object_visibility = None if activity.has_type( [ap.ActivityType.CREATE, ap.ActivityType.ANNOUNCE, ap.ActivityType.LIKE] ): object_visibility = ap.get_visibility(activity.get_object()).name actor_id = activity.get_actor().id return { MetaKey.UNDO.value: False, MetaKey.DELETED.value: False, MetaKey.PUBLIC.value: is_public, MetaKey.SERVER.value: urlparse(activity.id).netloc, MetaKey.VISIBILITY.value: visibility.name, MetaKey.ACTOR_ID.value: actor_id, MetaKey.OBJECT_ID.value: object_id, MetaKey.OBJECT_VISIBILITY.value: object_visibility, MetaKey.POLL_ANSWER.value: False, MetaKey.PUBLISHED.value: activity.published if activity.published else now(), }
def post_to_inbox(activity: ap.BaseActivity) -> None: # Check for Block activity actor = activity.get_actor() if outbox_is_blocked(actor.id): logger.info( f"actor {actor!r} is blocked, dropping the received activity {activity!r}" ) return # If the message is coming from a Pleroma relay, we process it as a possible reply for a stream activity if ( actor.has_type(ap.ActivityType.APPLICATION) and actor.id.endswith("/relay") and activity.has_type(ap.ActivityType.ANNOUNCE) and not find_one_activity( { **by_object_id(activity.get_object_id()), **by_type(ap.ActivityType.CREATE), } ) and not DB.replies.find_one(by_remote_id(activity.get_object_id())) ): Tasks.process_reply(activity.get_object_id()) return # Hubzilla sends Update with the same ID as the actor, and it poisons the cache if ( activity.has_type(ap.ActivityType.UPDATE) and activity.id == activity.get_object_id() ): # Start a task to update the cached actor Tasks.cache_actor(activity.id) return # Honk forwards activities in a Read, process them as replies if activity.has_type(ap.ActivityType.READ): Tasks.process_reply(activity.get_object_id()) return # TODO(tsileo): support ignore from Honk # Hubzilla forwards activities in a Create, process them as possible replies if activity.has_type(ap.ActivityType.CREATE) and server(activity.id) != server( activity.get_object_id() ): Tasks.process_reply(activity.get_object_id()) return if DB.activities.find_one({"box": Box.INBOX.value, "remote_id": activity.id}): # The activity is already in the inbox logger.info(f"received duplicate activity {activity!r}, dropping it") return save(Box.INBOX, activity) logger.info(f"spawning tasks for {activity!r}") if not activity.has_type([ap.ActivityType.DELETE, ap.ActivityType.UPDATE]): Tasks.cache_actor(activity.id) Tasks.process_new_activity(activity.id) Tasks.finish_post_to_inbox(activity.id)
def outbox_delete(self, as_actor: ap.Person, activity: ap.BaseActivity) -> None: current_app.logger.debug(f"outbox_delete {activity!r} as {as_actor!r}") # Fetch linked activity and mark it deleted # Somehow we needs to remove /activity here # FIXME do that better activity_uri = activity.get_object_id().rstrip("/activity") current_app.logger.debug(f"id: {activity_uri}") orig_activity = Activity.query.filter(Activity.url == activity_uri, Activity.type == "Create").first() orig_activity.meta_deleted = True db.session.commit()
def accept_follow(activity: ap.BaseActivity) -> str: actor_id = activity.get_actor().id accept = ap.Accept( actor=ID, context=new_context(activity), object={ "type": "Follow", "id": activity.id, "object": activity.get_object_id(), "actor": actor_id, }, to=[actor_id], published=now(), ) update_one_activity( by_remote_id(activity.id), upsert({MetaKey.FOLLOW_STATUS: FollowStatus.ACCEPTED.value}), ) return post_to_outbox(accept)
def save(box: Box, activity: ap.BaseActivity) -> None: """Custom helper for saving an activity to the DB.""" visibility = ap.get_visibility(activity) is_public = False if visibility in [ap.Visibility.PUBLIC, ap.Visibility.UNLISTED]: is_public = True object_id = None try: object_id = activity.get_object_id() except Exception: # TODO(tsileo): should be ValueError, but replies trigger a KeyError on object pass object_visibility = None if activity.has_type([ ap.ActivityType.CREATE, ap.ActivityType.ANNOUNCE, ap.ActivityType.LIKE ]): object_visibility = ap.get_visibility(activity.get_object()).name actor_id = activity.get_actor().id DB.activities.insert_one({ "box": box.value, "activity": activity.to_dict(), "type": _to_list(activity.type), "remote_id": activity.id, "meta": { "undo": False, "deleted": False, "public": is_public, "server": urlparse(activity.id).netloc, "visibility": visibility.name, "actor_id": actor_id, "object_id": object_id, "object_visibility": object_visibility, "poll_answer": False, }, })