mirror of
https://git.sr.ht/~tsileo/microblog.pub
synced 2024-11-15 03:04:28 +00:00
More bugfixes and re-handle replies
This commit is contained in:
parent
986edbd35e
commit
1338d99994
3 changed files with 80 additions and 22 deletions
|
@ -91,13 +91,13 @@ class MicroblogPubBackend(Backend):
|
||||||
# Check if the activity is owned by this server
|
# Check if the activity is owned by this server
|
||||||
if iri.startswith(BASE_URL):
|
if iri.startswith(BASE_URL):
|
||||||
is_a_note = False
|
is_a_note = False
|
||||||
if iri.endswith('/activity'):
|
if iri.endswith("/activity"):
|
||||||
iri = iri.replace('/activity', '')
|
iri = iri.replace("/activity", "")
|
||||||
is_a_note = True
|
is_a_note = True
|
||||||
data = DB.outbox.find_one({"remote_id": iri})
|
data = DB.outbox.find_one({"remote_id": iri})
|
||||||
if data:
|
if data:
|
||||||
if is_a_note:
|
if is_a_note:
|
||||||
return data['activity']['object']
|
return data["activity"]["object"]
|
||||||
return data["activity"]
|
return data["activity"]
|
||||||
else:
|
else:
|
||||||
# Check if the activity is stored in the inbox
|
# Check if the activity is stored in the inbox
|
||||||
|
@ -239,6 +239,11 @@ class MicroblogPubBackend(Backend):
|
||||||
{"activity.object.id": delete.get_object().id},
|
{"activity.object.id": delete.get_object().id},
|
||||||
{"$set": {"meta.deleted": True}},
|
{"$set": {"meta.deleted": True}},
|
||||||
)
|
)
|
||||||
|
obj = delete.get_object()
|
||||||
|
if obj.ACTIVITY_TYPE != ActivityType.NOTE:
|
||||||
|
obj = self.fetch_iri(delete.get_object().id)
|
||||||
|
self._handle_replies_delete(as_actor, obj)
|
||||||
|
|
||||||
# FIXME(tsileo): handle threads
|
# FIXME(tsileo): handle threads
|
||||||
# obj = delete._get_actual_object()
|
# obj = delete._get_actual_object()
|
||||||
# if obj.type_enum == ActivityType.NOTE:
|
# if obj.type_enum == ActivityType.NOTE:
|
||||||
|
@ -291,11 +296,43 @@ class MicroblogPubBackend(Backend):
|
||||||
# FIXME(tsileo): should send an Update (but not a partial one, to all the note's recipients
|
# FIXME(tsileo): should send an Update (but not a partial one, to all the note's recipients
|
||||||
# (create a new Update with the result of the update, and send it without saving it?)
|
# (create a new Update with the result of the update, and send it without saving it?)
|
||||||
|
|
||||||
|
@ensure_it_is_me
|
||||||
def outbox_create(self, as_actor: ap.Person, create: ap.Create) -> None:
|
def outbox_create(self, as_actor: ap.Person, create: ap.Create) -> None:
|
||||||
pass
|
self._handle_replies(as_actor, create)
|
||||||
|
|
||||||
|
@ensure_it_is_me
|
||||||
def inbox_create(self, as_actor: ap.Person, create: ap.Create) -> None:
|
def inbox_create(self, as_actor: ap.Person, create: ap.Create) -> None:
|
||||||
pass
|
self._handle_replies(as_actor, create)
|
||||||
|
|
||||||
|
@ensure_it_is_me
|
||||||
|
def _handle_replies_delete(self, as_actor: ap.Person, note: ap.Create) -> None:
|
||||||
|
in_reply_to = note.inReplyTo
|
||||||
|
if not in_reply_to:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not DB.inbox.find_one_and_update(
|
||||||
|
{"activity.object.id": in_reply_to},
|
||||||
|
{"$inc": {"meta.count_reply": -1, "meta.count_direct_reply": -1}},
|
||||||
|
):
|
||||||
|
DB.outbox.update_one(
|
||||||
|
{"activity.object.id": in_reply_to},
|
||||||
|
{"$inc": {"meta.count_reply": -1, "meta.count_direct_reply": -1}},
|
||||||
|
)
|
||||||
|
|
||||||
|
@ensure_it_is_me
|
||||||
|
def _handle_replies(self, as_actor: ap.Person, create: ap.Create) -> None:
|
||||||
|
in_reply_to = create.get_object().inReplyTo
|
||||||
|
if not in_reply_to:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not DB.inbox.find_one_and_update(
|
||||||
|
{"activity.object.id": in_reply_to},
|
||||||
|
{"$inc": {"meta.count_reply": 1, "meta.count_direct_reply": 1}},
|
||||||
|
):
|
||||||
|
DB.outbox.update_one(
|
||||||
|
{"activity.object.id": in_reply_to},
|
||||||
|
{"$inc": {"meta.count_reply": 1, "meta.count_direct_reply": 1}},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def gen_feed():
|
def gen_feed():
|
||||||
|
|
51
app.py
51
app.py
|
@ -553,7 +553,7 @@ def _build_thread(data, include_children=True):
|
||||||
|
|
||||||
@app.route("/note/<note_id>")
|
@app.route("/note/<note_id>")
|
||||||
def note_by_id(note_id):
|
def note_by_id(note_id):
|
||||||
data = DB.outbox.find_one({"id": note_id})
|
data = DB.outbox.find_one({"remote_id": back.activity_url(note_id)})
|
||||||
if not data:
|
if not data:
|
||||||
abort(404)
|
abort(404)
|
||||||
if data["meta"].get("deleted", False):
|
if data["meta"].get("deleted", False):
|
||||||
|
@ -671,17 +671,15 @@ def add_extra_collection(raw_doc: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
|
||||||
raw_doc["activity"]["object"]["replies"] = embed_collection(
|
raw_doc["activity"]["object"]["replies"] = embed_collection(
|
||||||
raw_doc.get("meta", {}).get("count_direct_reply", 0),
|
raw_doc.get("meta", {}).get("count_direct_reply", 0),
|
||||||
f'{ID}/outbox/{raw_doc["id"]}/replies',
|
f'{raw_doc["remote_id"]}/replies',
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_doc["activity"]["object"]["likes"] = embed_collection(
|
raw_doc["activity"]["object"]["likes"] = embed_collection(
|
||||||
raw_doc.get("meta", {}).get("count_like", 0),
|
raw_doc.get("meta", {}).get("count_like", 0), f'{raw_doc["remote_id"]}/likes'
|
||||||
f'{ID}/outbox/{raw_doc["id"]}/likes',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_doc["activity"]["object"]["shares"] = embed_collection(
|
raw_doc["activity"]["object"]["shares"] = embed_collection(
|
||||||
raw_doc.get("meta", {}).get("count_boost", 0),
|
raw_doc.get("meta", {}).get("count_boost", 0), f'{raw_doc["remote_id"]}/shares'
|
||||||
f'{ID}/outbox/{raw_doc["id"]}/shares',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return raw_doc
|
return raw_doc
|
||||||
|
@ -740,7 +738,7 @@ def outbox():
|
||||||
|
|
||||||
@app.route("/outbox/<item_id>")
|
@app.route("/outbox/<item_id>")
|
||||||
def outbox_detail(item_id):
|
def outbox_detail(item_id):
|
||||||
doc = DB.outbox.find_one({"id": item_id})
|
doc = DB.outbox.find_one({"remote_id": back.activity_url(item_id)})
|
||||||
if doc["meta"].get("deleted", False):
|
if doc["meta"].get("deleted", False):
|
||||||
obj = ap.parse_activity(doc["activity"])
|
obj = ap.parse_activity(doc["activity"])
|
||||||
resp = jsonify(**obj.get_object().get_tombstone())
|
resp = jsonify(**obj.get_object().get_tombstone())
|
||||||
|
@ -752,7 +750,9 @@ def outbox_detail(item_id):
|
||||||
@app.route("/outbox/<item_id>/activity")
|
@app.route("/outbox/<item_id>/activity")
|
||||||
def outbox_activity(item_id):
|
def outbox_activity(item_id):
|
||||||
# TODO(tsileo): handle Tombstone
|
# TODO(tsileo): handle Tombstone
|
||||||
data = DB.outbox.find_one({"id": item_id, "meta.deleted": False})
|
data = DB.outbox.find_one(
|
||||||
|
{"remote_id": back.activity_url(item_id), "meta.deleted": False}
|
||||||
|
)
|
||||||
if not data:
|
if not data:
|
||||||
abort(404)
|
abort(404)
|
||||||
obj = activity_from_doc(data)
|
obj = activity_from_doc(data)
|
||||||
|
@ -766,7 +766,9 @@ def outbox_activity_replies(item_id):
|
||||||
# TODO(tsileo): handle Tombstone
|
# TODO(tsileo): handle Tombstone
|
||||||
if not is_api_request():
|
if not is_api_request():
|
||||||
abort(404)
|
abort(404)
|
||||||
data = DB.outbox.find_one({"id": item_id, "meta.deleted": False})
|
data = DB.outbox.find_one(
|
||||||
|
{"remote_id": back.activity_url(item_id), "meta.deleted": False}
|
||||||
|
)
|
||||||
if not data:
|
if not data:
|
||||||
abort(404)
|
abort(404)
|
||||||
obj = ap.parse_activity(data["activity"])
|
obj = ap.parse_activity(data["activity"])
|
||||||
|
@ -796,7 +798,9 @@ def outbox_activity_likes(item_id):
|
||||||
# TODO(tsileo): handle Tombstone
|
# TODO(tsileo): handle Tombstone
|
||||||
if not is_api_request():
|
if not is_api_request():
|
||||||
abort(404)
|
abort(404)
|
||||||
data = DB.outbox.find_one({"id": item_id, "meta.deleted": False})
|
data = DB.outbox.find_one(
|
||||||
|
{"remote_id": back.activity_url(item_id), "meta.deleted": False}
|
||||||
|
)
|
||||||
if not data:
|
if not data:
|
||||||
abort(404)
|
abort(404)
|
||||||
obj = ap.parse_activity(data["activity"])
|
obj = ap.parse_activity(data["activity"])
|
||||||
|
@ -829,7 +833,9 @@ def outbox_activity_shares(item_id):
|
||||||
# TODO(tsileo): handle Tombstone
|
# TODO(tsileo): handle Tombstone
|
||||||
if not is_api_request():
|
if not is_api_request():
|
||||||
abort(404)
|
abort(404)
|
||||||
data = DB.outbox.find_one({"id": item_id, "meta.deleted": False})
|
data = DB.outbox.find_one(
|
||||||
|
{"remote_id": back.activity_url(item_id), "meta.deleted": False}
|
||||||
|
)
|
||||||
if not data:
|
if not data:
|
||||||
abort(404)
|
abort(404)
|
||||||
obj = ap.parse_activity(data["activity"])
|
obj = ap.parse_activity(data["activity"])
|
||||||
|
@ -1007,7 +1013,7 @@ def api_delete():
|
||||||
def api_boost():
|
def api_boost():
|
||||||
note = _user_api_get_note()
|
note = _user_api_get_note()
|
||||||
|
|
||||||
announce = note.build_announce()
|
announce = note.build_announce(MY_PERSON)
|
||||||
OUTBOX.post(announce)
|
OUTBOX.post(announce)
|
||||||
|
|
||||||
return _user_api_response(activity=announce.id)
|
return _user_api_response(activity=announce.id)
|
||||||
|
@ -1018,7 +1024,7 @@ def api_boost():
|
||||||
def api_like():
|
def api_like():
|
||||||
note = _user_api_get_note()
|
note = _user_api_get_note()
|
||||||
|
|
||||||
like = note.build_like()
|
like = note.build_like(MY_PERSON)
|
||||||
OUTBOX.post(like)
|
OUTBOX.post(like)
|
||||||
|
|
||||||
return _user_api_response(activity=like.id)
|
return _user_api_response(activity=like.id)
|
||||||
|
@ -1028,7 +1034,9 @@ def api_like():
|
||||||
@api_required
|
@api_required
|
||||||
def api_undo():
|
def api_undo():
|
||||||
oid = _user_api_arg("id")
|
oid = _user_api_arg("id")
|
||||||
doc = DB.outbox.find_one({"$or": [{"id": oid}, {"remote_id": oid}]})
|
doc = DB.outbox.find_one(
|
||||||
|
{"$or": [{"remote_id": back.activity_url(oid)}, {"remote_id": oid}]}
|
||||||
|
)
|
||||||
if not doc:
|
if not doc:
|
||||||
raise ActivityNotFoundError(f"cannot found {oid}")
|
raise ActivityNotFoundError(f"cannot found {oid}")
|
||||||
|
|
||||||
|
@ -1141,6 +1149,15 @@ def inbox():
|
||||||
return Response(status=201)
|
return Response(status=201)
|
||||||
|
|
||||||
|
|
||||||
|
def without_id(l):
|
||||||
|
out = []
|
||||||
|
for d in l:
|
||||||
|
if "_id" in d:
|
||||||
|
del d["_id"]
|
||||||
|
out.append(d)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/debug", methods=["GET", "DELETE"])
|
@app.route("/api/debug", methods=["GET", "DELETE"])
|
||||||
@api_required
|
@api_required
|
||||||
def api_debug():
|
def api_debug():
|
||||||
|
@ -1152,7 +1169,11 @@ def api_debug():
|
||||||
_drop_db()
|
_drop_db()
|
||||||
return flask_jsonify(message="DB dropped")
|
return flask_jsonify(message="DB dropped")
|
||||||
|
|
||||||
return flask_jsonify(inbox=DB.inbox.count(), outbox=DB.outbox.count())
|
return flask_jsonify(
|
||||||
|
inbox=DB.inbox.count(),
|
||||||
|
outbox=DB.outbox.count(),
|
||||||
|
outbox_data=without_id(DB.outbox.find()),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/upload", methods=["POST"])
|
@app.route("/api/upload", methods=["POST"])
|
||||||
|
|
|
@ -30,10 +30,10 @@ class Instance(object):
|
||||||
api_key = f.read()
|
api_key = f.read()
|
||||||
self._auth_headers = {"Authorization": f"Bearer {api_key}"}
|
self._auth_headers = {"Authorization": f"Bearer {api_key}"}
|
||||||
|
|
||||||
def _do_req(self, url, headers):
|
def _do_req(self, url):
|
||||||
"""Used to parse collection."""
|
"""Used to parse collection."""
|
||||||
url = url.replace(self.docker_url, self.host_url)
|
url = url.replace(self.docker_url, self.host_url)
|
||||||
resp = requests.get(url, headers={'Accept': 'application/actiivty+json'})
|
resp = requests.get(url, headers={'Accept': 'application/activity+json'})
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue