1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 from collections import defaultdict
6 from random import randint
8 from django.contrib.contenttypes.models import ContentType
9 from django.db.models import Q
10 from django.utils.functional import lazy
11 from catalogue.models import Book, Tag
12 from catalogue import utils
13 from catalogue.tasks import touch_tag
14 from social.models import Cite
17 def likes(user, work, request=None):
18 if not user.is_authenticated():
22 return work.tags.filter(category='set', user=user).exists()
24 if not hasattr(request, 'social_likes'):
25 # tuple: unchecked, checked, liked
26 request.social_likes = defaultdict(lambda: (set(), set(), set()))
28 ct = ContentType.objects.get_for_model(type(work))
29 likes_t = request.social_likes[ct.pk]
30 if work.pk in likes_t[1]:
31 return work.pk in likes_t[2]
33 likes_t[0].add(work.pk)
37 ids = tuple(likes_t[0])
39 likes_t[2].update(Tag.intermediary_table_model.objects.filter(
40 content_type_id=ct.pk, tag__user_id=user.pk,
42 ).distinct().values_list('object_id', flat=True))
43 likes_t[1].update(ids)
44 return work.pk in likes_t[2]
45 return lazy(_likes, bool)()
48 def get_set(user, name):
49 """Returns a tag for use by the user. Creates it, if necessary."""
51 tag = Tag.objects.get(category='set', user=user, name=name)
52 except Tag.DoesNotExist:
53 tag = Tag.objects.create(
54 category='set', user=user, name=name, slug=utils.get_random_hash(name), sort_key=name.lower())
58 def set_sets(user, work, sets):
59 """Set tags used for given work by a given user."""
61 old_sets = list(work.tags.filter(category='set', user=user))
63 work.tags = sets + list(
64 work.tags.filter(~Q(category='set') | ~Q(user=user)))
66 for shelf in [shelf for shelf in old_sets if shelf not in sets]:
68 for shelf in [shelf for shelf in sets if shelf not in old_sets]:
72 Tag.objects.filter(category='set', user=user, items=None).delete()
74 if isinstance(work, Book):
75 work.update_popularity()
78 def cites_for_tags(tags):
79 """Returns a QuerySet with all Cites for books with given tags."""
80 return Cite.objects.filter(book__in=Book.tagged.with_all(tags))
83 # tag_ids is never used
84 def choose_cite(book_id=None, tag_ids=None):
85 """Choose a cite for main page, for book or for set of tags."""
86 if book_id is not None:
87 cites = Cite.objects.filter(Q(book=book_id) | Q(book__ancestor=book_id))
88 elif tag_ids is not None:
89 tags = Tag.objects.filter(pk__in=tag_ids)
90 cites = cites_for_tags(tags)
92 cites = Cite.objects.all()
93 stickies = cites.filter(sticky=True)
100 cite = cites[randint(0, count - 1)]
106 def get_or_choose_cite(request, book_id=None, tag_ids=None):
108 assert request.user.is_staff
109 assert 'choose_cite' in request.GET
110 return Cite.objects.get(pk=request.GET['choose_cite'])
111 except (AssertionError, Cite.DoesNotExist):
112 return choose_cite(book_id, tag_ids)