fix
[wolnelektury.git] / src / picture / models.py
index 643149a..416c846 100644 (file)
@@ -1,22 +1,21 @@
-# -*- coding: utf-8 -*-
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.db import models, transaction
 import catalogue.models
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.db import models, transaction
 import catalogue.models
-from django.db.models import permalink
 from sorl.thumbnail import ImageField
 from django.conf import settings
 from django.contrib.contenttypes.fields import GenericRelation
 from django.core.files.storage import FileSystemStorage
 from sorl.thumbnail import ImageField
 from django.conf import settings
 from django.contrib.contenttypes.fields import GenericRelation
 from django.core.files.storage import FileSystemStorage
-from django.utils.datastructures import SortedDict
+from django.urls import reverse
 from slugify import slugify
 from ssify import flush_ssi_includes
 
 from catalogue.models.tag import prefetched_relations
 from catalogue.utils import split_tags
 from picture import tasks
 from slugify import slugify
 from ssify import flush_ssi_includes
 
 from catalogue.models.tag import prefetched_relations
 from catalogue.utils import split_tags
 from picture import tasks
-from StringIO import StringIO
+from wolnelektury.utils import cached_render, clear_cached_renders
+from io import BytesIO
 import jsonfield
 import itertools
 import logging
 import jsonfield
 import itertools
 import logging
@@ -35,7 +34,7 @@ picture_storage = FileSystemStorage(location=path.join(
 
 
 class PictureArea(models.Model):
 
 
 class PictureArea(models.Model):
-    picture = models.ForeignKey('picture.Picture', related_name='areas')
+    picture = models.ForeignKey('picture.Picture', models.CASCADE, related_name='areas')
     area = jsonfield.JSONField(_('area'), default={}, editable=False)
     kind = models.CharField(
         _('kind'), max_length=10, blank=False, null=False, db_index=True,
     area = jsonfield.JSONField(_('area'), default={}, editable=False)
     kind = models.CharField(
         _('kind'), max_length=10, blank=False, null=False, db_index=True,
@@ -124,7 +123,7 @@ class Picture(models.Model):
 
         return ret
 
 
         return ret
 
-    def __unicode__(self):
+    def __str__(self):
         return self.title
 
     def authors(self):
         return self.title
 
     def authors(self):
@@ -143,9 +142,8 @@ class Picture(models.Model):
     def tags_by_category(self):
         return split_tags(self.tags)
 
     def tags_by_category(self):
         return split_tags(self.tags)
 
-    @permalink
     def get_absolute_url(self):
     def get_absolute_url(self):
-        return 'picture.views.picture_detail', [self.slug]
+        return reverse('picture_detail', args=[self.slug])
 
     def get_initial(self):
         try:
 
     def get_initial(self):
         try:
@@ -180,7 +178,7 @@ class Picture(models.Model):
         close_image_file = False
 
         if image_file is not None and not isinstance(image_file, File):
         close_image_file = False
 
         if image_file is not None and not isinstance(image_file, File):
-            image_file = File(open(image_file))
+            image_file = File(open(image_file, 'rb'))
             close_image_file = True
 
         if not isinstance(xml_file, File):
             close_image_file = True
 
         if not isinstance(xml_file, File):
@@ -198,7 +196,7 @@ class Picture(models.Model):
                 raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug)
 
             picture.areas.all().delete()
                 raise Picture.AlreadyExists('Picture %s already exists' % picture_xml.slug)
 
             picture.areas.all().delete()
-            picture.title = unicode(picture_xml.picture_info.title)
+            picture.title = str(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))
             picture.extra_info = picture_xml.picture_info.to_dict()
 
             picture_tags = set(catalogue.models.Tag.tags_from_info(picture_xml.picture_info))
@@ -283,7 +281,7 @@ class Picture(models.Model):
 
             picture.width, picture.height = modified.size
 
 
             picture.width, picture.height = modified.size
 
-            modified_file = StringIO()
+            modified_file = BytesIO()
             modified.save(modified_file, format='JPEG', quality=95)
             # FIXME: hardcoded extension - detect from DC format or orginal filename
             picture.image_file.save(path.basename(picture_xml.image_path), File(modified_file))
             modified.save(modified_file, format='JPEG', quality=95)
             # FIXME: hardcoded extension - detect from DC format or orginal filename
             picture.image_file.save(path.basename(picture_xml.image_path), File(modified_file))
@@ -326,33 +324,6 @@ class Picture(models.Model):
         annotated.paste(annotation.resize((img.size[0], 40), Image.ANTIALIAS), (0, img.size[1]))
         return annotated
 
         annotated.paste(annotation.resize((img.size[0], 40), Image.ANTIALIAS), (0, img.size[1]))
         return annotated
 
-    # WTF/unused
-    @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.iterator():
-            authors = list(pic.authors().only('pk'))
-            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'):
     @property
     def info(self):
         if not hasattr(self, '_info'):
@@ -372,11 +343,18 @@ class Picture(models.Model):
             names = [tag[0] for tag in names]
         return ', '.join(names)
 
             names = [tag[0] for tag in names]
         return ', '.join(names)
 
+    @cached_render('picture/picture_mini_box.html')
+    def mini_box(self):
+        return {
+            'picture': self,
+        }
+
     def related_themes(self):
         return catalogue.models.Tag.objects.usage_for_queryset(
             self.areas.all(), counts=True).filter(category__in=('theme', 'thing'))
 
     def flush_includes(self, languages=True):
     def related_themes(self):
         return catalogue.models.Tag.objects.usage_for_queryset(
             self.areas.all(), counts=True).filter(category__in=('theme', 'thing'))
 
     def flush_includes(self, languages=True):
+        clear_cached_renders(self.mini_box)
         if not languages:
             return
         if languages is True:
         if not languages:
             return
         if languages is True:
@@ -400,6 +378,6 @@ class Picture(models.Model):
                 index.index_tags()
             if commit:
                 index.index.commit()
                 index.index_tags()
             if commit:
                 index.index.commit()
-        except Exception, e:
+        except Exception as e:
             index.index.rollback()
             raise e
             index.index.rollback()
             raise e