diff --git a/common/models/index.py b/common/models/index.py
index 7e94a401..1a57226c 100644
--- a/common/models/index.py
+++ b/common/models/index.py
@@ -118,8 +118,8 @@ class Index:
def delete_collection(self):
self.write_collection.delete()
- def update_schema(self):
- self.write_collection.update(self.get_schema())
+ def update_schema(self, schema: dict):
+ self.write_collection.update(schema)
def initialize_collection(self, max_wait=5) -> bool:
try:
diff --git a/journal/management/commands/journal.py b/journal/management/commands/journal.py
index 61205a40..36cd9860 100644
--- a/journal/management/commands/journal.py
+++ b/journal/management/commands/journal.py
@@ -157,8 +157,8 @@ class Command(BaseCommand):
self.stdout.write(self.style.SUCCESS("deleted."))
case "idx-alt":
- index.update_schema()
- self.stdout.write(self.style.SUCCESS("updated."))
+ # index.update_schema()
+ self.stdout.write(self.style.SUCCESS("not implemented."))
case "idx-init":
index.initialize_collection()
diff --git a/journal/models/index.py b/journal/models/index.py
index 98200097..4f2ede26 100644
--- a/journal/models/index.py
+++ b/journal/models/index.py
@@ -137,12 +137,14 @@ class JournalIndex(Index):
"type": "string[]",
"locale": "zh",
"optional": True,
+ # "store": False,
},
{
"name": "content",
"type": "string[]",
"locale": "zh",
"optional": True,
+ # "store": False,
},
{
"name": "shelf_type",
@@ -264,6 +266,10 @@ class JournalIndex(Index):
def delete_by_post(self, post_ids):
return self.delete_docs("post_id", post_ids)
+ def replace_posts(self, posts: Iterable[Post]):
+ docs = self.posts_to_docs(posts)
+ self.replace_docs(docs)
+
def replace_pieces(self, pieces: "Iterable[Piece] | QuerySet[Piece]"):
if isinstance(pieces, QuerySet):
pids = pieces.values_list("pk", flat=True)
diff --git a/neodb-takahe b/neodb-takahe
index df6f939a..616e9138 160000
--- a/neodb-takahe
+++ b/neodb-takahe
@@ -1 +1 @@
-Subproject commit df6f939a73512ac8a8c01e0e78bc0d5e8ffe3e6d
+Subproject commit 616e91382829866531c62e1b24f0e6e4595ab27d
diff --git a/social/templates/feed_events.html b/social/templates/feed_events.html
index 24ba272b..1d17f88a 100644
--- a/social/templates/feed_events.html
+++ b/social/templates/feed_events.html
@@ -125,7 +125,7 @@
{% if forloop.last %}
@@ -133,7 +133,7 @@
{% endif %}
{% empty %}
- {% if request.GET.last or request.GET.nextpage %}
+ {% if request.GET.last or page > 1 %}
{% trans 'nothing more.' %}
{% elif request.GET.q %}
{% trans 'no matching activities.' %}
diff --git a/social/views.py b/social/views.py
index 660ea3f5..f37e4f1e 100644
--- a/social/views.py
+++ b/social/views.py
@@ -78,7 +78,7 @@ def data(request):
typ = int_(request.GET.get("typ", 0))
q = request.GET.get("q")
identity_id = request.user.identity.pk
- page = int_(request.GET.get("page", 1))
+ page = int_(request.GET.get("lastpage")) + 1
if q:
q = QueryParser(request.GET.get("q", default=""))
index = JournalIndex.instance()
@@ -149,7 +149,7 @@ def data(request):
return render(
request,
"feed_events.html",
- {"feed_type": typ, "events": events, "nextpage": page + 1},
+ {"feed_type": typ, "events": events, "page": page},
)
diff --git a/takahe/ap_handlers.py b/takahe/ap_handlers.py
index 48a9fc98..31c12df6 100644
--- a/takahe/ap_handlers.py
+++ b/takahe/ap_handlers.py
@@ -14,6 +14,7 @@ from journal.models import (
Review,
ShelfMember,
)
+from journal.models.index import JournalIndex
from users.middlewares import activate_language_for_user
from users.models.apidentity import APIdentity
@@ -92,30 +93,61 @@ def _get_or_create_item(item_obj) -> Item | None:
def post_created(pk, post_data):
- return post_fetched(pk, post_data)
+ return _post_fetched(pk, True, post_data)
def post_edited(pk, post_data):
- return post_fetched(pk, post_data)
+ return _post_fetched(pk, True, post_data, False)
def post_fetched(pk, post_data):
- post = Post.objects.get(pk=pk)
+ return _post_fetched(pk, False, post_data, True)
+
+
+def _post_fetched(pk, local, post_data, create: bool | None = None):
+ post: Post = Post.objects.get(pk=pk)
owner = Takahe.get_or_create_remote_apidentity(post.author)
- activate_language_for_user(owner.user)
- if not post.type_data and not post_data:
- logger.warning(f"Post {post} has no type_data")
- return
- ap_objects = post_data or post.type_data.get("object", {})
- items = _parse_items(ap_objects.get("tag"))
- pieces = _parse_piece_objects(ap_objects.get("relatedWith"))
- logger.info(f"Post {post} has items {items} and pieces {pieces}")
+ if local:
+ activate_language_for_user(owner.user)
+ reply_to = post.in_reply_to_post()
+ items = []
+ pieces = []
+ if post_data and "raw_content" in post_data:
+ # Local post, extract info for Note if possible
+ if (
+ reply_to
+ and reply_to.author_id == post.author_id
+ and reply_to.type_data
+ and "object" in reply_to.type_data
+ and "relatedWith" in reply_to.type_data["object"]
+ ):
+ items = _parse_items(reply_to.type_data["object"].get("tag", []))
+ elif (
+ not create
+ and post.type_data
+ and "object" in post.type_data
+ and "relatedWith" in post.type_data["object"]
+ ):
+ items = _parse_items(post.type_data["object"].get("tag", []))
+ pieces = [{"type": "Note", "content": post_data["raw_content"]}]
+ if not items or not pieces:
+ # Local post has no related items or usable pieces, update index and move on
+ JournalIndex.instance().replace_posts([post])
+ return
+ else:
+ if not post.type_data and not post_data:
+ logger.warning(f"Remote post {post} has no type_data")
+ return
+ ap_objects = post_data or post.type_data.get("object", {})
+ items = _parse_items(ap_objects.get("tag"))
+ pieces = _parse_piece_objects(ap_objects.get("relatedWith"))
if len(items) == 0:
- logger.warning(f"Post {post} has no remote items")
+ logger.warning(f"Post {post} has no items")
return
elif len(items) > 1:
- logger.warning(f"Post {post} has more than one remote item")
+ logger.warning(f"Post {post} has more than one item")
return
+ logger.info(f"Post {post} has items {items} and pieces {pieces}")
item = _get_or_create_item(items[0])
if not item:
logger.warning(f"Post {post} has no local item matched or created")
@@ -128,7 +160,7 @@ def post_fetched(pk, post_data):
cls.update_by_ap_object(owner, item, p, post)
-def post_deleted(pk, post_data):
+def post_deleted(pk, local, post_data):
for piece in Piece.objects.filter(posts__id=pk):
if piece.local and piece.__class__ != Note:
# no delete other than Note, for backward compatibility, should reconsider later