merge picture to pretty
authorMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Tue, 20 Dec 2011 09:37:37 +0000 (10:37 +0100)
committerMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Tue, 20 Dec 2011 09:37:37 +0000 (10:37 +0100)
13 files changed:
apps/catalogue/models.py
apps/catalogue/urls.py
apps/catalogue/views.py
apps/picture/admin.py [new file with mode: 0644]
apps/picture/models.py
apps/picture/views.py [new file with mode: 0644]
apps/sponsors/models.py
lib/librarian
requirements.txt
wolnelektury/static/css/master.css
wolnelektury/templates/catalogue/book_list.html
wolnelektury/templates/catalogue/picture_detail.html [new file with mode: 0644]
wolnelektury/templates/catalogue/picture_list.html [new file with mode: 0644]

index 8b65d4b..6470ebb 100644 (file)
@@ -174,7 +174,11 @@ class Tag(TagBase):
             try:
                 tag_names = getattr(info, field_name)
             except:
             try:
                 tag_names = getattr(info, field_name)
             except:
-                tag_names = [getattr(info, category)]
+                try:
+                    tag_names = [getattr(info, category)]
+                except:
+                    # For instance, Pictures do not have 'genre' field.
+                    continue
             for tag_name in tag_names:
                 tag_sort_key = tag_name
                 if category == 'author':
             for tag_name in tag_names:
                 tag_sort_key = tag_name
                 if category == 'author':
index 452335a..bb1b960 100644 (file)
@@ -5,7 +5,7 @@
 from django.conf.urls.defaults import *
 from catalogue.feeds import AudiobookFeed
 from catalogue.models import Book
 from django.conf.urls.defaults import *
 from catalogue.feeds import AudiobookFeed
 from catalogue.models import Book
-
+from picture.models import Picture
 
 urlpatterns = patterns('catalogue.views',
     url(r'^$', 'catalogue', name='catalogue'),
 
 urlpatterns = patterns('catalogue.views',
     url(r'^$', 'catalogue', name='catalogue'),
@@ -43,5 +43,10 @@ urlpatterns = patterns('catalogue.views',
     url(r'^audiobooki/(?P<type>mp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'),
 
     url(r'^custompdf/(?P<book_fileid>%s).pdf' % Book.FILEID_RE, 'download_custom_pdf'),
     url(r'^audiobooki/(?P<type>mp3|ogg|daisy|all).xml$', AudiobookFeed(), name='audiobook_feed'),
 
     url(r'^custompdf/(?P<book_fileid>%s).pdf' % Book.FILEID_RE, 'download_custom_pdf'),
-)
+
+) + patterns('picture.views',
+        # pictures - currently pictures are coupled with catalogue, hence the url is here
+        url(r'^obraz/?$', 'picture_list'),
+        url(r'^obraz/(?P<picture>%s)/?$' % Picture.URLID_RE, 'picture_detail')
+    )
 
 
index 902907d..13bb5ac 100644 (file)
@@ -226,7 +226,7 @@ def book_detail(request, book):
         book = models.Book.objects.get(**kwargs)
     except models.Book.DoesNotExist:
         return pdcounter_views.book_stub_detail(request, kwargs['slug'])
         book = models.Book.objects.get(**kwargs)
     except models.Book.DoesNotExist:
         return pdcounter_views.book_stub_detail(request, kwargs['slug'])
-
+    
     book_tag = book.book_tag()
     tags = list(book.tags.filter(~Q(category='set')))
     categories = split_tags(tags)
     book_tag = book.book_tag()
     tags = list(book.tags.filter(~Q(category='set')))
     categories = split_tags(tags)
diff --git a/apps/picture/admin.py b/apps/picture/admin.py
new file mode 100644 (file)
index 0000000..fb6bcf2
--- /dev/null
@@ -0,0 +1,9 @@
+
+from django.contrib import admin
+from picture.models import Picture
+from sorl.thumbnail.admin import AdminImageMixin
+
+class PictureAdmin(AdminImageMixin, admin.ModelAdmin):
+    pass
+
+admin.site.register(Picture, PictureAdmin)
index af691f8..01f9b8d 100644 (file)
@@ -1,8 +1,12 @@
 from django.db import models
 import catalogue.models
 from django.db import models
 import catalogue.models
-from catalogue.fields import OverwritingFileField
+from django.db.models import permalink
+from sorl.thumbnail import ImageField
 from django.conf import settings
 from django.core.files.storage import FileSystemStorage
 from django.conf import settings
 from django.core.files.storage import FileSystemStorage
+from django.utils.datastructures import SortedDict
+from librarian import dcparser, picture
+
 from django.utils.translation import ugettext_lazy as _
 from newtagging import managers
 from os import path
 from django.utils.translation import ugettext_lazy as _
 from newtagging import managers
 from os import path
@@ -22,7 +26,7 @@ class Picture(models.Model):
     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)
     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)
