blender-studio/blog/views/blog.py
Anna Sirota f6ede7e3f7 Subscribers-only blog posts (#104416)
Adds `is_subscribers_only` column to Blog posts.

Posts with `is_subscribers_only == True` will

* not show up in the RSS feed;
* still show up at `/blog/` (`is_subscribers_only` is directly accessible in the templates);
* display a "Subscribe" banner in post's detail page instead of post's content;
   * comment section also won't be shown in this case.

Reviewed-on: #104416
Reviewed-by: Francesco Siddi <fsiddi@noreply.localhost>
2024-07-02 15:49:10 +02:00

93 lines
3.0 KiB
Python

"""Views that render blog pages are defined here."""
from typing import List
from django.contrib.syndication.views import Feed
from django.db.models.query import QuerySet
from django.utils import feedgenerator
from django.views.generic import ListView, DetailView
from blog.models import Post, Like
from blog.queries import get_posts
from comments.models import Comment
from comments.queries import get_annotated_comments
from comments.views.common import comments_to_template_type
import common.queries
class PostList(ListView):
model = Post
context_object_name = 'posts'
paginate_by = 12
def get_queryset(self) -> QuerySet:
return get_posts(
user_pk=self.request.user.pk if self.request.user.is_authenticated else None
)
class PostDetail(DetailView):
model = Post
context_object_name = 'post'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post: Post = self.object
show_subscribe_instead = post.is_subscribers_only and (
self.request.user.is_anonymous
or (
# This is neither the author of the post nor a subscriber
self.request.user.pk != post.author_id
and not common.queries.has_active_subscription(self.request.user)
)
)
if self.request.user.is_authenticated:
post.liked = Like.objects.filter(post_id=post.pk, user_id=self.request.user.pk).exists()
# Whether the subscribe banner should be displayed instead of content
context['show_subscribe_instead'] = show_subscribe_instead
# Display edit buttons for editors/authors
context['user_can_edit_post'] = self.request.user.is_staff and self.request.user.has_perm(
'blog.change_post'
)
if post.film and post.author.film_crew.filter(film=post.film):
context['user_film_role'] = post.author.film_crew.filter(film=post.film)[0].role
# Comment threads are only shown when post is visible
if not show_subscribe_instead:
comments: List[Comment] = get_annotated_comments(post, self.request.user.pk)
context['comments'] = comments_to_template_type(
comments, post.comment_url, self.request.user
)
return context
class PostFeed(Feed):
title = 'Blender Studio feed'
link = '/blog/'
description = 'Updates from Blender Studio'
def item_enclosures(self, item: Post):
return [
feedgenerator.Enclosure(
item.thumbnail_s_url,
str(item.thumbnail.size),
'image/{}'.format(item.thumbnail.name.split('.')[-1]),
)
]
def items(self):
return Post.objects.filter(is_published=True, is_subscribers_only=False).order_by(
'-date_published'
)[:5]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.excerpt