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 django.contrib.auth.models import User
6 from django.db import models
7 from django.db.models import permalink
8 from django.utils.translation import ugettext_lazy as _
9 from newtagging.models import TagBase
12 # Those are hard-coded here so that makemessages sees them.
14 ('author', _('author')),
15 ('epoch', _('epoch')),
17 ('genre', _('genre')),
18 ('theme', _('theme')),
25 """A tag attachable to books and fragments (and possibly anything).
27 Used to represent searchable metadata (authors, epochs, genres, kinds),
28 fragment themes (motifs) and some book hierarchy related kludges."""
29 name = models.CharField(_('name'), max_length=50, db_index=True)
30 slug = models.SlugField(_('slug'), max_length=120, db_index=True)
31 sort_key = models.CharField(_('sort key'), max_length=120, db_index=True)
32 category = models.CharField(_('category'), max_length=50, blank=False, null=False,
33 db_index=True, choices=TAG_CATEGORIES)
34 description = models.TextField(_('description'), blank=True)
36 user = models.ForeignKey(User, blank=True, null=True)
37 book_count = models.IntegerField(_('book count'), blank=True, null=True)
38 gazeta_link = models.CharField(blank=True, max_length=240)
39 wiki_link = models.CharField(blank=True, max_length=240)
41 created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True)
42 changed_at = models.DateTimeField(_('creation date'), auto_now=True, db_index=True)
44 class UrlDeprecationWarning(DeprecationWarning):
55 categories_dict = dict((item[::-1] for item in categories_rev.iteritems()))
58 ordering = ('sort_key',)
59 verbose_name = _('tag')
60 verbose_name_plural = _('tags')
61 unique_together = (("slug", "category"),)
62 app_label = 'catalogue'
64 def __unicode__(self):
68 return "Tag(slug=%r)" % self.slug
71 def get_absolute_url(self):
72 return ('catalogue.views.tagged_object_list', [self.url_chunk])
74 def has_description(self):
75 return len(self.description) > 0
76 has_description.short_description = _('description')
77 has_description.boolean = True
80 """Returns global book count for book tags, fragment count for themes."""
81 from catalogue.models import Book, Fragment
83 if self.category == 'book':
85 objects = Book.objects.none()
86 elif self.category == 'theme':
87 objects = Fragment.tagged.with_all((self,))
89 objects = Book.tagged.with_all((self,)).order_by()
90 if self.category != 'set':
91 # eliminate descendants
92 l_tags = Tag.objects.filter(slug__in=[book.book_tag_slug() for book in objects.iterator()])
93 descendants_keys = [book.pk for book in Book.tagged.with_any(l_tags).iterator()]
95 objects = objects.exclude(pk__in=descendants_keys)
96 return objects.count()
99 def get_tag_list(tags):
100 if isinstance(tags, basestring):
105 tags_splitted = tags.split('/')
106 for name in tags_splitted:
108 real_tags.append(Tag.objects.get(slug=name, category=category))
110 elif name in Tag.categories_rev:
111 category = Tag.categories_rev[name]
114 real_tags.append(Tag.objects.exclude(category='book').get(slug=name))
116 except Tag.MultipleObjectsReturned, e:
117 ambiguous_slugs.append(name)
120 # something strange left off
121 raise Tag.DoesNotExist()
123 # some tags should be qualified
124 e = Tag.MultipleObjectsReturned()
126 e.ambiguous_slugs = ambiguous_slugs
129 e = Tag.UrlDeprecationWarning()
134 return TagBase.get_tag_list(tags)
138 return '/'.join((Tag.categories_dict[self.category], self.slug))
141 def tags_from_info(info):
142 from slughifi import slughifi
143 from sortify import sortify
145 categories = (('kinds', 'kind'), ('genres', 'genre'), ('authors', 'author'), ('epochs', 'epoch'))
146 for field_name, category in categories:
148 tag_names = getattr(info, field_name)
151 tag_names = [getattr(info, category)]
153 # For instance, Pictures do not have 'genre' field.
155 for tag_name in tag_names:
156 tag_sort_key = tag_name
157 if category == 'author':
158 tag_sort_key = tag_name.last_name
159 tag_name = tag_name.readable()
160 tag, created = Tag.objects.get_or_create(slug=slughifi(tag_name), category=category)
163 tag.sort_key = sortify(tag_sort_key.lower())
165 meta_tags.append(tag)