except KeyError, e:
return rc.NOT_FOUND
- tags = Tag.objects.filter(category=category_sng)
- tags = [t for t in tags if t.get_count() > 0]
- if tags:
+ tags = Tag.objects.filter(category=category_sng).exclude(book_count=0)
+ if tags.exists():
return tags
else:
return rc.NOT_FOUND
changed_at__gte=since,
changed_at__lt=until):
# only serve non-empty tags
- if tag.get_count():
+ if tag.book_count:
tag_d = cls.tag_dict(tag, fields)
updated.append(tag_d)
elif tag.created_at < since:
db = init_db(last_checked)
for b in Book.objects.all():
add_book(db, b)
- for t in Tag.objects.exclude(category__in=('book', 'set', 'theme')):
+ for t in Tag.objects.exclude(
+ category__in=('book', 'set', 'theme')).exclude(book_count=0):
# only add non-empty tags
- if t.get_count():
- add_tag(db, t)
+ add_tag(db, t)
db.commit()
db.close()
current(last_checked)
self.fields['set_ids'] = forms.MultipleChoiceField(
label=_('Shelves'),
required=False,
- choices=[(tag.id, "%s (%s)" % (tag.name, tag.get_count())) for tag in Tag.objects.filter(category='set', user=user)],
+ choices=[(tag.id, "%s (%s)" % (tag.name, tag.book_count)) for tag in Tag.objects.filter(category='set', user=user)],
initial=[tag.id for tag in obj.tags.filter(category='set', user=user)],
widget=forms.CheckboxSelectMultiple
)
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from collections import namedtuple
-from datetime import datetime
from django.db import models
from django.db.models import permalink, Q
from newtagging import managers
from catalogue.fields import JSONField, OverwritingFileField
from catalogue.utils import create_zip
+from catalogue.tasks import touch_tag
from shutil import copy
from glob import glob
import re
has_description.boolean = True
def get_count(self):
- """ returns global book count for book tags, fragment count for themes """
-
- if self.book_count is None:
- if self.category == 'book':
- # never used
- objects = Book.objects.none()
- elif self.category == 'theme':
- objects = Fragment.tagged.with_all((self,))
- else:
- objects = Book.tagged.with_all((self,)).order_by()
- if self.category != 'set':
- # eliminate descendants
- l_tags = Tag.objects.filter(slug__in=[book.book_tag_slug() for book in objects])
- descendants_keys = [book.pk for book in Book.tagged.with_any(l_tags)]
- if descendants_keys:
- objects = objects.exclude(pk__in=descendants_keys)
- self.book_count = objects.count()
- self.save()
- return self.book_count
+ """Returns global book count for book tags, fragment count for themes."""
+
+ if self.category == 'book':
+ # never used
+ objects = Book.objects.none()
+ elif self.category == 'theme':
+ objects = Fragment.tagged.with_all((self,))
+ else:
+ objects = Book.tagged.with_all((self,)).order_by()
+ if self.category != 'set':
+ # eliminate descendants
+ l_tags = Tag.objects.filter(slug__in=[book.book_tag_slug() for book in objects])
+ descendants_keys = [book.pk for book in Book.tagged.with_any(l_tags)]
+ if descendants_keys:
+ objects = objects.exclude(pk__in=descendants_keys)
+ return objects.count()
@staticmethod
def get_tag_list(tags):
book.build_mobi()
book_descendants = list(book.children.all())
+ descendants_tags = set()
# add l-tag to descendants and their fragments
while len(book_descendants) > 0:
child_book = book_descendants.pop(0)
+ descendants_tags.update(child_book.tags)
child_book.tags = list(child_book.tags) + [book_tag]
child_book.save()
for fragment in child_book.fragments.all():
fragment.tags = set(list(fragment.tags) + [book_tag])
book_descendants += list(child_book.children.all())
+ for tag in descendants_tags:
+ touch_tag.delay(tag)
+
book.save()
# refresh cache
def _tags_updated_handler(sender, affected_tags, **kwargs):
# reset tag global counter
# we want Tag.changed_at updated for API to know the tag was touched
- Tag.objects.filter(pk__in=[tag.pk for tag in affected_tags]).update(book_count=None, changed_at=datetime.now())
+ for tag in affected_tags:
+ touch_tag.delay(tag)
# if book tags changed, reset book tag counter
if isinstance(sender, Book) and \
--- /dev/null
+# -*- 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 datetime import datetime
+from celery.task import task
+
+
+@task
+def touch_tag(tag):
+ update_dict = {
+ 'book_count': tag.get_count(),
+ 'changed_at': datetime.now(),
+ }
+
+ type(tag).objects.filter(pk=tag.pk).update(**update_dict)
from catalogue import models
from catalogue import forms
from catalogue.utils import split_tags, AttachmentHttpResponse, async_build_pdf
+from catalogue.tasks import touch_tag
from pdcounter import models as pdcounter_models
from pdcounter import views as pdcounter_views
from suggest.forms import PublishingSuggestForm
def catalogue(request):
- tags = models.Tag.objects.exclude(category__in=('set', 'book'))
+ tags = models.Tag.objects.exclude(
+ category__in=('set', 'book')).exclude(book_count=0)
+ tags = list(tags)
for tag in tags:
- tag.count = tag.get_count()
+ tag.count = tag.book_count
categories = split_tags(tags)
fragment_tags = categories.get('theme', [])
new_shelves = [models.Tag.objects.get(pk=id) for id in form.cleaned_data['set_ids']]
for shelf in [shelf for shelf in old_shelves if shelf not in new_shelves]:
- shelf.book_count = None
- shelf.save()
+ touch_tag(shelf)
for shelf in [shelf for shelf in new_shelves if shelf not in old_shelves]:
- shelf.book_count = None
- shelf.save()
+ touch_tag(shelf)
book.tags = new_shelves + list(book.tags.filter(~Q(category='set') | ~Q(user=request.user)))
if request.is_ajax():
if shelf in book.tags:
models.Tag.objects.remove_tag(book, shelf)
-
- shelf.book_count = None
- shelf.save()
+ touch_tag(shelf)
return HttpResponse(_('Book was successfully removed from the shelf'))
else:
return feed['title']
def items(self, feed):
- return (tag for tag in Tag.objects.filter(category=feed['category']) if tag.get_count() > 0)
+ return Tag.objects.filter(category=feed['category']).exclude(book_count=0)
def item_title(self, item):
return item.name
return u"Półki użytkownika %s" % user.username
def items(self, user):
- return (tag for tag in Tag.objects.filter(category='set', user=user) if tag.get_count() > 0)
+ return Tag.objects.filter(category='set', user=user).exclude(book_count=0)
def item_title(self, item):
return item.name
{% else %}
<ul>
{% for tag in tags %}
- <li><a href="{% catalogue_url choices tag %}">{{ tag }} ({{ tag.count }})</a></li>
+ <li><a href="{% catalogue_url choices tag %}">{{ tag }} ({{ tag.book_count }})</a></li>
{% endfor %}
</ul>
{% endif %}
{% if shelves %}
<ul class="shelf-list">
{% for shelf in shelves %}
- <li><a href="{% url delete_shelf shelf.slug %}" class="delete-shelf">{% trans "remove" %}</a> <a href="{{ shelf.get_absolute_url }}" class="visit-shelf">{{ shelf.name }} ({{ shelf.get_count }})</a></li>
+ <li><a href="{% url delete_shelf shelf.slug %}" class="delete-shelf">{% trans "remove" %}</a> <a href="{{ shelf.get_absolute_url }}" class="visit-shelf">{{ shelf.name }} ({{ shelf.book_count }})</a></li>
{% endfor %}
</ul>
{% else %}