delete from remote post
This commit is contained in:
parent
7eeabdbf20
commit
476a8bca35
10 changed files with 45 additions and 19 deletions
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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>
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Add table
Reference in a new issue