going production #21
authorMarcin Koziej <marcin@lolownia.org>
Mon, 16 Dec 2013 15:31:42 +0000 (16:31 +0100)
committerMarcin Koziej <marcin@lolownia.org>
Mon, 16 Dec 2013 15:31:42 +0000 (16:31 +0100)
24 files changed:
apps/catalogue/locale/pl/LC_MESSAGES/django.po
apps/catalogue/migrations/0012_auto__add_field_book_sort_key_author.py [new file with mode: 0644]
apps/catalogue/models/book.py
apps/catalogue/templates/catalogue/menu.html
apps/catalogue/templates/catalogue/tagged_object_list.html
apps/catalogue/urls.py
apps/catalogue/utils.py
apps/catalogue/views.py
apps/picture/migrations/0006_auto__add_field_picture_width__add_field_picture_height.py [new file with mode: 0644]
apps/picture/migrations/0007_auto__add_picturearea__del_field_picture_areas__add_field_picture_area.py [new file with mode: 0644]
apps/picture/migrations/0008_auto__add_field_picturearea__related_info.py [new file with mode: 0644]
apps/picture/migrations/0009_auto__add_field_picture_sort_key_author.py [new file with mode: 0644]
apps/picture/models.py
apps/picture/templates/picture/picture_wide.html
apps/picture/views.py
apps/wolnelektury_core/static/css/header.css
apps/wolnelektury_core/static/img/logo_nck_200horiz_trans.png [new file with mode: 0644]
apps/wolnelektury_core/static/img/logo_nck_200trans.png [new file with mode: 0644]
wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo
wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo
wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo
wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo
wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo
wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo

index 02d36e0..76b1aa7 100644 (file)
@@ -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 <marcinkoziej@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\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 (file)
index 0000000..076f668
--- /dev/null
@@ -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
index 30b4471..9f7803d 100644 (file)
@@ -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']]
index 4fe7769..55a9e18 100644 (file)
@@ -31,4 +31,9 @@
                <a href="{% url 'daisy_list' %}" class="menu">
                        <span class='mono'>{% trans "DAISY" %}</span></a>
        </li>
+       <li class="menu">
+               <a href="{% url 'picture_list_thumb' %}" class="menu">
+                       <span class='mono'>{% trans "Gallery" %}</span></a>
+       </li>
+
 </ul>
index 96b628d..ee207ff 100644 (file)
             <ul>
         {% if last_tag.gazeta_link %}
         <li><a href="{{ last_tag.gazeta_link }}">
-               {% trans "in Lektury.Gazeta.pl" %}
+            {% trans "in Lektury.Gazeta.pl" %}
         </a></li>
         {% endif %}
         {% if last_tag.wiki_link %}
         <li><a href="{{ last_tag.wiki_link }}">
-                       {% trans "in Wikipedia" %}
+           {% trans "in Wikipedia" %}
         </a></li>
         {% endif %}
-
-
-
+       {% if last_tag.culturepl_link %}
+       <li><a href="{{ picture.culturepl_link }}">
+           {% trans "Picture description on Culture.pl" %}
+       </a></li>
+       {% endif %}
             </ul>
             {% endif %}
         </div>
index 6d5ff79..7c11090 100644 (file)
@@ -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<slug>%s).html$' % SLUG, 'picture_viewer', name='picture_viewer'),
     url(r'^obraz/(?P<slug>%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<tags>[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'literature': True, 'gallery': False}, name='tagged_object_list'),
-    url(r'^galeria/(?P<tags>[a-zA-Z0-9-/]*)/$', 'tagged_object_list', {'literature': False, 'gallery': True}, name='tagged_object_list'),
     url(r'^(?P<tags>[a-zA-Z0-9-/]*)/$', 'tagged_object_list', name='tagged_object_list'),
 )
index 33b0830..fd74c94 100644 (file)
@@ -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
index deab259..fd66da9 100644 (file)
@@ -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 (file)
index 0000000..1b1d3b1
--- /dev/null
@@ -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 (file)
index 0000000..91652cb
--- /dev/null
@@ -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 (file)
index 0000000..60411fc
--- /dev/null
@@ -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 (file)
index 0000000..013e345
--- /dev/null
@@ -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
index 2703c80..705025a 100644 (file)
@@ -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
index 46e37c9..3125b0f 100644 (file)
@@ -55,9 +55,6 @@
       {% if extra_info.about and not hide_about %}
       <li>{% trans "Picture on" %} <a href="{{ extra_info.about }}">{% trans "Editor's Platform" %}</a></li>
       {% endif %}
-      {% if picture.culturepl_link %}
-      <li><a href="{{ picture.culturepl_link }}">{% trans "Picture description on Lektury.Gazeta.pl" %}</a></li>
-      {% endif %}
       {% if picture.wiki_link %}
       <li><a href="{{ picture.wiki_link }}">{% trans "Picture description on Wikipedia" %}</a></li>
       {% endif %}
index 6529e8d..f98d749 100644 (file)
@@ -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
 
index f1bd0df..10d4956 100755 (executable)
@@ -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 (file)
index 0000000..897a835
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 (file)
index 0000000..2731aac
Binary files /dev/null and b/apps/wolnelektury_core/static/img/logo_nck_200trans.png differ
index 4cfc69e..9dfa5d3 100644 (file)
Binary files a/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/de/LC_MESSAGES/django.mo differ
index fbfc91b..7a4cdeb 100644 (file)
Binary files a/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/en/LC_MESSAGES/django.mo differ
index 11bd915..a5ad327 100644 (file)
Binary files a/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/es/LC_MESSAGES/django.mo differ
index 7f2d6f7..b570747 100644 (file)
Binary files a/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/lt/LC_MESSAGES/django.mo differ
index dbd1ff3..3912839 100644 (file)
Binary files a/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/pl/LC_MESSAGES/django.mo differ
index cab4ca5..d6335b9 100644 (file)
Binary files a/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo and b/wolnelektury/locale-contrib/uk/LC_MESSAGES/django.mo differ