Add grammar to tags. Also: respect custom tag slugs on publishing.
[wolnelektury.git] / src / social / views.py
index 49c9b70..d9627eb 100644 (file)
@@ -1,19 +1,19 @@
-# -*- coding: utf-8 -*-
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.shortcuts import render, get_object_or_404, redirect
 from django.http import HttpResponseForbidden, JsonResponse
 from django.contrib.auth.decorators import login_required
+from django.views.decorators.cache import never_cache
 from django.views.decorators.http import require_POST
+from django.views.generic.edit import FormView
 
 from ajaxable.utils import AjaxableFormView
 
-from catalogue.models import Book
-from ssify import ssi_included
+from catalogue.models import Book, Tag
+import catalogue.models.tag
 from social import forms
-from .models import Cite
-from social.utils import get_set, likes, set_sets
+from wolnelektury.utils import is_ajax
 
 
 # ====================
@@ -23,68 +23,121 @@ from social.utils import get_set, likes, set_sets
 
 @require_POST
 def like_book(request, slug):
-    if not request.user.is_authenticated():
+    if not request.user.is_authenticated:
         return HttpResponseForbidden('Login required.')
     book = get_object_or_404(Book, slug=slug)
-    if not likes(request.user, book):
-        tag = get_set(request.user, '')
-        set_sets(request.user, book, [tag])
 
-    if request.is_ajax():
+    book.like(request.user)
+
+    if is_ajax(request):
         return JsonResponse({"success": True, "msg": "ok", "like": True})
     else:
         return redirect(book)
 
 
-@login_required
-def my_shelf(request):
-    books = Book.tagged.with_any(request.user.tag_set.all())
-    return render(request, 'social/my_shelf.html', locals())
+class AddSetView(FormView):
+    form_class = forms.AddSetForm
+    template_name = 'forms/form_detail.html'
 
+    def form_valid(self, form):
+        book, tag = form.save(self.request.user)
 
-class ObjectSetsFormView(AjaxableFormView):
-    form_class = forms.ObjectSetsForm
-    placeholdize = True
-    template = 'social/sets_form.html'
-    ajax_redirect = True
-    POST_login = True
-
-    def get_object(self, request, slug):
-        return get_object_or_404(Book, slug=slug)
+        if is_ajax(self.request):
+            return JsonResponse(get_sets_for_book_ids([book.id], self.request.user))
+        else:
+            return redirect(book)
 
-    def context_description(self, request, obj):
-        return obj.pretty_title()
 
-    def form_args(self, request, obj):
-        return (obj, request.user), {}
+class RemoveSetView(AddSetView):
+    form_class = forms.RemoveSetForm
 
 
 @require_POST
 def unlike_book(request, slug):
-    if not request.user.is_authenticated():
+    if not request.user.is_authenticated:
         return HttpResponseForbidden('Login required.')
     book = get_object_or_404(Book, slug=slug)
-    if likes(request.user, book):
-        set_sets(request.user, book, [])
 
-    if request.is_ajax():
+    book.unlike(request.user)
+
+    if is_ajax(request):
         return JsonResponse({"success": True, "msg": "ok", "like": False})
     else:
         return redirect(book)
 
 
-@ssi_included
-def cite(request, pk, main=False):
-    cite = get_object_or_404(Cite, pk=pk)
-    return render(request, 'social/cite_promo.html', {
-        'main': main,
-        'cite': cite,
+@login_required
+def my_shelf(request):
+    if request.EXPERIMENTS['layout'].value:
+        template_name = 'social/2022/my_shelf.html'
+    else:
+        template_name = 'social/my_shelf.html'
+    return render(request, template_name, {
+        'books': Book.tagged.with_any(request.user.tag_set.all())
     })
 
 
-@ssi_included(use_lang=False)
-def cite_info(request, pk):
-    cite = get_object_or_404(Cite, pk=pk)
-    return render(request, 'social/cite_info.html', {
-        'cite': cite,
-    })
+def get_sets_for_book_ids(book_ids, user):
+    data = {}
+    tagged = catalogue.models.tag.TagRelation.objects.filter(
+        tag__user=user,
+        #content_type= # for books,
+        object_id__in=book_ids
+    ).order_by('tag__sort_key')
+    for t in tagged:
+        # related?
+        item = data.setdefault(t.object_id, [])
+        if t.tag.name:
+            item.append({
+                "slug": t.tag.slug,
+                "url": t.tag.get_absolute_url(),
+                "name": t.tag.name,
+            })
+    for b in book_ids:
+        if b not in data:
+            data[b] = None
+    return data
+    
+    
+
+
+@never_cache
+def my_liked(request):
+    if not request.user.is_authenticated:
+        return JsonResponse({})
+    try:
+        ids = [int(x) for x in request.GET.get('ids', '').split(',')]
+    except:
+        return JsonResponse({})
+    return JsonResponse(get_sets_for_book_ids(ids, request.user))
+
+
+@never_cache
+@login_required
+def my_tags(request):
+    term = request.GET.get('term', '')
+    tags =             Tag.objects.filter(user=request.user).order_by('sort_key')
+    if term:
+        tags = tags.filter(name__icontains=term)
+    return JsonResponse(
+        [
+            t.name for t in tags
+        ], safe=False
+    )
+
+
+class ObjectSetsFormView(AjaxableFormView):
+    form_class = forms.ObjectSetsForm
+    placeholdize = True
+    template = 'social/sets_form.html'
+    ajax_redirect = True
+    POST_login = True
+
+    def get_object(self, request, slug):
+        return get_object_or_404(Book, slug=slug)
+
+    def context_description(self, request, obj):
+        return obj.pretty_title()
+
+    def form_args(self, request, obj):
+        return (obj, request.user), {}