2024-03-02 17:13:05 -05:00
|
|
|
from django.contrib.auth.decorators import login_required
|
2023-08-10 11:27:31 -04:00
|
|
|
from django.core.cache import cache
|
2022-12-15 17:29:35 -05:00
|
|
|
from django.core.paginator import Paginator
|
2023-08-10 11:27:31 -04:00
|
|
|
from django.db.models import Count
|
|
|
|
from django.http import Http404
|
|
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
2023-09-03 20:11:46 +00:00
|
|
|
from django.urls import reverse
|
2024-03-02 17:13:05 -05:00
|
|
|
from django.utils import timezone
|
2023-08-10 11:27:31 -04:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2023-02-10 15:56:13 -05:00
|
|
|
from django.views.decorators.clickjacking import xframe_options_exempt
|
2023-08-22 17:13:52 +00:00
|
|
|
from django.views.decorators.http import require_http_methods
|
2023-08-10 11:27:31 -04:00
|
|
|
|
2023-12-09 16:25:41 -05:00
|
|
|
from common.utils import PageLinksGenerator, get_uuid_or_404, user_identity_required
|
2023-01-07 00:35:30 -05:00
|
|
|
from journal.models import (
|
2024-06-02 15:58:37 -04:00
|
|
|
Collection,
|
2023-08-10 11:27:31 -04:00
|
|
|
Comment,
|
|
|
|
Mark,
|
|
|
|
Review,
|
2024-04-03 23:10:21 -04:00
|
|
|
ShelfManager,
|
2023-08-10 11:27:31 -04:00
|
|
|
ShelfMember,
|
|
|
|
ShelfType,
|
2023-07-20 21:59:49 -04:00
|
|
|
q_piece_in_home_feed_of_user,
|
|
|
|
q_piece_visible_to_user,
|
2023-01-07 00:35:30 -05:00
|
|
|
)
|
2024-06-03 07:27:44 -04:00
|
|
|
from takahe.utils import Takahe
|
2024-06-03 07:53:59 -04:00
|
|
|
from users.views import announcements
|
2023-08-10 11:27:31 -04:00
|
|
|
|
2023-01-05 03:06:13 -05:00
|
|
|
from .forms import *
|
2023-08-10 11:27:31 -04:00
|
|
|
from .models import *
|
2023-01-05 03:06:13 -05:00
|
|
|
from .search.views import *
|
2023-06-19 15:40:27 -04:00
|
|
|
from .views_edit import *
|
2022-12-15 17:29:35 -05:00
|
|
|
|
2022-12-24 01:28:24 -05:00
|
|
|
NUM_REVIEWS_ON_ITEM_PAGE = 5
|
|
|
|
NUM_REVIEWS_ON_LIST_PAGE = 20
|
|
|
|
|
|
|
|
|
|
|
|
def retrieve_by_uuid(request, item_uid):
|
|
|
|
item = get_object_or_404(Item, uid=item_uid)
|
2022-12-17 02:04:12 -05:00
|
|
|
return redirect(item.url)
|
|
|
|
|
|
|
|
|
2023-12-25 11:05:09 -05:00
|
|
|
def retrieve_redirect(request, item_path, item_uuid):
|
2023-12-26 18:57:09 -05:00
|
|
|
return redirect(f"/{item_path}/{item_uuid}", permanent=True)
|
2023-12-25 11:05:09 -05:00
|
|
|
|
|
|
|
|
2023-12-25 17:27:31 -05:00
|
|
|
@require_http_methods(["GET"])
|
2023-02-10 15:56:13 -05:00
|
|
|
@xframe_options_exempt
|
|
|
|
def embed(request, item_path, item_uuid):
|
|
|
|
item = Item.get_by_url(item_uuid)
|
|
|
|
if item is None:
|
2024-04-23 23:57:49 -04:00
|
|
|
raise Http404(_("Item not found"))
|
2023-02-10 15:56:13 -05:00
|
|
|
if item.merged_to_item:
|
|
|
|
return redirect(item.merged_to_item.url)
|
|
|
|
if item.is_deleted:
|
2024-04-23 23:57:49 -04:00
|
|
|
raise Http404(_("Item no longer exists"))
|
2023-02-10 15:56:13 -05:00
|
|
|
focus_item = None
|
|
|
|
if request.GET.get("focus"):
|
|
|
|
focus_item = get_object_or_404(
|
2023-04-18 14:05:36 -04:00
|
|
|
Item, uid=get_uuid_or_404(request.GET.get("focus"))
|
2022-12-15 17:29:35 -05:00
|
|
|
)
|
2023-02-10 15:56:13 -05:00
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
"embed_" + item.class_name + ".html",
|
|
|
|
{"item": item, "focus_item": focus_item},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-12-25 18:48:45 -05:00
|
|
|
@require_http_methods(["GET", "HEAD"])
|
2023-12-09 16:25:41 -05:00
|
|
|
@user_identity_required
|
2023-02-10 15:56:13 -05:00
|
|
|
def retrieve(request, item_path, item_uuid):
|
2023-04-18 14:05:36 -04:00
|
|
|
# item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
2023-02-10 15:56:13 -05:00
|
|
|
item = Item.get_by_url(item_uuid)
|
|
|
|
if item is None:
|
2024-04-23 23:57:49 -04:00
|
|
|
raise Http404(_("Item not found"))
|
2023-02-10 15:56:13 -05:00
|
|
|
item_url = f"/{item_path}/{item_uuid}"
|
|
|
|
if item.url != item_url:
|
|
|
|
return redirect(item.url)
|
2023-06-12 15:07:55 -04:00
|
|
|
skipcheck = request.GET.get("skipcheck", False) and request.user.is_authenticated
|
2023-02-10 15:56:13 -05:00
|
|
|
if not skipcheck and item.merged_to_item:
|
|
|
|
return redirect(item.merged_to_item.url)
|
|
|
|
if not skipcheck and item.is_deleted:
|
2024-04-23 23:57:49 -04:00
|
|
|
raise Http404(_("Item no longer exists"))
|
2023-11-20 18:11:16 -05:00
|
|
|
if request.headers.get("Accept", "").endswith("json"):
|
|
|
|
return redirect(item.api_url)
|
2023-02-10 15:56:13 -05:00
|
|
|
focus_item = None
|
|
|
|
if request.GET.get("focus"):
|
|
|
|
focus_item = get_object_or_404(
|
2023-04-18 14:05:36 -04:00
|
|
|
Item, uid=get_uuid_or_404(request.GET.get("focus"))
|
2023-02-10 15:56:13 -05:00
|
|
|
)
|
|
|
|
mark = None
|
|
|
|
review = None
|
2023-05-20 11:01:18 -04:00
|
|
|
my_collections = []
|
2023-02-10 15:56:13 -05:00
|
|
|
collection_list = []
|
2023-06-18 20:53:10 -04:00
|
|
|
child_item_comments = []
|
2024-04-03 23:10:21 -04:00
|
|
|
shelf_actions = ShelfManager.get_actions_for_category(item.category)
|
2024-05-29 10:50:41 -04:00
|
|
|
shelf_statuses = ShelfManager.get_statuses_for_category(item.category)
|
2023-02-10 15:56:13 -05:00
|
|
|
if request.user.is_authenticated:
|
2023-07-20 21:59:49 -04:00
|
|
|
visible = q_piece_visible_to_user(request.user)
|
|
|
|
mark = Mark(request.user.identity, item)
|
2023-06-18 20:53:10 -04:00
|
|
|
child_item_comments = Comment.objects.filter(
|
2023-07-20 21:59:49 -04:00
|
|
|
owner=request.user.identity, item__in=item.child_items.all()
|
2023-06-18 20:53:10 -04:00
|
|
|
)
|
2023-02-10 15:56:13 -05:00
|
|
|
review = mark.review
|
2023-07-20 21:59:49 -04:00
|
|
|
my_collections = item.collections.all().filter(owner=request.user.identity)
|
2023-02-10 15:56:13 -05:00
|
|
|
collection_list = (
|
|
|
|
item.collections.all()
|
2023-07-20 21:59:49 -04:00
|
|
|
.exclude(owner=request.user.identity)
|
2023-02-10 15:56:13 -05:00
|
|
|
.filter(visible)
|
|
|
|
.annotate(like_counts=Count("likes"))
|
|
|
|
.order_by("-like_counts")
|
|
|
|
)
|
2023-05-20 11:01:18 -04:00
|
|
|
else:
|
|
|
|
collection_list = (
|
|
|
|
item.collections.all()
|
|
|
|
.filter(visibility=0)
|
|
|
|
.annotate(like_counts=Count("likes"))
|
|
|
|
.order_by("-like_counts")
|
2023-02-10 15:56:13 -05:00
|
|
|
)
|
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
item.class_name + ".html",
|
|
|
|
{
|
|
|
|
"item": item,
|
|
|
|
"focus_item": focus_item,
|
|
|
|
"mark": mark,
|
|
|
|
"review": review,
|
2023-06-18 20:53:10 -04:00
|
|
|
"child_item_comments": child_item_comments,
|
2023-05-20 11:01:18 -04:00
|
|
|
"my_collections": my_collections,
|
2023-02-10 15:56:13 -05:00
|
|
|
"collection_list": collection_list,
|
2024-04-03 23:10:21 -04:00
|
|
|
"shelf_actions": shelf_actions,
|
2024-05-29 10:50:41 -04:00
|
|
|
"shelf_statuses": shelf_statuses,
|
2023-02-10 15:56:13 -05:00
|
|
|
},
|
|
|
|
)
|
2022-12-24 01:28:24 -05:00
|
|
|
|
|
|
|
|
2023-06-12 15:07:55 -04:00
|
|
|
def episode_data(request, item_uuid):
|
2024-05-27 15:44:12 -04:00
|
|
|
item = get_object_or_404(Podcast, uid=get_uuid_or_404(item_uuid))
|
2023-06-12 15:07:55 -04:00
|
|
|
qs = item.episodes.all().order_by("-pub_date")
|
|
|
|
if request.GET.get("last"):
|
|
|
|
qs = qs.filter(pub_date__lt=request.GET.get("last"))
|
|
|
|
return render(
|
|
|
|
request, "podcast_episode_data.html", {"item": item, "episodes": qs[:5]}
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-01-01 23:50:57 -05:00
|
|
|
@login_required
|
2022-12-24 01:28:24 -05:00
|
|
|
def mark_list(request, item_path, item_uuid, following_only=False):
|
2023-04-18 14:05:36 -04:00
|
|
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
2022-12-29 23:57:02 -05:00
|
|
|
queryset = ShelfMember.objects.filter(item=item).order_by("-created_time")
|
2022-12-24 01:28:24 -05:00
|
|
|
if following_only:
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_in_home_feed_of_user(request.user))
|
2022-12-24 01:28:24 -05:00
|
|
|
else:
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
2022-12-24 01:28:24 -05:00
|
|
|
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
2022-12-29 23:57:02 -05:00
|
|
|
page_number = request.GET.get("page", default=1)
|
2022-12-24 01:28:24 -05:00
|
|
|
marks = paginator.get_page(page_number)
|
2023-12-30 22:20:15 -05:00
|
|
|
pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET)
|
2022-12-24 01:28:24 -05:00
|
|
|
return render(
|
|
|
|
request,
|
2022-12-29 23:57:02 -05:00
|
|
|
"item_mark_list.html",
|
2022-12-24 01:28:24 -05:00
|
|
|
{
|
2022-12-29 23:57:02 -05:00
|
|
|
"marks": marks,
|
|
|
|
"item": item,
|
2023-05-20 14:17:02 -04:00
|
|
|
"followeing_only": following_only,
|
2023-06-16 17:47:22 -04:00
|
|
|
"pagination": pagination,
|
2022-12-29 23:57:02 -05:00
|
|
|
},
|
2022-12-24 01:28:24 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def review_list(request, item_path, item_uuid):
|
2023-04-18 14:05:36 -04:00
|
|
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
2022-12-29 23:57:02 -05:00
|
|
|
queryset = Review.objects.filter(item=item).order_by("-created_time")
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
2022-12-24 01:28:24 -05:00
|
|
|
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
2022-12-29 23:57:02 -05:00
|
|
|
page_number = request.GET.get("page", default=1)
|
2022-12-24 01:28:24 -05:00
|
|
|
reviews = paginator.get_page(page_number)
|
2023-12-30 22:20:15 -05:00
|
|
|
pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET)
|
2022-12-24 01:28:24 -05:00
|
|
|
return render(
|
|
|
|
request,
|
2022-12-29 23:57:02 -05:00
|
|
|
"item_review_list.html",
|
2022-12-24 01:28:24 -05:00
|
|
|
{
|
2022-12-29 23:57:02 -05:00
|
|
|
"reviews": reviews,
|
|
|
|
"item": item,
|
2023-06-16 17:47:22 -04:00
|
|
|
"pagination": pagination,
|
2022-12-29 23:57:02 -05:00
|
|
|
},
|
2022-12-24 01:28:24 -05:00
|
|
|
)
|
2023-04-19 22:31:27 -04:00
|
|
|
|
|
|
|
|
2023-05-20 11:01:18 -04:00
|
|
|
def comments(request, item_path, item_uuid):
|
|
|
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
2024-05-14 10:54:49 -04:00
|
|
|
ids = item.child_item_ids + [item.pk] + item.sibling_item_ids
|
2023-06-08 17:22:11 -04:00
|
|
|
queryset = Comment.objects.filter(item_id__in=ids).order_by("-created_time")
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
2023-05-20 11:01:18 -04:00
|
|
|
before_time = request.GET.get("last")
|
|
|
|
if before_time:
|
|
|
|
queryset = queryset.filter(created_time__lte=before_time)
|
|
|
|
return render(
|
|
|
|
request,
|
2023-06-09 02:45:27 -04:00
|
|
|
"_item_comments.html",
|
2023-05-20 11:01:18 -04:00
|
|
|
{
|
2023-06-08 17:22:11 -04:00
|
|
|
"item": item,
|
2023-05-20 11:01:18 -04:00
|
|
|
"comments": queryset[:11],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-06-16 17:47:22 -04:00
|
|
|
def comments_by_episode(request, item_path, item_uuid):
|
|
|
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
|
|
|
episode_uuid = request.GET.get("episode_uuid")
|
|
|
|
if episode_uuid:
|
2023-08-10 11:27:31 -04:00
|
|
|
episode = TVEpisode.get_by_url(episode_uuid)
|
|
|
|
ids = [episode.pk] if episode else []
|
2023-06-16 17:47:22 -04:00
|
|
|
else:
|
|
|
|
ids = item.child_item_ids
|
|
|
|
queryset = Comment.objects.filter(item_id__in=ids).order_by("-created_time")
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
2023-06-16 17:47:22 -04:00
|
|
|
before_time = request.GET.get("last")
|
|
|
|
if before_time:
|
|
|
|
queryset = queryset.filter(created_time__lte=before_time)
|
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
"_item_comments_by_episode.html",
|
|
|
|
{
|
|
|
|
"item": item,
|
|
|
|
"episode_uuid": episode_uuid,
|
|
|
|
"comments": queryset[:11],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-05-20 11:01:18 -04:00
|
|
|
def reviews(request, item_path, item_uuid):
|
|
|
|
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
2024-05-14 10:54:49 -04:00
|
|
|
ids = item.child_item_ids + [item.pk] + item.sibling_item_ids
|
2023-06-08 17:22:11 -04:00
|
|
|
queryset = Review.objects.filter(item_id__in=ids).order_by("-created_time")
|
2023-07-20 21:59:49 -04:00
|
|
|
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
2023-05-20 11:01:18 -04:00
|
|
|
before_time = request.GET.get("last")
|
|
|
|
if before_time:
|
|
|
|
queryset = queryset.filter(created_time__lte=before_time)
|
|
|
|
return render(
|
|
|
|
request,
|
2023-06-09 02:45:27 -04:00
|
|
|
"_item_reviews.html",
|
2023-05-20 11:01:18 -04:00
|
|
|
{
|
2023-06-08 17:22:11 -04:00
|
|
|
"item": item,
|
2023-05-20 11:01:18 -04:00
|
|
|
"reviews": queryset[:11],
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-12-25 18:48:45 -05:00
|
|
|
@require_http_methods(["GET", "HEAD"])
|
2023-04-19 22:31:27 -04:00
|
|
|
def discover(request):
|
2023-05-20 11:01:18 -04:00
|
|
|
cache_key = "public_gallery"
|
2023-04-19 22:31:27 -04:00
|
|
|
gallery_list = cache.get(cache_key, [])
|
|
|
|
|
2024-03-02 17:13:05 -05:00
|
|
|
# rotate every 6 minutes
|
|
|
|
rot = timezone.now().minute // 6
|
|
|
|
for gallery in gallery_list:
|
|
|
|
i = rot * len(gallery["items"]) // 10
|
|
|
|
gallery["items"] = gallery["items"][i:] + gallery["items"][:i]
|
2023-04-19 22:31:27 -04:00
|
|
|
|
2023-08-17 18:54:00 -04:00
|
|
|
if request.user.is_authenticated:
|
2023-09-03 20:11:46 +00:00
|
|
|
if not request.user.registration_complete:
|
|
|
|
return redirect(reverse("users:register"))
|
2023-08-17 18:54:00 -04:00
|
|
|
layout = request.user.preference.discover_layout
|
|
|
|
identity = request.user.identity
|
2024-06-03 07:53:59 -04:00
|
|
|
announcements = []
|
2024-06-03 18:09:47 -04:00
|
|
|
post_ids = cache.get("popular_posts", [])
|
2024-06-03 23:39:20 -04:00
|
|
|
popular_posts = Takahe.get_posts(post_ids).order_by("-published")
|
2023-05-20 11:01:18 -04:00
|
|
|
else:
|
2023-08-17 18:54:00 -04:00
|
|
|
identity = None
|
|
|
|
layout = []
|
2024-06-03 07:53:59 -04:00
|
|
|
announcements = Takahe.get_announcements()
|
2024-06-03 07:27:44 -04:00
|
|
|
popular_posts = []
|
2023-04-19 22:31:27 -04:00
|
|
|
|
2024-06-02 15:58:37 -04:00
|
|
|
collection_ids = cache.get("featured_collections", [])
|
|
|
|
if collection_ids:
|
|
|
|
i = rot * len(collection_ids) // 10
|
|
|
|
collection_ids = collection_ids[i:] + collection_ids[:i]
|
|
|
|
featured_collections = Collection.objects.filter(pk__in=collection_ids)
|
|
|
|
else:
|
|
|
|
featured_collections = []
|
|
|
|
|
2024-06-03 00:14:34 -04:00
|
|
|
popular_tags = cache.get("popular_tags", [])
|
|
|
|
|
2023-04-19 22:31:27 -04:00
|
|
|
return render(
|
|
|
|
request,
|
|
|
|
"discover.html",
|
|
|
|
{
|
2023-08-17 18:54:00 -04:00
|
|
|
"identity": identity,
|
2024-06-03 07:53:59 -04:00
|
|
|
"all_announcements": announcements,
|
2023-04-19 22:31:27 -04:00
|
|
|
"gallery_list": gallery_list,
|
2024-06-02 15:58:37 -04:00
|
|
|
"featured_collections": featured_collections,
|
2024-06-03 00:14:34 -04:00
|
|
|
"popular_tags": popular_tags,
|
2024-06-03 07:27:44 -04:00
|
|
|
"popular_posts": popular_posts,
|
2023-04-19 22:31:27 -04:00
|
|
|
"layout": layout,
|
|
|
|
},
|
|
|
|
)
|