lib.itmens/journal/views/review.py

181 lines
5.9 KiB
Python
Raw Permalink Normal View History

2023-08-10 14:56:38 -04:00
import mimetypes
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.syndication.views import Feed
2024-02-25 23:04:50 -05:00
from django.core.exceptions import BadRequest, PermissionDenied
from django.http import Http404
2023-08-10 14:56:38 -04:00
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.utils.dateparse import parse_datetime
2024-06-07 22:29:10 -04:00
from django.utils.translation import gettext as _
2023-12-25 17:27:31 -05:00
from django.views.decorators.http import require_http_methods
2023-08-10 14:56:38 -04:00
from catalog.models import *
2023-12-30 22:20:15 -05:00
from common.utils import AuthedHttpRequest, get_uuid_or_404
from journal.models.renderers import convert_leading_space_in_md, has_spoiler, render_md
from users.middlewares import activate_language_for_user
2023-07-20 21:59:49 -04:00
from users.models.apidentity import APIdentity
2023-08-10 14:56:38 -04:00
from ..forms import *
from ..models import *
from .common import render_list
2023-12-25 17:27:31 -05:00
@require_http_methods(["GET"])
2023-08-10 14:56:38 -04:00
def review_retrieve(request, review_uuid):
# piece = get_object_or_404(Review, uid=get_uuid_or_404(review_uuid))
piece = Review.get_by_url(review_uuid)
if piece is None:
2024-04-23 23:57:49 -04:00
raise Http404(_("Content not found"))
2023-08-10 14:56:38 -04:00
if not piece.is_visible_to(request.user):
2024-04-23 23:57:49 -04:00
raise PermissionDenied(_("Insufficient permission"))
2023-08-10 14:56:38 -04:00
return render(request, "review.html", {"review": piece})
@login_required
2024-04-23 23:57:49 -04:00
@require_http_methods(["GET", "POST"])
2023-07-20 21:59:49 -04:00
def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
2023-08-10 14:56:38 -04:00
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
review = (
get_object_or_404(Review, uid=get_uuid_or_404(review_uuid))
if review_uuid
else None
)
if review and not review.is_editable_by(request.user):
2024-04-23 23:57:49 -04:00
raise PermissionDenied(_("Insufficient permission"))
2023-08-10 14:56:38 -04:00
if request.method == "GET":
form = (
ReviewForm(instance=review)
if review
2023-12-27 17:37:04 -05:00
else ReviewForm(
initial={
"item": item.pk,
2023-12-27 17:37:04 -05:00
"share_to_mastodon": request.user.preference.mastodon_default_repost,
}
)
2023-08-10 14:56:38 -04:00
)
return render(
request,
"review_edit.html",
{
"form": form,
"item": item,
"date_today": timezone.localdate().isoformat(),
},
)
2024-04-23 23:57:49 -04:00
else:
2023-08-10 14:56:38 -04:00
form = (
ReviewForm(request.POST, instance=review)
if review
else ReviewForm(request.POST)
)
if form.is_valid():
mark_date = None
if request.POST.get("mark_anotherday"):
2023-07-20 21:59:49 -04:00
dt = parse_datetime(request.POST.get("mark_date", "") + " 20:00:00")
2023-08-10 14:56:38 -04:00
mark_date = (
dt.replace(tzinfo=timezone.get_current_timezone()) if dt else None
)
body = form.instance.body
if request.POST.get("leading_space"):
body = convert_leading_space_in_md(body)
2023-12-27 17:29:21 -05:00
review = Review.update_item_review(
2023-08-10 14:56:38 -04:00
item,
2023-07-20 21:59:49 -04:00
request.user.identity,
2023-08-10 14:56:38 -04:00
form.cleaned_data["title"],
body,
form.cleaned_data["visibility"],
mark_date,
2023-12-27 17:29:21 -05:00
form.cleaned_data["share_to_mastodon"],
2023-08-10 14:56:38 -04:00
)
if not review:
2024-04-23 23:57:49 -04:00
raise BadRequest(_("Invalid parameter"))
2023-08-10 14:56:38 -04:00
return redirect(reverse("journal:review_retrieve", args=[review.uuid]))
else:
2024-04-23 23:57:49 -04:00
raise BadRequest(_("Invalid parameter"))
2023-08-10 14:56:38 -04:00
2023-12-30 22:20:15 -05:00
def user_review_list(request, user_name, item_category):
return render_list(request, user_name, "review", item_category=item_category)
2023-08-10 14:56:38 -04:00
MAX_ITEM_PER_TYPE = 10
class ReviewFeed(Feed):
2023-12-31 08:32:19 -05:00
def get_object(self, request, *args, **kwargs):
o = APIdentity.get_by_handle(kwargs["username"], match_linked=True)
activate_language_for_user(o.user)
return o
2023-08-10 14:56:38 -04:00
2023-07-20 21:59:49 -04:00
def title(self, owner):
2024-03-24 22:28:22 -04:00
return (
_("Reviews by {0}").format(owner.display_name)
if owner
2024-04-23 23:57:49 -04:00
else _("Link invalid")
2024-03-24 22:28:22 -04:00
)
2023-08-10 14:56:38 -04:00
def link(self, owner: APIdentity):
2023-07-20 21:59:49 -04:00
return owner.url if owner else settings.SITE_INFO["site_url"]
2023-08-10 14:56:38 -04:00
def description(self, owner: APIdentity):
2023-12-31 08:32:19 -05:00
if not owner:
2024-04-23 23:57:49 -04:00
return _("Link invalid")
2023-12-31 08:32:19 -05:00
elif not owner.anonymous_viewable:
2024-04-23 23:57:49 -04:00
return _("Login required")
2023-12-31 08:32:19 -05:00
else:
2024-03-24 22:28:22 -04:00
return _("Reviews by {0}").format(owner.display_name)
2023-08-10 14:56:38 -04:00
def items(self, owner: APIdentity):
2023-12-29 18:10:44 -05:00
if owner is None or not owner.anonymous_viewable:
2023-08-10 14:56:38 -04:00
return []
2023-12-29 18:10:44 -05:00
reviews = Review.objects.filter(owner=owner, visibility=0)[:MAX_ITEM_PER_TYPE]
2023-08-10 14:56:38 -04:00
return reviews
def item_title(self, item: Review):
s = _("{review_title} - a review of {item_title}").format(
2024-03-24 22:28:22 -04:00
review_title=item.title, item_title=item.item.title
)
if has_spoiler(item.body):
s += " (" + _("may contain spoiler or triggering content") + ")"
return s
2023-08-10 14:56:38 -04:00
def item_description(self, item: Review):
target_html = (
f'<p><a href="{item.item.absolute_url}">{item.item.title}</a></p>\n'
)
html = render_md(item.body)
return target_html + html
# item_link is only needed if NewsItem has no get_absolute_url method.
def item_link(self, item: Review):
2023-12-31 08:32:19 -05:00
return str(item.absolute_url)
2023-08-10 14:56:38 -04:00
def item_categories(self, item):
return [item.item.category.label]
def item_pubdate(self, item):
return item.created_time
def item_updateddate(self, item):
return item.edited_time
def item_enclosure_url(self, item):
return item.item.cover.url
def item_enclosure_mime_type(self, item):
t, _ = mimetypes.guess_type(item.item.cover.url)
return t
def item_enclosure_length(self, item):
try:
size = item.item.cover.file.size
except Exception:
size = None
return size
def item_comments(self, item):
return item.absolute_url