delete from remote post

This commit is contained in:
Her Email 2023-11-20 19:11:02 -05:00 committed by Henri Dickson
parent 7eeabdbf20
commit 476a8bca35
10 changed files with 45 additions and 19 deletions

View file

@ -34,6 +34,9 @@ class Comment(Content):
@classmethod @classmethod
def update_by_ap_object(cls, owner, item, obj, post_id, visibility): def update_by_ap_object(cls, owner, item, obj, post_id, visibility):
p = cls.objects.filter(owner=owner, item=item).first()
if p and p.edited_time >= datetime.fromisoformat(obj["updated"]):
return p # incoming ap object is older than what we have, no update needed
content = obj.get("content", "").strip() if obj else "" content = obj.get("content", "").strip() if obj else ""
if not content: if not content:
cls.objects.filter(owner=owner, item=item).delete() cls.objects.filter(owner=owner, item=item).delete()

View file

@ -198,10 +198,15 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
PiecePost.objects.filter(piece=self).delete() PiecePost.objects.filter(piece=self).delete()
@cached_property @cached_property
def latest_post(self): def latest_post_id(self):
# local post id is ordered by their created time # post id is ordered by their created time
pp = PiecePost.objects.filter(piece=self).order_by("-post_id").first() pp = PiecePost.objects.filter(piece=self).order_by("-post_id").first()
return Takahe.get_post(pp.post_id) if pp else None # type: ignore return pp.post_id if pp else None
@cached_property
def latest_post(self):
pk = self.latest_post_id
return Takahe.get_post(pk) if pk else None
@cached_property @cached_property
def all_post_ids(self): def all_post_ids(self):
@ -212,6 +217,7 @@ class Piece(PolymorphicModel, UserOwnedObjectMixin):
class PiecePost(models.Model): class PiecePost(models.Model):
post_id: int
piece = models.ForeignKey(Piece, on_delete=models.CASCADE) piece = models.ForeignKey(Piece, on_delete=models.CASCADE)
post = models.ForeignKey( post = models.ForeignKey(
"takahe.Post", db_constraint=False, db_index=True, on_delete=models.CASCADE "takahe.Post", db_constraint=False, db_index=True, on_delete=models.CASCADE

View file

@ -39,6 +39,9 @@ class Rating(Content):
@classmethod @classmethod
def update_by_ap_object(cls, owner, item, obj, post_id, visibility): def update_by_ap_object(cls, owner, item, obj, post_id, visibility):
p = cls.objects.filter(owner=owner, item=item).first()
if p and p.edited_time >= datetime.fromisoformat(obj["updated"]):
return p # incoming ap object is older than what we have, no update needed
value = obj.get("value", 0) if obj else 0 value = obj.get("value", 0) if obj else 0
if not value: if not value:
cls.objects.filter(owner=owner, item=item).delete() cls.objects.filter(owner=owner, item=item).delete()

View file

@ -53,6 +53,9 @@ class Review(Content):
@classmethod @classmethod
def update_by_ap_object(cls, owner, item, obj, post_id, visibility): def update_by_ap_object(cls, owner, item, obj, post_id, visibility):
p = cls.objects.filter(owner=owner, item=item).first()
if p and p.edited_time >= datetime.fromisoformat(obj["updated"]):
return p # incoming ap object is older than what we have, no update needed
content = ( content = (
obj["content"] obj["content"]
if obj.get("mediaType") == "text/markdown" if obj.get("mediaType") == "text/markdown"

View file

@ -80,10 +80,9 @@ class ShelfMember(ListMember):
def update_by_ap_object( def update_by_ap_object(
cls, owner: APIdentity, item: Identity, obj: dict, post_id: int, visibility: int cls, owner: APIdentity, item: Identity, obj: dict, post_id: int, visibility: int
): ):
# TODO check timestamp? (update may come in with inconsistent sequence) p = cls.objects.filter(owner=owner, item=item).first()
if not obj: if p and p.edited_time >= datetime.fromisoformat(obj["updated"]):
cls.objects.filter(owner=owner, item=item).delete() return p # incoming ap object is older than what we have, no update needed
return
shelf = owner.shelf_manager.get_shelf(obj["status"]) shelf = owner.shelf_manager.get_shelf(obj["status"])
if not shelf: if not shelf:
logger.warning(f"unable to locate shelf for {owner}, {obj}") logger.warning(f"unable to locate shelf for {owner}, {obj}")
@ -147,7 +146,8 @@ class ShelfMember(ListMember):
self.delete() self.delete()
def link_post_id(self, post_id: int): def link_post_id(self, post_id: int):
self.ensure_log_entry().link_post_id(post_id) if self.local:
self.ensure_log_entry().link_post_id(post_id)
return super().link_post_id(post_id) return super().link_post_id(post_id)

View file

@ -25,7 +25,7 @@ def like_piece_action(context, piece):
action = {} action = {}
if user and user.is_authenticated and piece and piece.latest_post: if user and user.is_authenticated and piece and piece.latest_post:
action = { action = {
"taken": Takahe.post_liked_by(piece.latest_post.pk, user), "taken": Takahe.post_liked_by(piece.latest_post.pk, user.identity.pk),
"url": reverse("journal:like", args=[piece.uuid]), "url": reverse("journal:like", args=[piece.uuid]),
} }
return action return action

@ -1 +1 @@
Subproject commit a8f8f9d5931b062d1b8bb9455db7e7f0ad79ff41 Subproject commit bb145fa4ae8d68810ee1963e9b24b3e7623a7069

View file

@ -11,12 +11,10 @@
{% load duration %} {% load duration %}
{% wish_item_action activity.action_object.item as action %} {% wish_item_action activity.action_object.item as action %}
<span class="action"> <span class="action">
{% if activity.action_object.mark.comment_text %} <span>
<span> {% liked_piece activity.action_object as liked %}
{% liked_piece activity.action_object.mark.comment as liked %} {% include 'like_stats.html' with liked=liked piece=activity.action_object %}
{% include 'like_stats.html' with liked=liked piece=activity.action_object.mark.comment %} </span>
</span>
{% endif %}
{% comment %} {% comment %}
<span> <span>
<a><i class="fa-solid fa-circle-play"></i></a> <a><i class="fa-solid fa-circle-play"></i></a>

View file

@ -24,7 +24,7 @@
<a href="{{ activity.owner.url }}" class="nickname">{{ activity.owner.display_name }}</a> <a href="{{ activity.owner.url }}" class="nickname">{{ activity.owner.display_name }}</a>
</span> </span>
<span> <span>
<a href="{{ activity.owner.url }}" class="handler">@{{ activity.owner.handler }}</a> <a href="{{ activity.owner.url }}" class="handler">{{ activity.owner.handler }}</a>
</span> </span>
</div> </div>
{% with "activity/"|add:activity.template|add:".html" as template %} {% with "activity/"|add:activity.template|add:".html" as template %}

View file

@ -61,12 +61,16 @@ def _get_or_create_item(item_obj):
if typ in ["TVEpisode", "PodcastEpisode"]: if typ in ["TVEpisode", "PodcastEpisode"]:
# TODO support episode item # TODO support episode item
# match and fetch parent item first # match and fetch parent item first
logger.debug(f"{typ}:{url} not supported yet")
return None return None
site = SiteManager.get_site_by_url(url) site = SiteManager.get_site_by_url(url)
if not site: if not site:
logger.warning(f"Site not found for {url}")
return None return None
site.get_resource_ready() site.get_resource_ready()
item = site.get_item() item = site.get_item()
if not item:
logger.warning(f"Item not fetched for {url}")
return item return item
@ -100,12 +104,21 @@ def post_fetched(pk, obj):
logger.warning(f"Post {post} has no local item matched or created") logger.warning(f"Post {post} has no local item matched or created")
return return
for p in pieces: for p in pieces:
cls = _supported_ap_journal_types[p["type"]] cls = _supported_ap_journal_types.get(p["type"])
if not cls:
logger.warning(f'Unknown link type {p["type"]}')
continue
cls.update_by_ap_object(owner, item, p, pk, _get_visibility(post.visibility)) cls.update_by_ap_object(owner, item, p, pk, _get_visibility(post.visibility))
def post_deleted(pk, obj): def post_deleted(pk, obj):
Piece.objects.filter(posts__id=pk, local=False).delete() for piece in Piece.objects.filter(posts__id=pk, local=False):
# delete piece if the deleted post is the most recent one for the piece
if piece.latest_post_id == pk:
logger.debug(f"Deleting remote piece {piece}")
piece.delete()
else:
logger.debug(f"Matched remote piece {piece} has newer posts, not deleting")
def identity_fetched(pk): def identity_fetched(pk):