lib.itmens/journal/models/comment.py

156 lines
5 KiB
Python
Raw Normal View History

2023-07-20 21:59:49 -04:00
from datetime import datetime
from functools import cached_property
2024-06-14 00:17:27 -04:00
from django.conf import settings
from django.db import models
from django.utils import timezone
2024-06-14 00:17:27 -04:00
from django.utils.translation import gettext as _
from catalog.models import Item
2024-06-13 20:44:15 -04:00
from takahe.utils import Takahe
2023-07-20 21:59:49 -04:00
from users.models import APIdentity
from .common import Content
from .rating import Rating
2024-06-14 00:17:27 -04:00
from .renderers import (
render_post_with_macro,
render_rating,
render_spoiler_text,
render_text,
)
from .shelf import ShelfManager, ShelfType
class Comment(Content):
text = models.TextField(blank=False, null=False)
2023-07-20 21:59:49 -04:00
@property
def ap_object(self):
2023-11-19 15:19:49 -05:00
d = {
2023-07-20 21:59:49 -04:00
"id": self.absolute_url,
"type": "Comment",
"content": self.text,
"published": self.created_time.isoformat(),
"updated": self.edited_time.isoformat(),
"attributedTo": self.owner.actor_uri,
2023-11-28 08:45:04 -05:00
"withRegardTo": self.item.absolute_url,
"href": self.absolute_url,
2023-07-20 21:59:49 -04:00
}
2023-11-19 15:19:49 -05:00
if self.metadata.get("position"):
d["relatedWithItemPosition"] = self.metadata["position"]
d["relatedWithItemPositionType"] = "time"
return d
2023-07-20 21:59:49 -04:00
@classmethod
2024-06-13 20:44:15 -04:00
def update_by_ap_object(cls, owner, item, obj, post):
2023-11-20 19:11:02 -05:00
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
2023-07-20 21:59:49 -04:00
content = obj.get("content", "").strip() if obj else ""
if not content:
cls.objects.filter(owner=owner, item=item).delete()
return
d = {
"text": content,
"local": False,
"remote_id": obj["id"],
2024-06-13 20:44:15 -04:00
"visibility": Takahe.visibility_t2n(post.visibility),
2023-07-20 21:59:49 -04:00
"created_time": datetime.fromisoformat(obj["published"]),
"edited_time": datetime.fromisoformat(obj["updated"]),
}
2023-11-19 15:19:49 -05:00
if obj.get("relatedWithItemPosition"):
d["metadata"] = {"position": obj["relatedWithItemPosition"]}
2023-07-20 21:59:49 -04:00
p, _ = cls.objects.update_or_create(owner=owner, item=item, defaults=d)
2024-06-13 20:44:15 -04:00
p.link_post_id(post.id)
2023-07-20 21:59:49 -04:00
return p
@property
def html(self):
return render_text(self.text)
@cached_property
def rating_grade(self):
2023-07-20 21:59:49 -04:00
return Rating.get_item_rating(self.item, self.owner)
@cached_property
def mark(self):
from .mark import Mark
m = Mark(self.owner, self.item)
m.comment = self
return m
@property
def item_url(self):
if self.metadata.get("position"):
2023-11-19 15:19:49 -05:00
return self.item.get_url_with_position(self.metadata["position"])
else:
return self.item.url
@staticmethod
2023-07-20 21:59:49 -04:00
def comment_item(
item: Item, owner: APIdentity, text: str | None, visibility=0, created_time=None
):
2023-07-20 21:59:49 -04:00
comment = Comment.objects.filter(owner=owner, item=item).first()
if not text:
if comment is not None:
comment.delete()
comment = None
elif comment is None:
comment = Comment.objects.create(
2023-07-20 21:59:49 -04:00
owner=owner,
item=item,
text=text,
visibility=visibility,
created_time=created_time or timezone.now(),
)
elif comment.text != text or comment.visibility != visibility:
comment.text = text
comment.visibility = visibility
if created_time:
comment.created_time = created_time
comment.save()
return comment
2024-06-14 00:17:27 -04:00
2024-06-16 21:54:20 -04:00
def get_crosspost_postfix(self):
2024-06-14 00:17:27 -04:00
tags = render_post_with_macro(
self.owner.user.preference.mastodon_append_tag, self.item
)
return "\n" + tags if tags else ""
2024-06-16 21:54:20 -04:00
def get_crosspost_template(self):
2024-06-14 00:17:27 -04:00
return _(
ShelfManager.get_action_template(ShelfType.PROGRESS, self.item.category)
)
def to_mastodon_params(self):
spoiler_text, txt = render_spoiler_text(self.text, self.item)
content = (
2024-06-16 21:54:20 -04:00
self.get_crosspost_template().format(item=self.item.display_title)
2024-06-14 00:17:27 -04:00
+ f"\n{txt}\n{settings.SITE_INFO['site_url']}{self.item_url}"
2024-06-16 21:54:20 -04:00
+ self.get_crosspost_postfix()
2024-06-14 00:17:27 -04:00
)
params = {
"content": content,
"spoiler_text": spoiler_text,
"sensitive": bool(spoiler_text),
}
return params
def to_post_params(self):
item_link = f"{settings.SITE_INFO['site_url']}/~neodb~{self.item_url}"
2024-06-15 21:54:39 -04:00
prepend_content = (
2024-06-16 21:54:20 -04:00
self.get_crosspost_template().format(
2024-06-14 00:17:27 -04:00
item=f'<a href="{item_link}">{self.item.display_title}</a>'
)
+ "<br>"
)
spoiler_text, txt = render_spoiler_text(self.text, self.item)
2024-06-16 21:54:20 -04:00
content = f"{txt}\n{self.get_crosspost_postfix()}"
2024-06-14 00:17:27 -04:00
return {
2024-06-15 21:54:39 -04:00
"prepend_content": prepend_content,
2024-06-14 00:17:27 -04:00
"content": content,
"summary": spoiler_text,
"sensitive": bool(spoiler_text),
}