-    image_file  = models.FileField(_('image_file'), upload_to="images", storage=picture_storage)
+    image_file  = ImageField(_('image_file'), upload_to="images", storage=picture_storage)
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
@@ -36,6 +40,9 @@ class Picture(models.Model):
         verbose_name = _('picture')
         verbose_name_plural = _('pictures')
 
         verbose_name = _('picture')
         verbose_name_plural = _('pictures')
 
+    URLID_RE = r'[a-z0-9-]+'
+    FILEID_RE = r'[a-z0-9-]+'
+
     def save(self, force_insert=False, force_update=False, reset_short_html=True, **kwargs):
         from sortify import sortify
 
     def save(self, force_insert=False, force_update=False, reset_short_html=True, **kwargs):
         from sortify import sortify
 
@@ -48,6 +55,13 @@ class Picture(models.Model):
     def __unicode__(self):
         return self.title
 
     def __unicode__(self):
         return self.title
 
+    @permalink
+    def get_absolute_url(self):
+        return ('picture.views.picture_detail', [self.urlid()])
+
+    def urlid(self):
+        return self.slug
+
     @classmethod
     def from_xml_file(cls, xml_file, images_path=None, overwrite=False):
         """
     @classmethod
     def from_xml_file(cls, xml_file, images_path=None, overwrite=False):
         """
@@ -84,3 +98,37 @@ class Picture(models.Model):
             if close_xml_file:
                 xml_file.close()
         return picture
             if close_xml_file:
                 xml_file.close()
         return picture
+
+    @classmethod
+    def picture_list(cls, filter=None):
+        """Generates a hierarchical listing of all pictures
+        Pictures are optionally filtered with a test function.
+        """
+
+        pics = cls.objects.all().order_by('sort_key')\
+            .only('title', 'slug', 'image_file')
+
+        if filter:
+            pics = pics.filter(filter).distinct()
+
+        pics_by_author = SortedDict()
+        orphans = []
+        for tag in catalogue.models.Tag.objects.filter(category='author'):
+            pics_by_author[tag] = []
+
+        for pic in pics:
+            authors = list(pic.tags.filter(category='author'))
+            if authors:
+                for author in authors:
+                    pics_by_author[author].append(pic)
+            else:
+                orphans.append(pic)
+
+        return pics_by_author, orphans
+
+    @property
+    def info(self):
+        if not hasattr(self, '_info'):
+            info = dcparser.parse(self.xml_file.path, picture.PictureInfo)
+            self._info = info
+        return self._info
diff --git a/apps/picture/views.py b/apps/picture/views.py
new file mode 100644 (file)
index 0000000..105f6b8
--- /dev/null
@@ -0,0 +1,35 @@
+from catalogue import forms
+from picture.models import Picture
+from django.utils.datastructures import SortedDict
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+
+
+def picture_list(request, filter=None, template_name='catalogue/picture_list.html'):
+    """ generates a listing of all books, optionally filtered with a test function """
+
+    form = forms.SearchForm()
+
+    pictures_by_author, orphans = Picture.picture_list()
+    books_nav = SortedDict()
+    for tag in pictures_by_author:
+        if pictures_by_author[tag]:
+            books_nav.setdefault(tag.sort_key[0], []).append(tag)
+
+            #    import pdb; pdb.set_trace()
+    return render_to_response(template_name, locals(),
+        context_instance=RequestContext(request))
+
+
+def picture_detail(request, picture):
+    form = forms.SearchForm()
+    picture = get_object_or_404(Picture, slug=picture)
+
+    categories = SortedDict()
+    for tag in picture.tags:
+        categories.setdefault(tag.category, []).append(tag)
+
+    picture_themes = []
+
+    return render_to_response("catalogue/picture_detail.html", locals(),
+                              context_instance=RequestContext(request))
index 4357d78..1e0d2e5 100644 (file)
@@ -12,8 +12,9 @@ from PIL import Image
 from sponsors.fields import JSONField
 from django.core.files.base import ContentFile
 
 from sponsors.fields import JSONField
 from django.core.files.base import ContentFile
 
-THUMB_WIDTH=120
-THUMB_HEIGHT=120
+THUMB_WIDTH = 120
+THUMB_HEIGHT = 120
+
 
 class Sponsor(models.Model):
     name = models.CharField(_('name'), max_length=120)
 
 class Sponsor(models.Model):
     name = models.CharField(_('name'), max_length=120)
