X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/d0072de89eb395f99aedcdf7804e48b547cbbeca..ad39c2501159fa52e980c95af3e735e36b459c15:/apps/social/utils.py diff --git a/apps/social/utils.py b/apps/social/utils.py index 00cf43e28..bf1c24229 100755 --- a/apps/social/utils.py +++ b/apps/social/utils.py @@ -1,12 +1,45 @@ +# -*- 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 django.contrib.contenttypes.models import ContentType from django.db.models import Q +from django.utils.functional import lazy from catalogue.models import Book, Tag from catalogue import utils from catalogue.tasks import touch_tag from social.models import Cite -def likes(user, work): - return user.is_authenticated() and work.tags.filter(category='set', user=user).exists() +def likes(user, work, request=None): + if not user.is_authenticated(): + return False + + if request is None: + return work.tags.filter(category='set', user=user).exists() + + if not hasattr(request, 'social_likes'): + # tuple: unchecked, checked, liked + request.social_likes = defaultdict(lambda:(set(), set(), set())) + + ct = ContentType.objects.get_for_model(type(work)) + likes_t = request.social_likes[ct.pk] + if work.pk in likes_t[1]: + 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]) + likes_t[0].clear() + likes_t[2].update(Tag.intermediary_table_model.objects.filter( + content_type_id=ct.pk, tag__user_id=user.pk, + object_id__in=ids + ).distinct().values_list('object_id', flat=True)) + likes_t[1].update(ids) + return work.pk in likes_t[2] + return lazy(_likes, bool)() def get_set(user, name): @@ -33,11 +66,9 @@ def set_sets(user, work, sets): touch_tag(shelf) # delete empty tags - Tag.objects.filter(category='set', user=user, book_count=0).delete() + Tag.objects.filter(category='set', user=user, items=None).delete() def cites_for_tags(tags): """Returns a QuerySet with all Cites for books with given tags.""" - books = Book.tagged.with_all(tags).order_by().values_list('id', flat=True) - books = list(books) - return Cite.objects.filter(book__id__in=books) + return Cite.objects.filter(book__in=Book.tagged.with_all(tags))