keep book popularity in model
authorJan Szejko <j-sz@o2.pl>
Tue, 16 Feb 2016 09:21:25 +0000 (10:21 +0100)
committerJan Szejko <j-sz@o2.pl>
Tue, 16 Feb 2016 09:59:34 +0000 (10:59 +0100)
src/catalogue/management/commands/update_popularity.py [new file with mode: 0644]
src/catalogue/migrations/0010_bookpopularity.py [new file with mode: 0644]
src/catalogue/models/__init__.py
src/catalogue/models/book.py
src/social/utils.py

diff --git a/src/catalogue/management/commands/update_popularity.py b/src/catalogue/management/commands/update_popularity.py
new file mode 100644 (file)
index 0000000..3a99056
--- /dev/null
@@ -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 (file)
index 0000000..42fd6cb
--- /dev/null
@@ -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')),
+            ],
+        ),
+    ]
index 73b5109..7aebc31 100644 (file)
@@ -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
index 5194fe1..f954e1a 100644 (file)
@@ -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)
index c89878a..63a4227 100755 (executable)
@@ -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."""