@@ -57,7 +58,7 @@ class SponsorPage(models.Model):
         for column in self.get_sponsors_value():
             sponsor_ids.extend(column['sponsors'])
         sponsors = Sponsor.objects.in_bulk(sponsor_ids)
         for column in self.get_sponsors_value():
             sponsor_ids.extend(column['sponsors'])
         sponsors = Sponsor.objects.in_bulk(sponsor_ids)
-        sprite = Image.new('RGBA', (THUMB_WIDTH, len(sponsors)*THUMB_HEIGHT))
+        sprite = Image.new('RGBA', (THUMB_WIDTH, len(sponsors) * THUMB_HEIGHT))
         for i, sponsor_id in enumerate(sponsor_ids):
             simg = Image.open(sponsors[sponsor_id].logo.path)
             if simg.size[0] > THUMB_WIDTH or simg.size[1] > THUMB_HEIGHT:
         for i, sponsor_id in enumerate(sponsor_ids):
             simg = Image.open(sponsors[sponsor_id].logo.path)
             if simg.size[0] > THUMB_WIDTH or simg.size[1] > THUMB_HEIGHT:
index 808e7c2..262c708 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 808e7c2967440cacbc15af82cde171e10aea8a6a
+Subproject commit 262c7082c23ab266254175438d1524470996c4d2
index 5f99441..52ffd1f 100644 (file)
@@ -17,7 +17,7 @@ Feedparser>=4.1
 # PIL 
 PIL>=1.1.6
 mutagen>=1.17
 # PIL 
 PIL>=1.1.6
 mutagen>=1.17
-sorl-thumbnail>=10,<12
+sorl-thumbnail>=11.09<12
 
 # home-brewed & dependencies
 lxml>=2.2.2
 
 # home-brewed & dependencies
 lxml>=2.2.2
index 739ecee..85f1a40 100644 (file)
@@ -1195,4 +1195,22 @@ div.shown-tags p, div.all-tags p {
 /* report */
 .stats td {
     vertical-align: top;
 /* report */
 .stats td {
     vertical-align: top;
-}
\ No newline at end of file
+}
+
+/* ============ */
+/* = Pictures = */
+/* ============ */
+
+
+#picture-list .picture .title {
+    font-weight: bold;
+}
+
+#picture-list .picture {
+    background-color: white;
+    padding: 0.8em;
+    margin: 0.8em;
+    border: black 1px solid;
+    width: 600px;
+}
+
index dd01066..ec6aae8 100644 (file)
@@ -33,6 +33,7 @@
         {% endfor %}    
     </div>
     <div id="book-list">
         {% endfor %}    
     </div>
     <div id="book-list">
+      {% block book_list %}
         {% book_tree orphans books_by_parent %}
         {% for author, group in books_by_author.items %}
             {% if group %}
         {% book_tree orphans books_by_parent %}
         {% for author, group in books_by_author.items %}
             {% if group %}
@@ -43,6 +44,7 @@
                 </div>
             {% endif %}
         {% endfor %}
                 </div>
             {% endif %}
         {% endfor %}
+      {% endblock %}
     </div>
     <div id="book-list-up">
         <p><a href="#top">{% trans "↑ top ↑" %}</a></p>
     </div>
     <div id="book-list-up">
         <p><a href="#top">{% trans "↑ top ↑" %}</a></p>
