113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
import json
|
|
|
|
from django.conf import settings
|
|
from django.contrib import messages
|
|
from django.contrib.humanize.templatetags.humanize import naturaltime
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import redirect
|
|
from django.utils.translation import gettext as _
|
|
from django.views.generic import View as BaseView
|
|
|
|
from moku.constants import EMOJI_CATEGORIES, Verbs
|
|
from moku.forms.post import PostForm
|
|
from moku.images import process_post_image
|
|
from moku.models.post import Post
|
|
from moku.models.recipe import Recipe
|
|
from moku.views.base import FormView
|
|
|
|
|
|
class FeedView(FormView):
|
|
"""Allows users to see recent posts and create a new post."""
|
|
|
|
template_name = "moku/feed.jinja"
|
|
form_class = PostForm
|
|
|
|
def form_valid(self, form):
|
|
if not self.request.user.is_authenticated:
|
|
raise PermissionDenied
|
|
if (
|
|
form.instance.recipe
|
|
and form.instance.recipe.created_by.id != self.request.user.id
|
|
):
|
|
messages.error(
|
|
self.request, _("you can't add someone else's recipe to your post!")
|
|
)
|
|
return redirect("feed")
|
|
form.instance.created_by = self.request.user
|
|
if "image" in form.changed_data and form.instance.image is not None:
|
|
form.instance.image = process_post_image(form.instance.image)
|
|
form.save()
|
|
messages.success(self.request, _("your post was made!"))
|
|
return redirect("feed")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = {
|
|
**super().get_context_data(**kwargs),
|
|
"posts": Post.objects.all()[:128],
|
|
}
|
|
if self.request.user.is_authenticated:
|
|
return self.get_authenticated_context_data(context)
|
|
return context
|
|
|
|
def get_authenticated_context_data(self, context):
|
|
return {
|
|
**context,
|
|
"emoji": EMOJI_CATEGORIES,
|
|
"verbs": (
|
|
(
|
|
verb[0],
|
|
verb[1] % {"user": f"@{self.request.user.username}", "food": "..."},
|
|
)
|
|
for verb in Verbs.CHOICES
|
|
),
|
|
}
|
|
|
|
def get_form(self, form_class=None):
|
|
form = super().get_form(form_class)
|
|
if self.request.user.is_authenticated:
|
|
form.fields["recipe"].queryset = Recipe.objects.filter(
|
|
created_by=self.request.user
|
|
)
|
|
return form
|
|
|
|
|
|
class LatestPostJSONView(BaseView):
|
|
"""Renders the latest post from a specific user as JSON."""
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
post = (
|
|
Post.objects.prefetch_related("recipe__steps")
|
|
.filter(created_by__username=kwargs.get("username"))
|
|
.order_by("-created_at")
|
|
.first()
|
|
)
|
|
if not post:
|
|
return HttpResponse(
|
|
json.dumps({"post": None}), content_type="application/json"
|
|
)
|
|
post_data = {
|
|
"date": {
|
|
"iso": str(post.created_at),
|
|
"natural": naturaltime(post.created_at),
|
|
},
|
|
"text": post.get_verb_display()
|
|
% {"user": f"@{post.created_by.username}", "food": post.food},
|
|
"food": post.food,
|
|
"verb": {
|
|
"id": post.verb,
|
|
"pattern": post.get_verb_display() % {"user": "$1", "food": "$2"},
|
|
},
|
|
"image": f"{settings.SITE_ROOT_URL}{post.image.url}"
|
|
if post.image
|
|
else None,
|
|
"user": {
|
|
"username": post.created_by.username,
|
|
"url": f"{settings.SITE_ROOT_URL}{post.created_by.get_absolute_url()}",
|
|
},
|
|
}
|
|
if post.recipe:
|
|
post_data["recipe"] = [
|
|
step.instructions for step in post.recipe.steps.all()
|
|
]
|
|
return HttpResponse(json.dumps(post_data), content_type="application/json")
|