From: Marcin Koziej Date: Mon, 16 Dec 2013 15:31:42 +0000 (+0100) Subject: going production #21 X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/08bd2b6b6557481ecbb64b2f07db0d3d9784d9bb?ds=inline going production #21 --- diff --git a/apps/catalogue/locale/pl/LC_MESSAGES/django.po b/apps/catalogue/locale/pl/LC_MESSAGES/django.po index 02d36e089..76b1aa73c 100644 --- a/apps/catalogue/locale/pl/LC_MESSAGES/django.po +++ b/apps/catalogue/locale/pl/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-12-16 09:19+0100\n" -"PO-Revision-Date: 2013-12-16 09:29+0100\n" +"PO-Revision-Date: 2013-12-16 15:51+0100\n" "Last-Translator: Marcin Koziej \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" @@ -321,7 +321,7 @@ msgstr "" #: templates/catalogue/book_info.html:20 msgid "Resource prepared based on:" -msgstr "Tekst opracowany na podstawie:" +msgstr "Zasób opracowany na podstawie:" #: templates/catalogue/book_info.html:28 msgid "Edited and annotated by:" diff --git a/apps/catalogue/migrations/0012_auto__add_field_book_sort_key_author.py b/apps/catalogue/migrations/0012_auto__add_field_book_sort_key_author.py new file mode 100644 index 000000000..076f668e3 --- /dev/null +++ b/apps/catalogue/migrations/0012_auto__add_field_book_sort_key_author.py @@ -0,0 +1,184 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Book.sort_key_author' + db.add_column(u'catalogue_book', 'sort_key_author', + self.gf('django.db.models.fields.CharField')(default=u'', max_length=120, db_index=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Book.sort_key_author' + db.delete_column(u'catalogue_book', 'sort_key_author') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'catalogue.book': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Book'}, + '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'common_slug': ('django.db.models.fields.SlugField', [], {'max_length': '120'}), + 'cover': ('catalogue.fields.EbookField', [], {'max_length': '100', 'null': 'True', 'format_name': "'cover'", 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'epub_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'epub'", 'blank': 'True'}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'fb2_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'fb2'", 'blank': 'True'}), + 'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'html_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'html'", 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'pol'", 'max_length': '3', 'db_index': 'True'}), + 'mobi_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'mobi'", 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['catalogue.Book']"}), + 'parent_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'pdf_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'pdf'", 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'sort_key_author': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'txt_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'txt'", 'blank': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'xml'", 'blank': 'True'}) + }, + 'catalogue.bookmedia': { + 'Meta': {'ordering': "('type', 'name')", 'object_name': 'BookMedia'}, + 'book': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'media'", 'to': "orm['catalogue.Book']"}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'file': ('catalogue.fields.OverwritingFileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': "'100'"}), + 'source_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': "'100'", 'db_index': 'True'}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}) + }, + 'catalogue.collection': { + 'Meta': {'ordering': "('title',)", 'object_name': 'Collection'}, + 'book_slugs': ('django.db.models.fields.TextField', [], {}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'description_de': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_en': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_es': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_fr': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_it': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_lt': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_pl': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_ru': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_uk': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'kind': ('django.db.models.fields.CharField', [], {'default': "'book'", 'max_length': '10', 'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120', 'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'title_de': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_en': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_es': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_fr': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_it': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_lt': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_pl': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_ru': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}), + 'title_uk': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '120', 'null': True, 'db_index': 'True'}) + }, + 'catalogue.fragment': { + 'Meta': {'ordering': "('book', 'anchor')", 'object_name': 'Fragment'}, + 'anchor': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'book': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'fragments'", 'to': "orm['catalogue.Book']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'short_text': ('django.db.models.fields.TextField', [], {}), + 'text': ('django.db.models.fields.TextField', [], {}) + }, + 'catalogue.tag': { + 'Meta': {'ordering': "('sort_key',)", 'unique_together': "(('slug', 'category'),)", 'object_name': 'Tag'}, + 'book_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'category': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'description_de': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_en': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_es': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_fr': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_it': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_lt': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_pl': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_ru': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'description_uk': ('django.db.models.fields.TextField', [], {'null': True, 'blank': True}), + 'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}), + 'name_de': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_en': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_es': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_fr': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_it': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_lt': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_pl': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_ru': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'name_uk': ('django.db.models.fields.CharField', [], {'blank': True, 'max_length': '50', 'null': True, 'db_index': 'True'}), + 'picture_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'wiki_link_de': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_en': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_es': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_fr': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_it': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_lt': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_pl': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_ru': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}), + 'wiki_link_uk': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': True, 'blank': True}) + }, + 'catalogue.tagrelation': { + 'Meta': {'unique_together': "(('tag', 'content_type', 'object_id'),)", 'object_name': 'TagRelation', 'db_table': "u'catalogue_tag_relation'"}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'to': "orm['catalogue.Tag']"}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['catalogue'] \ No newline at end of file diff --git a/apps/catalogue/models/book.py b/apps/catalogue/models/book.py index 30b447197..9f7803dcd 100644 --- a/apps/catalogue/models/book.py +++ b/apps/catalogue/models/book.py @@ -27,6 +27,7 @@ class Book(models.Model): """Represents a book imported from WL-XML.""" title = models.CharField(_('title'), max_length=120) sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False) + sort_key_author = models.CharField(_('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) common_slug = models.SlugField(_('slug'), max_length=120, db_index=True) @@ -141,6 +142,14 @@ class Book(models.Model): for fragm in self.fragments.all().iterator(): fragm.reset_short_html() + try: + author = self.tags.filter(category='author')[0].sort_key + except IndexError: + author = u'' + type(self).objects.filter(pk=self.pk).update(sort_key_author=author) + + + def has_description(self): return len(self.description) > 0 has_description.short_description = _('description') @@ -405,7 +414,7 @@ class Book(models.Model): for category in tags: cat = [] for tag in tags[category]: - tag_info = {'slug': tag.slug} + tag_info = {'slug': tag.slug, 'name': tag.name} for lc, ln in settings.LANGUAGES: tag_name = getattr(tag, "name_%s" % lc) if tag_name: @@ -497,6 +506,8 @@ class Book(models.Model): rel_info = book.related_info() names = [(related_tag_name(tag), Tag.create_url('author', tag['slug'])) for tag in rel_info['tags'].get('author', ())] + import logging + logging.info("%s, %s" % (book.slug, unicode(rel_info['tags'].get('author', ())))) if 'parents' in rel_info: books = [(name, Book.create_url(slug)) for name, slug in rel_info['parents']] diff --git a/apps/catalogue/templates/catalogue/menu.html b/apps/catalogue/templates/catalogue/menu.html index 4fe776925..55a9e1851 100644 --- a/apps/catalogue/templates/catalogue/menu.html +++ b/apps/catalogue/templates/catalogue/menu.html @@ -31,4 +31,9 @@ {% trans "DAISY" %} + + diff --git a/apps/catalogue/templates/catalogue/tagged_object_list.html b/apps/catalogue/templates/catalogue/tagged_object_list.html index 96b628d59..ee207ff57 100644 --- a/apps/catalogue/templates/catalogue/tagged_object_list.html +++ b/apps/catalogue/templates/catalogue/tagged_object_list.html @@ -110,17 +110,19 @@ {% endif %} diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index 6d5ff795a..7c1109008 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -14,7 +14,7 @@ SLUG = r'[a-z0-9-]*' urlpatterns = patterns('picture.views', # pictures - currently pictures are coupled with catalogue, hence the url is here - url(r'^obraz/?$', 'picture_list_thumb'), + url(r'^obraz/?$', 'picture_list_thumb', name='picture_list_thumb'), url(r'^obraz/(?P%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'), url(r'^obraz/(?P%s)/?$' % SLUG, 'picture_detail'), @@ -65,7 +65,5 @@ urlpatterns += patterns('catalogue.views', 'book_fragments', name='book_fragments'), # This should be the last pattern. - url(r'^literatura/(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'literature': True, 'gallery': False}, name='tagged_object_list'), - url(r'^galeria/(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'literature': False, 'gallery': True}, name='tagged_object_list'), url(r'^(?P[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'), ) diff --git a/apps/catalogue/utils.py b/apps/catalogue/utils.py index 33b0830e7..fd74c9498 100644 --- a/apps/catalogue/utils.py +++ b/apps/catalogue/utils.py @@ -192,6 +192,52 @@ class MultiQuerySet(object): stop = total_len - len(items) continue +class SortedMultiQuerySet(MultiQuerySet): + def __init__(self, *args, **kwargs): + self.order_by = kwargs.pop('order_by', None) + self.sortfn = kwargs.pop('sortfn', None) + if self.order_by is not None: + self.sortfn = lambda a, b: cmp(getattr(a, self.order_by), + getattr(b, self.order_by)) + super(SortedMultiQuerySet, self).__init__(*args, **kwargs) + + def __getitem__(self, item): + sort_heads = [0] * len(self.querysets) + try: + indices = (offset, stop, step) = item.indices(self.count()) + except AttributeError: + # it's not a slice - make it one + return self[item : item + 1][0] + items = [] + total_len = stop - offset + skipped = 0 + i_s = range(len(sort_heads)) + + while len(items) < total_len: + candidate = None + for i in i_s: + def get_next(): + return self.querysets[i][sort_heads[i]] + try: + if candidate is None: + candidate = get_next() + else: + competitor = get_next() + if self.sortfn(candidate, competitor) > 0: + candidate = competitor + except IndexError: + continue # continue next sort_head + sort_heads[i] += 1 + # we have no more elements: + if candidate is None: + break + if skipped < offset: + skipped += 1 + continue # continue next item + items.append(candidate) + + return items + def truncate_html_words(s, num, end_text='...'): """Truncates HTML to a certain number of words (not counting tags and diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index deab25967..fd66da9dd 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -23,7 +23,7 @@ from django.views.decorators.vary import vary_on_headers from ajaxable.utils import JSONResponse, AjaxableFormView from catalogue import models from catalogue import forms -from catalogue.utils import split_tags, MultiQuerySet +from catalogue.utils import split_tags, MultiQuerySet, SortedMultiQuerySet from catalogue.templatetags.catalogue_tags import tag_list, collection_list from pdcounter import models as pdcounter_models from pdcounter import views as pdcounter_views @@ -65,9 +65,13 @@ def catalogue(request): return render_to_string('catalogue/tag_list_split.html', ctx) output = {'theme': {}} - output['theme'] = render_split(fragment_tags) + output['theme'] = render_tag_list(fragment_tags) for category, tags in categories.items(): - output[category] = render_split(tags) + if category in ('author', 'theme'): + output[category] = render_tag_list(tags) + else: + output[category] = render_split(tags) + output['collections'] = render_to_string( 'catalogue/collection_list.html', collection_list(collections)) @@ -150,7 +154,7 @@ def differentiate_tags(request, tags, ambiguous_slugs): # TODO: Rewrite this hellish piece of code which tries to do everything -def tagged_object_list(request, tags='', gallery=True, literature=True): +def tagged_object_list(request, tags=''): # preliminary tests and conditions try: tags = models.Tag.get_tag_list(tags) @@ -178,7 +182,6 @@ def tagged_object_list(request, tags='', gallery=True, literature=True): raise Http404 # beginning of digestion - theme_is_set = [tag for tag in tags if tag.category == 'theme'] shelf_is_set = [tag for tag in tags if tag.category == 'set'] only_shelf = shelf_is_set and len(tags) == 1 @@ -192,16 +195,10 @@ def tagged_object_list(request, tags='', gallery=True, literature=True): if theme_is_set: shelf_tags = [tag for tag in tags if tag.category == 'set'] fragment_tags = [tag for tag in tags if tag.category != 'set'] - if literature: - fragments = models.Fragment.tagged.with_all(fragment_tags) - else: - fragments = models.Fragment.objects.none() - if gallery: - areas = PictureArea.tagged.with_all(fragment_tags) - else: - areas = PictureArea.objects.none() + fragments = models.Fragment.tagged.with_all(fragment_tags) + areas = PictureArea.tagged.with_all(fragment_tags) - if shelf_tags and literature: + if shelf_tags: books = models.Book.tagged.with_all(shelf_tags).order_by() l_tags = models.Tag.objects.filter(category='book', slug__in=[book.book_tag_slug() for book in books.iterator()]) @@ -230,23 +227,19 @@ def tagged_object_list(request, tags='', gallery=True, literature=True): related_tags = (tag for tag in related_tags if tag not in fragment_tags) categories = split_tags(related_tags, categories) - object_queries.append(areas) + + # we want the Pictures to go first + object_queries.insert(0, areas) objects = MultiQuerySet(*object_queries) else: - if literature: - if shelf_is_set: - books = models.Book.tagged.with_all(tags) - else: - books = models.Book.tagged_top_level(tags) + if shelf_is_set: + books = models.Book.tagged.with_all(tags).order_by('sort_key_author') else: - books = models.Book.objects.none() + books = models.Book.tagged_top_level(tags).order_by('sort_key_author') - if gallery: - pictures = Picture.tagged.with_all(tags) - else: - pictures = Picture.objects.none() + pictures = Picture.tagged.with_all(tags).order_by('sort_key_author') - if literature and books.count() > 0: + if books.count() > 0: # get related tags from `tag_counter` and `theme_counter` related_counts = {} tags_pks = [tag.pk for tag in tags] @@ -263,7 +256,27 @@ def tagged_object_list(request, tags='', gallery=True, literature=True): categories = split_tags(related_tags) del related_tags - objects = MultiQuerySet(pictures, books) + if pictures.count() > 0: + related_counts = {} + tags_pks = [tag.pk for tag in tags] + for picture in pictures: + for tag_pk, value in itertools.chain(picture.tag_counter.iteritems(), picture.theme_counter.iteritems()): + if tag_pk in tags_pks: + continue + logging.info("counting tag not in tags_pks: %d", tag_pk) + related_counts[tag_pk] = related_counts.get(tag_pk, 0) + value + related_tags = models.Tag.objects.filter(pk__in=related_counts.keys()) + related_tags = [tag for tag in related_tags if tag not in tags] + for tag in related_tags: + tag.count = related_counts[tag.pk] + + categories = split_tags(related_tags) + del related_tags + + logging.info("Returning %d picutres and %d books" % (pictures.count(), books.count())) + objects = SortedMultiQuerySet(pictures, books, order_by='sort_key_author') + + if not objects: only_author = len(tags) == 1 and tags[0].category == 'author' diff --git a/apps/picture/migrations/0006_auto__add_field_picture_width__add_field_picture_height.py b/apps/picture/migrations/0006_auto__add_field_picture_width__add_field_picture_height.py new file mode 100644 index 000000000..1b1d3b198 --- /dev/null +++ b/apps/picture/migrations/0006_auto__add_field_picture_width__add_field_picture_height.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Picture.width' + db.add_column(u'picture_picture', 'width', + self.gf('django.db.models.fields.IntegerField')(null=True), + keep_default=False) + + # Adding field 'Picture.height' + db.add_column(u'picture_picture', 'height', + self.gf('django.db.models.fields.IntegerField')(null=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Picture.width' + db.delete_column(u'picture_picture', 'width') + + # Deleting field 'Picture.height' + db.delete_column(u'picture_picture', 'height') + + + models = { + u'picture.picture': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Picture'}, + 'areas': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image_file': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) + } + } + + complete_apps = ['picture'] \ No newline at end of file diff --git a/apps/picture/migrations/0007_auto__add_picturearea__del_field_picture_areas__add_field_picture_area.py b/apps/picture/migrations/0007_auto__add_picturearea__del_field_picture_areas__add_field_picture_area.py new file mode 100644 index 000000000..91652cbea --- /dev/null +++ b/apps/picture/migrations/0007_auto__add_picturearea__del_field_picture_areas__add_field_picture_area.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'PictureArea' + db.create_table(u'picture_picturearea', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('picture', self.gf('django.db.models.fields.related.ForeignKey')(related_name='areas', to=orm['picture.Picture'])), + ('area', self.gf('jsonfield.fields.JSONField')(default={})), + ('kind', self.gf('django.db.models.fields.CharField')(max_length=10, db_index=True)), + )) + db.send_create_signal(u'picture', ['PictureArea']) + + # Deleting field 'Picture.areas' + db.delete_column(u'picture_picture', 'areas') + + # Adding field 'Picture.areas_json' + db.add_column(u'picture_picture', 'areas_json', + self.gf('jsonfield.fields.JSONField')(default={}), + keep_default=False) + + + def backwards(self, orm): + # Deleting model 'PictureArea' + db.delete_table(u'picture_picturearea') + + # Adding field 'Picture.areas' + db.add_column(u'picture_picture', 'areas', + self.gf('jsonfield.fields.JSONField')(default={}), + keep_default=False) + + # Deleting field 'Picture.areas_json' + db.delete_column(u'picture_picture', 'areas_json') + + + models = { + u'picture.picture': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Picture'}, + 'areas_json': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image_file': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) + }, + u'picture.picturearea': { + 'Meta': {'object_name': 'PictureArea'}, + 'area': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.CharField', [], {'max_length': '10', 'db_index': 'True'}), + 'picture': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areas'", 'to': u"orm['picture.Picture']"}) + } + } + + complete_apps = ['picture'] \ No newline at end of file diff --git a/apps/picture/migrations/0008_auto__add_field_picturearea__related_info.py b/apps/picture/migrations/0008_auto__add_field_picturearea__related_info.py new file mode 100644 index 000000000..60411fcc9 --- /dev/null +++ b/apps/picture/migrations/0008_auto__add_field_picturearea__related_info.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Picture._related_info' + db.add_column(u'picture_picture', '_related_info', + self.gf('jsonfield.fields.JSONField')(null=True, blank=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Picture._related_info' + db.delete_column(u'picture_picture', '_related_info') + + + models = { + u'picture.picture': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Picture'}, + '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}), + 'areas_json': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image_file': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) + }, + u'picture.picturearea': { + 'Meta': {'object_name': 'PictureArea'}, + 'area': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.CharField', [], {'max_length': '10', 'db_index': 'True'}), + 'picture': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areas'", 'to': u"orm['picture.Picture']"}) + } + } + + complete_apps = ['picture'] \ No newline at end of file diff --git a/apps/picture/migrations/0009_auto__add_field_picture_sort_key_author.py b/apps/picture/migrations/0009_auto__add_field_picture_sort_key_author.py new file mode 100644 index 000000000..013e345fa --- /dev/null +++ b/apps/picture/migrations/0009_auto__add_field_picture_sort_key_author.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Picture.sort_key_author' + db.add_column(u'picture_picture', 'sort_key_author', + self.gf('django.db.models.fields.CharField')(default=u'', max_length=120, db_index=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Picture.sort_key_author' + db.delete_column(u'picture_picture', 'sort_key_author') + + + models = { + u'picture.picture': { + 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Picture'}, + '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}), + 'areas_json': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image_file': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}), + 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), + 'sort_key_author': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '120', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), + 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), + 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) + }, + u'picture.picturearea': { + 'Meta': {'object_name': 'PictureArea'}, + 'area': ('jsonfield.fields.JSONField', [], {'default': '{}'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.CharField', [], {'max_length': '10', 'db_index': 'True'}), + 'picture': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'areas'", 'to': u"orm['picture.Picture']"}) + } + } + + complete_apps = ['picture'] \ No newline at end of file diff --git a/apps/picture/models.py b/apps/picture/models.py index 2703c8091..705025a7f 100644 --- a/apps/picture/models.py +++ b/apps/picture/models.py @@ -16,17 +16,18 @@ from StringIO import StringIO import jsonfield import itertools import logging -logging.basicConfig(level=logging.DEBUG) from sorl.thumbnail import get_thumbnail, default from .engine import CustomCroppingEngine from PIL import Image -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import get_language, ugettext_lazy as _ from newtagging import managers from os import path +permanent_cache = get_cache('permanent') + picture_storage = FileSystemStorage(location=path.join( settings.MEDIA_ROOT, 'pictures'), base_url=settings.MEDIA_URL + "pictures/") @@ -52,10 +53,35 @@ class PictureArea(models.Model): pa.area = coords return pa + def reset_short_html(self): + if self.id is None: + return + + cache_key = "PictureArea.short_html/%d/%s" + for lang, langname in settings.LANGUAGES: + permanent_cache.delete(cache_key % (self.id, lang)) + + def short_html(self): - short_html = unicode(render_to_string( - 'picture/picturearea_short.html', {'area': self})) - return mark_safe(short_html) + if self.id: + cache_key = "PictureArea.short_html/%d/%s" % (self.id, get_language()) + short_html = permanent_cache.get(cache_key) + else: + short_html = None + + if short_html is not None: + return mark_safe(short_html) + else: + theme = self.tags.filter(category='theme') + theme = theme and theme[0] or None + thing = self.tags.filter(category='thing') + thing = thing and thing[0] or None + area = self + short_html = unicode(render_to_string( + 'picture/picturearea_short.html', locals())) + if self.id: + permanent_cache.set(cache_key, short_html) + return mark_safe(short_html) class Picture(models.Model): @@ -66,6 +92,7 @@ class Picture(models.Model): title = models.CharField(_('title'), max_length=120) slug = models.SlugField(_('slug'), max_length=120, db_index=True, unique=True) sort_key = models.CharField(_('sort key'), max_length=120, db_index=True, editable=False) + sort_key_author = models.CharField(_('sort key by author'), max_length=120, db_index=True, editable=False, default=u'') created_at = models.DateTimeField(_('creation date'), auto_now_add=True, db_index=True) changed_at = models.DateTimeField(_('creation date'), auto_now=True, db_index=True) xml_file = models.FileField('xml_file', upload_to="xml", storage=picture_storage) @@ -76,6 +103,8 @@ class Picture(models.Model): culturepl_link = models.CharField(blank=True, max_length=240) wiki_link = models.CharField(blank=True, max_length=240) + _related_info = jsonfield.JSONField(blank=True, null=True, editable=False) + width = models.IntegerField(null=True) height = models.IntegerField(null=True) @@ -148,8 +177,10 @@ class Picture(models.Model): picture.title = unicode(picture_xml.picture_info.title) picture.extra_info = picture_xml.picture_info.to_dict() + picture_tags = set(catalogue.models.Tag.tags_from_info(picture_xml.picture_info)) motif_tags = set() thing_tags = set() + area_data = {'themes':{}, 'things':{}} for part in picture_xml.partiter(): @@ -191,10 +222,9 @@ class Picture(models.Model): logging.debug("coords for theme: %s" % part['coords']) area = PictureArea.rectangle(picture, 'theme', part['coords']) area.save() - area.tags = _tags + area.tags = _tags.union(picture_tags) - picture.tags = catalogue.models.Tag.tags_from_info(picture_xml.picture_info) + \ - list(motif_tags) + list(thing_tags) + picture.tags = picture_tags.union(motif_tags).union(thing_tags) picture.areas_json = area_data if image_file is not None: @@ -276,13 +306,24 @@ class Picture(models.Model): def reset_short_html(self): if self.id is None: return + + type(self).objects.filter(pk=self.pk).update(_related_info=None) + for area in self.areas.all().iterator(): + area.reset_short_html() + + try: + author = self.tags.filter(category='author')[0].sort_key + except IndexError: + author = u'' + type(self).objects.filter(pk=self.pk).update(sort_key_author=author) - cache_key = "Picture.short_html/%d" % (self.id) - get_cache('permanent').delete(cache_key) + cache_key = "Picture.short_html/%d/%s" + for lang, langname in settings.LANGUAGES: + permanent_cache.delete(cache_key % (self.id, lang)) def short_html(self): if self.id: - cache_key = "Picture.short_html/%d" % (self.id) + cache_key = "Picture.short_html/%d/%s" % (self.id, get_language()) short_html = get_cache('permanent').get(cache_key) else: short_html = None @@ -314,3 +355,90 @@ class Picture(models.Model): else: names = [tag[0] for tag in names] return ', '.join(names) + + def related_info(self): + """Keeps info about related objects (tags) in cache field.""" + if self._related_info is not None: + return self._related_info + else: + rel = {'tags': {}} + + tags = self.tags.filter(category__in=( + 'author', 'kind', 'genre', 'epoch')) + tags = split_tags(tags) + for category in tags: + cat = [] + for tag in tags[category]: + tag_info = {'slug': tag.slug, 'name': tag.name} + for lc, ln in settings.LANGUAGES: + tag_name = getattr(tag, "name_%s" % lc) + if tag_name: + tag_info["name_%s" % lc] = tag_name + cat.append(tag_info) + rel['tags'][category] = cat + + + if self.pk: + type(self).objects.filter(pk=self.pk).update(_related_info=rel) + return rel + + # copied from book.py, figure out + def related_themes(self): + # self.theme_counter hides a computation, so a line below actually makes sense + theme_counter = self.theme_counter + picture_themes = list(catalogue.models.Tag.objects.filter(pk__in=theme_counter.keys())) + for tag in picture_themes: + tag.count = theme_counter[tag.pk] + return picture_themes + + def reset_tag_counter(self): + if self.id is None: + return + + cache_key = "Picture.tag_counter/%d" % self.id + permanent_cache.delete(cache_key) + if self.parent: + self.parent.reset_tag_counter() + + @property + def tag_counter(self): + if self.id: + cache_key = "Picture.tag_counter/%d" % self.id + tags = permanent_cache.get(cache_key) + else: + tags = None + + if tags is None: + tags = {} + # do we need to do this? there are no children here. + for tag in self.tags.exclude(category__in=('book', 'theme', 'thing', 'set')).order_by().iterator(): + tags[tag.pk] = 1 + + if self.id: + permanent_cache.set(cache_key, tags) + return tags + + def reset_theme_counter(self): + if self.id is None: + return + + cache_key = "Picture.theme_counter/%d" % self.id + permanent_cache.delete(cache_key) + + @property + def theme_counter(self): + if self.id: + cache_key = "Picture.theme_counter/%d" % self.id + tags = permanent_cache.get(cache_key) + else: + tags = None + + if tags is None: + tags = {} + for area in PictureArea.objects.filter(picture=self).order_by().iterator(): + for tag in area.tags.filter(category__in=('theme','thing')).order_by().iterator(): + tags[tag.pk] = tags.get(tag.pk, 0) + 1 + + if self.id: + permanent_cache.set(cache_key, tags) + return tags diff --git a/apps/picture/templates/picture/picture_wide.html b/apps/picture/templates/picture/picture_wide.html index 46e37c9af..3125b0f8f 100644 --- a/apps/picture/templates/picture/picture_wide.html +++ b/apps/picture/templates/picture/picture_wide.html @@ -55,9 +55,6 @@ {% if extra_info.about and not hide_about %}
  • {% trans "Picture on" %} {% trans "Editor's Platform" %}
  • {% endif %} - {% if picture.culturepl_link %} -
  • {% trans "Picture description on Lektury.Gazeta.pl" %}
  • - {% endif %} {% if picture.wiki_link %}
  • {% trans "Picture description on Wikipedia" %}
  • {% endif %} diff --git a/apps/picture/views.py b/apps/picture/views.py index 6529e8db7..f98d749fb 100644 --- a/apps/picture/views.py +++ b/apps/picture/views.py @@ -5,6 +5,7 @@ from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.core.paginator import Paginator from picture.models import Picture +from catalogue.utils import split_tags # was picture/picture_list.html list (without thumbs) def picture_list(request, filter=None, get_filter=None, template_name='catalogue/picture_list.html', cache_key=None, context=None): @@ -36,12 +37,14 @@ def picture_list_thumb(request, filter=None, get_filter=None, template_name='pic def picture_detail(request, slug): picture = get_object_or_404(Picture, slug=slug) - categories = SortedDict() - for tag in picture.tags.iterator(): - categories.setdefault(tag.category, []).append(tag) + theme_things = split_tags(picture.related_themes_things()) - themes = categories.get('theme', []) - things = categories.get('thing', []) + # categories = SortedDict() + # for tag in picture.tags.iterator(): + # categories.setdefault(tag.category, []).append(tag) + + themes = theme_things.get('theme', []) + things = theme_things.get('thing', []) extra_info = picture.extra_info diff --git a/apps/wolnelektury_core/static/css/header.css b/apps/wolnelektury_core/static/css/header.css index f1bd0df94..10d4956a1 100755 --- a/apps/wolnelektury_core/static/css/header.css +++ b/apps/wolnelektury_core/static/css/header.css @@ -150,8 +150,8 @@ li.menu { } a.menu { display: block; - padding-left: 1.4em; - padding-right: 1.4em; + padding-left: 1.2em; + padding-right: 1.2em; /* must match grid-line */ height: 3.1em; padding-top: 1.8em; diff --git a/apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png b/apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png new file mode 100644 index 000000000..897a8352b Binary files /dev/null and b/apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png differ diff --git a/apps/wolnelektury_core/static/img/logo_nck_200trans.png b/apps/wolnelektury_core/static/img/logo_nck_200trans.png new file mode 100644 index 000000000..2731aacec Binary files /dev/null and b/apps/wolnelektury_core/static/img/logo_nck_200trans.png differ diff --git a/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo index 4cfc69e47..9dfa5d3ef 100644 Binary files a/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo differ diff --git a/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo index fbfc91ba5..7a4cdebe4 100644 Binary files a/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo differ diff --git a/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo index 11bd91561..a5ad327ba 100644 Binary files a/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo differ diff --git a/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo index 7f2d6f711..b57074733 100644 Binary files a/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo differ diff --git a/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo index dbd1ff37d..3912839c1 100644 Binary files a/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo differ diff --git a/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo b/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo index cab4ca5f1..d6335b97c 100644 Binary files a/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo differ