def migrate(self) -> None: for data in find_activities({ **by_type(ap.ActivityType.CREATE), **not_deleted() }): try: in_reply_to = data["activity"]["object"].get("inReplyTo") if in_reply_to: update_one_activity( by_remote_id(data["remote_id"]), upsert({MetaKey.IN_REPLY_TO: in_reply_to}), ) except Exception: logger.exception(f"failed to process activity {data!r}") for data in DB.replies.find({**not_deleted()}): try: in_reply_to = data["activity"].get("inReplyTo") if in_reply_to: DB.replies.update_one( by_remote_id(data["remote_id"]), upsert({MetaKey.IN_REPLY_TO: in_reply_to}), ) except Exception: logger.exception(f"failed to process activity {data!r}")
def migrate(self) -> None: for data in find_activities({ **by_type(ap.ActivityType.CREATE), **not_deleted() }): try: activity = ap.parse_activity(data["activity"]) 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 # update_one_activity( by_remote_id(data["remote_id"]), upsert({ MetaKey.MENTIONS: mentions, MetaKey.HASHTAGS: hashtags }), ) except Exception: logger.exception(f"failed to process activity {data!r}")
def migrate(self) -> None: for data in find_activities({**by_type(ap.ActivityType.ACCEPT), **in_inbox()}): try: update_one_activity( { **by_type(ap.ActivityType.FOLLOW), **by_remote_id(data["meta"]["object_id"]), }, upsert({MetaKey.FOLLOW_STATUS: FollowStatus.ACCEPTED.value}), ) # Check if we are following this actor follow_query = { **in_inbox(), **by_type(ap.ActivityType.FOLLOW), **by_actor_id(data["meta"]["actor_id"]), **not_undo(), } raw_follow = DB.activities.find_one(follow_query) if raw_follow: DB.activities.update_many( follow_query, {"$set": {_meta(MetaKey.NOTIFICATION_FOLLOWS_BACK): True}}, ) except Exception: logger.exception(f"failed to process activity {data!r}") for data in find_activities({**by_type(ap.ActivityType.REJECT), **in_inbox()}): try: update_one_activity( { **by_type(ap.ActivityType.FOLLOW), **by_remote_id(data["meta"]["object_id"]), }, upsert({MetaKey.FOLLOW_STATUS: FollowStatus.REJECTED.value}), ) except Exception: logger.exception(f"failed to process activity {data!r}") DB.activities.update_many( { **by_type(ap.ActivityType.FOLLOW), **in_inbox(), "meta.follow_status": {"$exists": False}, }, {"$set": {"meta.follow_status": "waiting"}}, )
def migrate(self) -> None: for data in find_activities({"activity.object.tag.type": "Place"}): for tag in data["activity"]["object"]["tag"]: if tag["type"] == "Place": break DB.activities.update_one( {"_id": data["_id"]}, { "$pull": { "activity.object.tag": { "type": "Place" } }, "$set": { "activity.object.location": tag }, }, )
def migrate(self) -> None: for data in find_activities({"meta.published": {"$exists": False}}): try: raw = data["activity"] # If the activity has its own `published` field, we'll use it if "published" in raw: published = raw["published"] else: # Otherwise, we take the date we received the activity as the published time published = ap.format_datetime(data["_id"].generation_time) # Set the field in the DB update_one_activity( {"_id": data["_id"]}, {"$set": {_meta(MetaKey.PUBLISHED): published}}, ) except Exception: logger.exception(f"failed to process activity {data!r}")
def _build_thread(data, include_children=True, query=None): # noqa: C901 if query is None: query = {} data["_requested"] = True app.logger.info(f"_build_thread({data!r})") root_id = (data["meta"].get(MetaKey.THREAD_ROOT_PARENT.value) or data["meta"].get(MetaKey.OBJECT_ID.value) or data["remote_id"]) replies = [data] for dat in find_activities({ **by_object_id(root_id), **not_deleted(), **by_type(ap.ActivityType.CREATE), **query, }): replies.append(dat) for dat in find_activities({ **flag(MetaKey.THREAD_ROOT_PARENT, root_id), **not_deleted(), **by_type(ap.ActivityType.CREATE), **query, }): replies.append(dat) for dat in DB.replies.find({ **flag(MetaKey.THREAD_ROOT_PARENT, root_id), **not_deleted(), **query }): # Make a Note/Question/... looks like a Create dat["meta"].update({ MetaKey.OBJECT_VISIBILITY.value: dat["meta"][MetaKey.VISIBILITY.value] }) dat = { "activity": { "object": dat["activity"] }, "meta": dat["meta"], "_id": dat["_id"], } replies.append(dat) replies = sorted(replies, key=lambda d: d["meta"]["published"]) # Index all the IDs in order to build a tree idx = {} replies2 = [] for rep in replies: rep_id = rep["activity"]["object"]["id"] if rep_id in idx: continue idx[rep_id] = rep.copy() idx[rep_id]["_nodes"] = [] replies2.append(rep) # Build the tree for rep in replies2: rep_id = rep["activity"]["object"]["id"] if rep_id == root_id: continue reply_of = ap._get_id(rep["activity"]["object"].get("inReplyTo")) try: idx[reply_of]["_nodes"].append(rep) except KeyError: app.logger.info(f"{reply_of} is not there! skipping {rep}") # Flatten the tree thread = [] def _flatten(node, level=0): node["_level"] = level thread.append(node) for snode in sorted( idx[node["activity"]["object"]["id"]]["_nodes"], key=lambda d: d["activity"]["object"]["published"], ): _flatten(snode, level=level + 1) try: _flatten(idx[root_id]) except KeyError: app.logger.info(f"{root_id} is not there! skipping") return thread