diff --git a/wolnelektury/templates/catalogue/picture_detail.html b/wolnelektury/templates/catalogue/picture_detail.html
new file mode 100644 (file)
index 0000000..dbea337
--- /dev/null
@@ -0,0 +1,103 @@
+{% extends "base.html" %}
+{% load i18n %}
+{% load catalogue_tags pagination_tags %}
+{% load thumbnail %}
+
+
+{% block title %}{{ picture.title }} {% trans "on WolneLektury.pl" %}{% endblock %}
+
+{% block bodyid %}picture-detail{% endblock %}
+
+{% block body %}
+    <h1>{{picture.title}}</h1>
+    <form action="{% url search %}" method="get" accept-charset="utf-8" id="search-form">
+        <p>{{ form.q }} <input type="submit" value="{% trans "Search" %}" /> <strong>{% trans "or" %}</strong> <a href="{% url main_page %}">{% trans "return to main page" %}</a></p>
+    </form>
+
+    <div id="books-list">
+        <div id='breadcrumbs'>
+            {% if categories.author %}
+                {% for tag in categories.author %}
+                    <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>{% if not forloop.last %}, {% endif %}
+                {% endfor %}
+                &#187; 
+            {% endif %}
+        </div>
+
+       {% thumbnail picture.image_file "400x500" upscale="false" as im %}
+       <img style="margin:{{ im|margin:"400x500" }}" src="{{ im.url }}" width="{{ im.x }}" height="{{ im.y }}" />
+       {% endthumbnail %}
+
+        {% if picture.info.license %}
+        <p>{% trans "Work is licensed under " %} <a href="{{ picture.info.license }}">{{ picture.info.license_description }}</a>.</p>
+        {% endif %}
+        <p>{% trans "Based on" %}: {{ picture.info.source_name }}</p>
+        {% if picture.info.description %}
+            <div id="description">
+                <div id='description-long'>{{ picture.info.description|safe }}</div>
+                <div id='description-short'>{{ picture.info.description|safe|truncatewords_html:30 }}</div>
+            </div>
+            <div id="toggle-description"><p></p></div>
+        {% endif %}
+
+    </div>
+
+    <div id="tags-list">
+        <div id="book-info">
+            <h2>{% trans "Details" %}</h2>
+            <ul>
+                <li>
+                    {% trans "Author" %}:
+                    {% for tag in categories.author %}
+                    <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>{% if not forloop.last %}, {% endif %}
+                    {% endfor %}
+                </li>
+                <li>
+                    {% trans "Epoch" %}:
+                    {% for tag in categories.epoch %}
+                    <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>{% if not forloop.last %}, {% endif %}
+                    {% endfor %}
+                </li>
+                <li>
+                    {% trans "Kind" %}:
+                    {% for tag in categories.kind %}
+                    <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>{% if not forloop.last %}, {% endif %}
+                    {% endfor %}
+                </li>
+            </ul>
+            <h2>{% trans "Other resources" %}</h2>
+            <ul>
+                {% if picture.info.source_url %}
+                <li><a href="{{ picture.info.source_url }}">{% trans "Source of the image" %}</a></li>
+                {% endif %}
+                {% if picture.info.about and not hide_about %}
+                <li><a href="{{ picture.info.about }}">{% trans "Image on the Editor's Platform" %}</a></li>
+                {% endif %}
+{% comment %}
+                {% if book.gazeta_link %}
+                <li><a href="{{ book.gazeta_link }}">{% trans "Picture description on Lektury.Gazeta.pl" %}</a></li>
+                {% endif %}
+                {% if book.wiki_link %}
+                <li><a href="{{ book.wiki_link }}">{% trans "Book description on Wikipedia" %}</a></li>
+                {% endif %}
+{% endcomment %}
+            </ul>
+            <p><a href="{{ picture.xml_file.url }}">{% trans "View XML source" %}</a></p>
+        </div>
+        <div id="themes-list">
+            <h2>{% trans "Work's themes " %}</h2>
+            <ul>
+            {% for theme in picture_themes %}
+                <li><a href="{{ theme.get_absolute_url }}">{{ theme }} ({{ theme.count }})</a></li>
+            {% endfor %}
+            </ul>
+        </div>
+        <div class="clearboth"></div>
+    </div>
+    <div id="set-window">
+        <div class="header"><a href="#" class="jqmClose">{% trans "Close" %}</a></div>
+        <div class="target">
+            <p><img src="{{ STATIC_URL }}img/indicator.gif" alt="*"/> {% trans "Loading" %}</p>
+        </div>
+    </div>
+{% endblock %}
diff --git a/wolnelektury/templates/catalogue/picture_list.html b/wolnelektury/templates/catalogue/picture_list.html
new file mode 100644 (file)
index 0000000..c4edda8
--- /dev/null
@@ -0,0 +1,32 @@
+{% extends "catalogue/book_list.html" %}
+{% load i18n %}
+{% load catalogue_tags chunks %}
+{% load thumbnail %}
+
+{% block bodyid %}picture-list{% endblock %}
+
+{% block title %}{% trans "Listing of all pictures on WolneLektury.pl" %}{% endblock %}
+
+{% block picture_list_header %}{% trans "Listing of all pictures" %}{% endblock %}
+
+
+{% block book_list %}
+{% for author, group in pictures_by_author.items %}
+<a name="{{ author.slug }}"/>
+<div class="group">
+  <h2><a href="{{ author.get_absolute_url }}">{{ author }}</a></h2>
+  {% for picture in group %}
+  <div class="picture">
+    {% thumbnail picture.image_file "300x300" as im %}
+    <img style="float: left; margin:{{ im|margin:"300x300" }}" src="{{ im.url }}" width="{{ im.x }}" height="{{ im.y }}" />
+    {% endthumbnail %}
+    <span class="title"><a href="{{picture.get_absolute_url}}">{{picture.title}}</a></span>
+    <br class="clearboth"/>
+  </div>
+  {% endfor %}
+</div>
+  
+{% endfor %}
+
+{% endblock %}
+