X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/f906193db2ec44590f57beae2e8ee2df76117b7b..e9cd7fc641895a7702a8f81fcd11c388dd7d9db7:/apps/picture/models.py diff --git a/apps/picture/models.py b/apps/picture/models.py index af691f8ae..1dfd59618 100644 --- a/apps/picture/models.py +++ b/apps/picture/models.py @@ -1,8 +1,17 @@ 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.utils.datastructures import SortedDict +from django.template.loader import render_to_string +from django.core.cache import cache +from catalogue.utils import split_tags +from django.utils.safestring import mark_safe +from librarian import dcparser, picture +from slughifi import slughifi + from django.utils.translation import ugettext_lazy as _ from newtagging import managers from os import path @@ -22,7 +31,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) - 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) @@ -36,6 +45,9 @@ class Picture(models.Model): 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 @@ -43,16 +55,27 @@ class Picture(models.Model): ret = super(Picture, self).save(force_insert, force_update) + if reset_short_html: + self.reset_short_html() + return ret 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): + def from_xml_file(cls, xml_file, image_file=None, overwrite=False): """ Import xml and it's accompanying image file. """ + from sortify import sortify from django.core.files import File from librarian.picture import WLPicture close_xml_file = False @@ -64,23 +87,97 @@ class Picture(models.Model): # use librarian to parse meta-data picture_xml = WLPicture.from_file(xml_file) - picture, created = Picture.objects.get_or_create(slug=picture_xml.slug) + pict, created = Picture.objects.get_or_create(slug=picture_xml.slug) if not created and not overwrite: raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug) - picture.title = picture_xml.picture_info.title + pict.title = picture_xml.picture_info.title - picture.tags = catalogue.models.Tag.tags_from_info(picture_xml.picture_info) + # from nose.tools import set_trace; set_trace() + motif_tags = set() + for part in picture_xml.partiter(): + for motif in part['themes']: + tag, created = catalogue.models.Tag.objects.get_or_create(slug=slughifi(motif), category='theme') + if created: + tag.name = motif + tag.sort_key = sortify(tag.name) + tag.save() + motif_tags.add(tag) - img = picture_xml.image_file() - try: - picture.image_file.save(path.basename(picture_xml.image_path), File(img)) - finally: - img.close() + pict.tags = catalogue.models.Tag.tags_from_info(picture_xml.picture_info) + \ + list(motif_tags) - picture.xml_file.save("%s.xml" % picture.slug, File(xml_file)) - picture.save() + if image_file is not None: + img = image_file + else: + img = picture_xml.image_file() + + pict.image_file.save(path.basename(picture_xml.image_path), File(img)) + + pict.xml_file.save("%s.xml" % pict.slug, File(xml_file)) + pict.save() finally: if close_xml_file: xml_file.close() - return picture + return pict + + @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 + + def reset_short_html(self): + if self.id is None: + return + + cache_key = "Picture.short_html/%d" % (self.id) + cache.delete(cache_key) + + def short_html(self): + if self.id: + cache_key = "Picture.short_html/%d" % (self.id) + short_html = cache.get(cache_key) + else: + short_html = None + + if short_html is not None: + return mark_safe(short_html) + else: + tags = self.tags.filter(category__in=('author', 'kind', 'epoch')) + tags = split_tags(tags) + + short_html = unicode(render_to_string('picture/picture_short.html', + {'picture': self, 'tags': tags})) + + if self.id: + cache.set(cache_key, short_html, catalogue.models.CACHE_FOREVER) + return mark_safe(short_html)