예제 #1
0
def liked():
    if not is_api_request():
        q = {
            "box": Box.OUTBOX.value,
            "type": ActivityType.LIKE.value,
            "meta.deleted": False,
            "meta.undo": False,
        }

        liked, older_than, newer_than = paginated_query(DB.activities, q)

        return htmlify(
            render_template("liked.html",
                            liked=liked,
                            older_than=older_than,
                            newer_than=newer_than))

    q = {
        "meta.deleted": False,
        "meta.undo": False,
        "type": ActivityType.LIKE.value
    }
    return activitypubify(**activitypub.build_ordered_collection(
        DB.activities,
        q=q,
        cursor=request.args.get("cursor"),
        map_func=lambda doc: doc["activity"]["object"],
        col_name="liked",
    ))
예제 #2
0
def followers():
    q = {
        "box": Box.INBOX.value,
        "type": ActivityType.FOLLOW.value,
        "meta.undo": False
    }

    if is_api_request():
        _log_sig()
        return activitypubify(**activitypub.build_ordered_collection(
            DB.activities,
            q=q,
            cursor=request.args.get("cursor"),
            map_func=lambda doc: doc["activity"]["actor"],
            col_name="followers",
        ))

    raw_followers, older_than, newer_than = paginated_query(DB.activities, q)
    followers = [
        doc["meta"] for doc in raw_followers if "actor" in doc.get("meta", {})
    ]
    return htmlify(
        render_template(
            "followers.html",
            followers_data=followers,
            older_than=older_than,
            newer_than=newer_than,
        ))
예제 #3
0
def following():
    q = {**in_outbox(), **by_type(ActivityType.FOLLOW), **not_undo()}

    if is_api_request():
        _log_sig()
        return jsonify(**activitypub.build_ordered_collection(
            DB.activities,
            q=q,
            cursor=request.args.get("cursor"),
            map_func=lambda doc: doc["activity"]["object"],
            col_name="following",
        ))

    if config.HIDE_FOLLOWING and not session.get("logged_in", False):
        abort(404)

    following, older_than, newer_than = paginated_query(DB.activities, q)
    following = [(doc["remote_id"], doc["meta"]["object"]) for doc in following
                 if "remote_id" in doc and "object" in doc.get("meta", {})]
    lists = list(DB.lists.find())
    return render_template(
        "following.html",
        following_data=following,
        older_than=older_than,
        newer_than=newer_than,
        lists=lists,
    )
예제 #4
0
def admin_list(name: str) -> _Response:
    list_ = DB.lists.find_one({"name": name})
    if not list_:
        abort(404)

    q = {
        "meta.stream": True,
        "meta.deleted": False,
        "meta.actor_id": {
            "$in": list_["members"]
        },
    }

    tpl = "stream.html"
    if request.args.get("debug"):
        tpl = "stream_debug.html"
        if request.args.get("debug_inbox"):
            q = {}

    inbox_data, older_than, newer_than = paginated_query(
        DB.activities, q, limit=int(request.args.get("limit", 25)))

    return htmlify(
        render_template(
            tpl,
            inbox_data=inbox_data,
            older_than=older_than,
            newer_than=newer_than,
            list_name=name,
        ))
예제 #5
0
def index():
    if is_api_request():
        _log_sig()
        return activitypubify(**ME)

    q = {
        **in_outbox(),
        "$or": [
            {
                **by_type(ActivityType.CREATE),
                **not_deleted(),
                **by_visibility(ap.Visibility.PUBLIC),
                "$or": [{
                    "meta.pinned": False
                }, {
                    "meta.pinned": {
                        "$exists": False
                    }
                }],
            },
            {
                **by_type(ActivityType.ANNOUNCE),
                **not_undo()
            },
        ],
    }

    apinned = []
    # Only fetch the pinned notes if we're on the first page
    if not request.args.get("older_than") and not request.args.get(
            "newer_than"):
        q_pinned = {
            **in_outbox(),
            **by_type(ActivityType.CREATE),
            **not_deleted(),
            **pinned(),
            **by_visibility(ap.Visibility.PUBLIC),
        }
        apinned = list(DB.activities.find(q_pinned))

    outbox_data, older_than, newer_than = paginated_query(DB.activities,
                                                          q,
                                                          limit=25 -
                                                          len(apinned))

    return htmlify(
        render_template(
            "index.html",
            outbox_data=outbox_data,
            older_than=older_than,
            newer_than=newer_than,
            pinned=apinned,
        ))
예제 #6
0
def index():
    if is_api_request():
        _log_sig()
        return jsonify(**ME)

    q = {
        "box": Box.OUTBOX.value,
        "type": {
            "$in": [ActivityType.CREATE.value, ActivityType.ANNOUNCE.value]
        },
        "activity.object.inReplyTo": None,
        "meta.deleted": False,
        "meta.undo": False,
        "meta.public": True,
        "$or": [{
            "meta.pinned": False
        }, {
            "meta.pinned": {
                "$exists": False
            }
        }],
    }

    pinned = []
    # Only fetch the pinned notes if we're on the first page
    if not request.args.get("older_than") and not request.args.get(
            "newer_than"):
        q_pinned = {
            "box": Box.OUTBOX.value,
            "type": ActivityType.CREATE.value,
            "meta.deleted": False,
            "meta.undo": False,
            "meta.public": True,
            "meta.pinned": True,
        }
        pinned = list(DB.activities.find(q_pinned))

    outbox_data, older_than, newer_than = paginated_query(DB.activities,
                                                          q,
                                                          limit=25 -
                                                          len(pinned))

    resp = render_template(
        "index.html",
        outbox_data=outbox_data,
        older_than=older_than,
        newer_than=newer_than,
        pinned=pinned,
    )
    return resp
