Fixes #4076: Recommendations from collections.
[wolnelektury.git] / src / social / utils.py
old mode 100755 (executable)
new mode 100644 (file)
index bf1c242..67bc867
@@ -1,8 +1,9 @@
-# -*- 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 collections import defaultdict
+from random import randint
+
 from django.contrib.contenttypes.models import ContentType
 from django.db.models import Q
 from django.utils.functional import lazy
@@ -13,7 +14,7 @@ from social.models import Cite
 
 
 def likes(user, work, request=None):
-    if not user.is_authenticated():
+    if not user.is_authenticated:
         return False
 
     if request is None:
@@ -21,7 +22,7 @@ def likes(user, work, request=None):
 
     if not hasattr(request, 'social_likes'):
         # tuple: unchecked, checked, liked
-        request.social_likes = defaultdict(lambda:(set(), set(), set()))
+        request.social_likes = defaultdict(lambda: (set(), set(), set()))
 
     ct = ContentType.objects.get_for_model(type(work))
     likes_t = request.social_likes[ct.pk]
@@ -29,6 +30,7 @@ def likes(user, work, request=None):
         return work.pk in likes_t[2]
     else:
         likes_t[0].add(work.pk)
+
         def _likes():
             if likes_t[0]:
                 ids = tuple(likes_t[0])
@@ -47,8 +49,17 @@ def get_set(user, name):
     try:
         tag = Tag.objects.get(category='set', user=user, name=name)
     except Tag.DoesNotExist:
-        tag = Tag.objects.create(category='set', user=user, name=name,
-                slug=utils.get_random_hash(name), sort_key=name.lower())
+        tag = Tag.objects.create(
+            category='set', user=user, name=name, slug=utils.get_random_hash(name), sort_key=name.lower())
+    except Tag.MultipleObjectsReturned:
+        # fix duplicated noname shelf
+        tags = list(Tag.objects.filter(category='set', user=user, name=name))
+        tag = tags[0]
+        for other_tag in tags[1:]:
+            for item in other_tag.items.all():
+                Tag.objects.remove_tag(item, other_tag)
+                Tag.objects.add_tag(item, tag)
+            other_tag.delete()
     return tag
 
 
@@ -68,7 +79,42 @@ def set_sets(user, work, sets):
     # delete empty tags
     Tag.objects.filter(category='set', user=user, items=None).delete()
 
+    if isinstance(work, Book):
+        work.update_popularity()
+
 
 def cites_for_tags(tags):
     """Returns a QuerySet with all Cites for books with given tags."""
     return Cite.objects.filter(book__in=Book.tagged.with_all(tags))
+
+
+# tag_ids is never used
+def choose_cite(book_id=None, tag_ids=None):
+    """Choose a cite for main page, for book or for set of tags."""
+    if book_id is not None:
+        cites = Cite.objects.filter(Q(book=book_id) | Q(book__ancestor=book_id))
+    elif tag_ids is not None:
+        tags = Tag.objects.filter(pk__in=tag_ids)
+        cites = cites_for_tags(tags)
+    else:
+        cites = Cite.objects.all()
+    stickies = cites.filter(sticky=True)
+    count = len(stickies)
+    if count:
+        cites = stickies
+    else:
+        count = len(cites)
+    if count:
+        cite = cites[randint(0, count - 1)]
+    else:
+        cite = None
+    return cite
+
+
+def get_or_choose_cite(request, book_id=None, tag_ids=None):
+    try:
+        assert request.user.is_staff
+        assert 'banner' in request.GET
+        return Cite.objects.get(pk=request.GET['banner'])
+    except (AssertionError, Cite.DoesNotExist):
+        return choose_cite(book_id, tag_ids)