From 89495af70dd1b941c4f5889f10fc33e8450eeb70 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Tue, 16 Feb 2016 10:21:25 +0100 Subject: [PATCH] keep book popularity in model --- .../management/commands/update_popularity.py | 24 +++++++++++++++++++ .../migrations/0010_bookpopularity.py | 22 +++++++++++++++++ src/catalogue/models/__init__.py | 2 +- src/catalogue/models/book.py | 14 +++++++++++ src/social/utils.py | 3 +++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/catalogue/management/commands/update_popularity.py create mode 100644 src/catalogue/migrations/0010_bookpopularity.py diff --git a/src/catalogue/management/commands/update_popularity.py b/src/catalogue/management/commands/update_popularity.py new file mode 100644 index 000000000..3a9905673 --- /dev/null +++ b/src/catalogue/management/commands/update_popularity.py @@ -0,0 +1,24 @@ +# -*- 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 __future__ import print_function, unicode_literals + +from django.core.management.base import BaseCommand +from django.db.models import Count + +from catalogue.models import Book, BookPopularity + + +class Command(BaseCommand): + help = 'Update popularity counters.' + + def handle(self, **options): + BookPopularity.objects.all().delete() + books_with_popularity = Book.objects.filter(tag_relations__tag__category='set').only('id').distinct()\ + .annotate(pop=Count('tag_relations__tag__user', distinct=True)) + for book in books_with_popularity: + BookPopularity.objects.create(book=book, count=book.pop) + books_without_popularity = Book.objects.exclude(tag_relations__tag__category='set') + for book in books_without_popularity: + BookPopularity.objects.create(book=book, count=0) diff --git a/src/catalogue/migrations/0010_bookpopularity.py b/src/catalogue/migrations/0010_bookpopularity.py new file mode 100644 index 000000000..42fd6cb7a --- /dev/null +++ b/src/catalogue/migrations/0010_bookpopularity.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0009_auto_20160127_1019'), + ] + + operations = [ + migrations.CreateModel( + name='BookPopularity', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('count', models.IntegerField(default=0)), + ('book', models.OneToOneField(related_name='popularity', to='catalogue.Book')), + ], + ), + ] diff --git a/src/catalogue/models/__init__.py b/src/catalogue/models/__init__.py index 73b51090c..7aebc3175 100644 --- a/src/catalogue/models/__init__.py +++ b/src/catalogue/models/__init__.py @@ -5,6 +5,6 @@ from catalogue.models.tag import Tag from catalogue.models.bookmedia import BookMedia from catalogue.models.fragment import Fragment -from catalogue.models.book import Book +from catalogue.models.book import Book, BookPopularity from catalogue.models.collection import Collection from catalogue.models.source import Source diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index 5194fe1d6..f954e1a90 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -544,6 +544,15 @@ class Book(models.Model): else: return None + def update_popularity(self): + count = self.tags.filter(category='set').values('user').order_by('user').distinct().count() + try: + pop = self.popularity + pop.count = count + pop.save() + except BookPopularity.DoesNotExist: + BookPopularity.objects.create(book=self, count=count) + def add_file_fields(): for format_ in Book.formats: @@ -563,3 +572,8 @@ def add_file_fields(): ).contribute_to_class(Book, field_name) add_file_fields() + + +class BookPopularity(models.Model): + book = models.OneToOneField(Book, related_name='popularity') + count = models.IntegerField(default=0) diff --git a/src/social/utils.py b/src/social/utils.py index c89878ad4..63a42279b 100755 --- a/src/social/utils.py +++ b/src/social/utils.py @@ -69,6 +69,9 @@ 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.""" -- 2.20.1