예제 #7
0
def admin_bookmarks() -> _Response:
    q = {"meta.bookmarked": True}

    tpl = "stream.html"
    if request.args.get("debug"):
        tpl = "stream_debug.html"
        if request.args.get("debug_inbox"):
            q = {}

    inbox_data, older_than, newer_than = paginated_query(
        DB.activities, q, limit=int(request.args.get("limit", 25)))

    return render_template(tpl,
                           inbox_data=inbox_data,
                           older_than=older_than,
                           newer_than=newer_than)
예제 #8
0
def all():
    q = {
        **in_outbox(),
        **by_type([ActivityType.CREATE, ActivityType.ANNOUNCE]),
        **not_deleted(),
        **not_undo(),
        **not_poll_answer(),
    }
    outbox_data, older_than, newer_than = paginated_query(DB.activities, q)

    return htmlify(
        render_template(
            "index.html",
            outbox_data=outbox_data,
            older_than=older_than,
            newer_than=newer_than,
        ))
예제 #9
0
def all():
    q = {
        "box": Box.OUTBOX.value,
        "type": {
            "$in": [ActivityType.CREATE.value, ActivityType.ANNOUNCE.value]
        },
        "meta.deleted": False,
        "meta.undo": False,
        "meta.poll_answer": False,
    }
    outbox_data, older_than, newer_than = paginated_query(DB.activities, q)

    return render_template(
        "index.html",
        outbox_data=outbox_data,
        older_than=older_than,
        newer_than=newer_than,
    )
예제 #10
0
def admin_profile() -> _Response:
    if not request.args.get("actor_id"):
        abort(404)

    actor_id = request.args.get("actor_id")
    actor = ap.fetch_remote_activity(actor_id)
    q = {
        "meta.actor_id": actor_id,
        "box": "inbox",
        **not_deleted(),
        "type": {
            "$in":
            [ap.ActivityType.CREATE.value, ap.ActivityType.ANNOUNCE.value]
        },
    }
    inbox_data, older_than, newer_than = paginated_query(
        DB.activities, q, limit=int(request.args.get("limit", 25)))
    follower = find_one_activity({
        "box": "inbox",
        "type": ap.ActivityType.FOLLOW.value,
        "meta.actor_id": actor.id,
        "meta.undo": False,
    })
    following = find_one_activity({
        **by_type(ap.ActivityType.FOLLOW),
        **by_object_id(actor.id),
        **not_undo(),
        **in_outbox(),
        **follow_request_accepted(),
    })

    return htmlify(
        render_template(
            "stream.html",
            actor_id=actor_id,
            actor=actor.to_dict(),
            inbox_data=inbox_data,
            older_than=older_than,
            newer_than=newer_than,
            follower=follower,
            following=following,
            lists=list(DB.lists.find()),
        ))
예제 #11
0
def admin_notifications() -> _Response:
    # Setup the cron for deleting old activities

    # FIXME(tsileo): put back to 12h
    p.push({}, "/task/cleanup", schedule="@every 1h")

    # Trigger a cleanup if asked
    if request.args.get("cleanup"):
        p.push({}, "/task/cleanup")

    # FIXME(tsileo): show unfollow (performed by the current actor) and liked???
    mentions_query = {
        "type": ap.ActivityType.CREATE.value,
        "activity.object.tag.type": "Mention",
        "activity.object.tag.name": f"@{config.USERNAME}@{config.DOMAIN}",
        "meta.deleted": False,
    }
    replies_query = {
        "type": ap.ActivityType.CREATE.value,
        "activity.object.inReplyTo": {
            "$regex": f"^{config.BASE_URL}"
        },
        "meta.poll_answer": False,
    }
    announced_query = {
        "type": ap.ActivityType.ANNOUNCE.value,
        "activity.object": {
            "$regex": f"^{config.BASE_URL}"
        },
    }
    new_followers_query = {"type": ap.ActivityType.FOLLOW.value}
    unfollow_query = {
        "type": ap.ActivityType.UNDO.value,
        "activity.object.type": ap.ActivityType.FOLLOW.value,
    }
    likes_query = {
        "type": ap.ActivityType.LIKE.value,
        "activity.object": {
            "$regex": f"^{config.BASE_URL}"
        },
    }
    followed_query = {"type": ap.ActivityType.ACCEPT.value}
    rejected_query = {"type": ap.ActivityType.REJECT.value}
    q = {
        "box":
        Box.INBOX.value,
        "$or": [
            mentions_query,
            announced_query,
            replies_query,
            new_followers_query,
            followed_query,
            rejected_query,
            unfollow_query,
            likes_query,
        ],
    }
    inbox_data, older_than, newer_than = paginated_query(DB.activities, q)
    if not newer_than:
        nstart = datetime.now(timezone.utc).isoformat()
    else:
        nstart = inbox_data[0]["_id"].generation_time.isoformat()
    if not older_than:
        nend = (datetime.now(timezone.utc) - timedelta(days=15)).isoformat()
    else:
        nend = inbox_data[-1]["_id"].generation_time.isoformat()
    print(nstart, nend)
    notifs = list(
        DB.notifications.find({
            "datetime": {
                "$lte": nstart,
                "$gt": nend
            }
        }).sort("_id", -1).limit(50))
    print(inbox_data)

    nid = None
    if inbox_data:
        nid = inbox_data[0]["_id"]

    inbox_data.extend(notifs)
    inbox_data = sorted(inbox_data,
                        reverse=True,
                        key=lambda doc: doc["_id"].generation_time)

    return htmlify(
        render_template(
            "stream.html",
            inbox_data=inbox_data,
            older_than=older_than,
            newer_than=newer_than,
            nid=nid,
        ))