예제 #1
0
def update_cached_actor(actor: ap.BaseActivity) -> None:
    actor_hash = _actor_hash(actor)
    update_many_activities(
        {
            **flag(MetaKey.ACTOR_ID, actor.id),
            **flag(MetaKey.ACTOR_HASH, {"$ne": actor_hash}),
        },
        upsert({
            MetaKey.ACTOR: actor.to_dict(embed=True),
            MetaKey.ACTOR_HASH: actor_hash
        }),
    )
    update_many_activities(
        {
            **flag(MetaKey.OBJECT_ACTOR_ID, actor.id),
            **flag(MetaKey.OBJECT_ACTOR_HASH, {"$ne": actor_hash}),
        },
        upsert({
            MetaKey.OBJECT_ACTOR: actor.to_dict(embed=True),
            MetaKey.OBJECT_ACTOR_HASH: actor_hash,
        }),
    )
    # TODO(tsileo): Also update following (it's in the object)
    # DB.activities.update_many(
    #     {"meta.object_id": actor.id}, {"$set": {"meta.object": actor.to_dict(embed=True)}}
    # )
    _cache_actor_icon(actor)
예제 #2
0
def save(box: Box, activity: ap.BaseActivity) -> None:
    """Custom helper for saving an activity to the DB."""
    # Set some "type"-related neta
    meta = _meta(activity)
    if box == Box.OUTBOX and activity.has_type(ap.ActivityType.FOLLOW):
        meta[MetaKey.FOLLOW_STATUS.value] = FollowStatus.WAITING.value
    elif activity.has_type(ap.ActivityType.CREATE):
        mentions = []
        obj = activity.get_object()
        for m in obj.get_mentions():
            mentions.append(m.href)
        hashtags = []
        for h in obj.get_hashtags():
            hashtags.append(h.name[1:])  # Strip the #
        meta.update(
            {MetaKey.MENTIONS.value: mentions, MetaKey.HASHTAGS.value: hashtags}
        )

    DB.activities.insert_one(
        {
            "box": box.value,
            "activity": activity.to_dict(),
            "type": _to_list(activity.type),
            "remote_id": activity.id,
            "meta": meta,
        }
    )
예제 #3
0
 def save(self, box: Box, activity: ap.BaseActivity) -> None:
     """Custom helper for saving an activity to the DB."""
     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},
         }
     )
예제 #4
0
 def outbox_new(self, as_actor: ap.Person,
                activity: ap.BaseActivity) -> None:
     print(f"saving {activity!r} to DB")
     actor_id = activity.get_actor().id
     if activity.id in self.OUTBOX_IDX[actor_id]:
         return
     self.DB[actor_id]["outbox"].append(activity)
     self.OUTBOX_IDX[actor_id][activity.id] = activity
     self.FETCH_MOCK[activity.id] = activity.to_dict()
     if isinstance(activity, ap.Create):
         self.FETCH_MOCK[
             activity.get_object().id] = activity.get_object().to_dict()
예제 #5
0
    def save(self, box: Box, activity: ap.BaseActivity) -> None:
        """Save an Activity in database"""

        current_app.logger.info(f"asked to save an activity {activity!r}")

        # Save remote Actor
        ap_actor = activity.get_actor()
        domain = urlparse(ap_actor.id)
        current_app.logger.debug(f"actor.id=={ap_actor.__dict__}")

        current_app.logger.debug(f"actor domain {domain.netloc} and " f"name {ap_actor.preferredUsername}")

        actor = Actor.query.filter(Actor.domain == domain.netloc, Actor.name == ap_actor.preferredUsername).first()

        # FIXME TODO: check if it still works with unknown remote actor
        if not actor:
            current_app.logger.debug("cannot find actor")
            actor = Actor.query.filter(Actor.url == ap_actor.id).first()
            if not actor:
                current_app.logger.debug(f"actor {ap_actor.id} not found")
                actor, user = create_remote_actor(ap_actor)
                db.session.add(user)
                db.session.add(actor)
                current_app.logger.debug("created one in DB")
            else:
                current_app.logger.debug(f"got local one {actor.url}")
        else:
            current_app.logger.debug(f"got remote one {actor.url}")

        # Save Activity
        act = Activity()
        act.payload = activity.to_dict()
        act.url = activity.id
        act.type = activity.type
        act.box = box.value

        # Activity is local only if the url starts like BASE_URL
        base_url = current_app.config["BASE_URL"]
        act.local = activity.id.startswith(base_url)

        act.actor_id = actor.id

        db.session.add(act)

        db.session.commit()
예제 #6
0
    def post_to_outbox(self, activity: ap.BaseActivity) -> None:
        if activity.has_type(ap.CREATE_TYPES):
            activity = activity.build_create()

        self.save(Box.OUTBOX, activity)

        # Assign create a random ID
        obj_id = self.random_object_id()
        activity.set_id(self.activity_url(obj_id), obj_id)

        recipients = activity.recipients()
        logger.info(f"recipients={recipients}")
        activity = ap.clean_activity(activity.to_dict())

        payload = json.dumps(activity)
        for recp in recipients:
            logger.debug(f"posting to {recp}")
            self.post_to_remote_inbox(self.get_actor(), payload, recp)
예제 #7
0
    def save(self, box: Box, activity: ap.BaseActivity) -> None:
        """Custom helper for saving an activity to the DB."""
        is_public = True
        if activity.has_type(
                ap.ActivityType.CREATE) and not activity.is_public():
            is_public = False

        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
            },
        })
예제 #8
0
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,
        },
    })
예제 #9
0
def save_reply(activity: ap.BaseActivity, meta: Dict[str, Any] = {}) -> None:
    visibility = ap.get_visibility(activity)
    is_public = False
    if visibility in [ap.Visibility.PUBLIC, ap.Visibility.UNLISTED]:
        is_public = True

    published = activity.published if activity.published else now()
    DB.replies.insert_one({
        "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": activity.get_actor().id,
            MetaKey.PUBLISHED.value: published,
            **meta,
        },
    })