2023-07-20 21:59:49 -04:00
|
|
|
from datetime import datetime
|
2023-08-10 11:27:31 -04:00
|
|
|
from functools import cached_property
|
|
|
|
|
2024-06-14 00:17:27 -04:00
|
|
|
from django.conf import settings
|
2023-08-10 11:27:31 -04:00
|
|
|
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 _
|
2023-08-10 11:27:31 -04:00
|
|
|
|
|
|
|
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
|
2023-08-10 11:27:31 -04:00
|
|
|
|
|
|
|
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
|
2023-08-10 11:27:31 -04:00
|
|
|
|
|
|
|
|
|
|
|
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,
|
2023-11-17 22:46:31 -05:00
|
|
|
"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
|
|
|
|
|
2023-08-10 11:27:31 -04:00
|
|
|
@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)
|
2023-08-10 11:27:31 -04:00
|
|
|
|
|
|
|
@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"])
|
2023-08-10 11:27:31 -04:00
|
|
|
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-08-10 11:27:31 -04:00
|
|
|
):
|
2023-07-20 21:59:49 -04:00
|
|
|
comment = Comment.objects.filter(owner=owner, item=item).first()
|
2023-08-10 11:27:31 -04:00
|
|
|
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,
|
2023-08-10 11:27:31 -04:00
|
|
|
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),
|
|
|
|
}
|