Commits

Anonymous committed e5bfd98

Fixes seria

  • Participants
  • Parent commits 6110ad4

Comments (0)

Files changed (3)

File eif/fields.py

 ''' Extended class of ImageField.
     It can add previews by set sizes and sort them to directories.
     It use self.storage for all operations with files
-    It used widget with thumbnail in admin interface 
-    It also can retrun a dictonary (height, width, url) 
-        of preview's name in the template '''
+    It used widget with thumbnail in admin interface
+    It also can retrun a dictonary (height, width, url) of preview's name in the template '''
 
+import cStringIO
 import os
-import random
-import cStringIO
+
 from PIL import Image
 from django.core.files.base import ContentFile
 from django.db.models import ImageField
 from django.db.models.fields.files import ImageFieldFile
-from widgets import ExtendedImageWidget
 
+from .widgets import ExtendedImageWidget
+from .utils import gen_filename
 
-class ExtendedImageFieldFile(ImageFieldFile):      
+
+class ExtendedImageFieldFile(ImageFieldFile):
     def __init__(self, *args, **kwargs):
         super(ExtendedImageFieldFile, self).__init__(*args, **kwargs)
         for preview in self.field.previews:
-            try:
-                setattr(self, preview['name'], self.get_thumb_params(preview['name']))
-            except:
-                setattr(self, preview['name'], {'width': 0, 'height': 0, 'url': ''})
+            setattr(self, preview['name'], self.get_thumb_params(preview['name']))
 
     def save(self, name, content, save=True):
-        name = self.gen_filename(name)
+        name = gen_filename(name)
         if self.instance.pk:
+            model = self.field.model
             try:
-                model = self.field.model
                 old_image = model.objects.get(pk=self.instance.pk)
                 old_path = getattr(old_image, self.field.attname)
                 if self.storage.exists(old_path):
                     self.storage.delete(old_path)
                 self.delete_previews(old_path.name)
-            except:
+            except model.DoesNotExist:
                 pass
         super(ExtendedImageFieldFile, self).save(name, content, save)
         self.add_previews(name, content)
-    
+
     def delete(self, save=True):
         self.delete_previews(self.name)
         super(ExtendedImageFieldFile, self).delete(save)
 
     def add_previews(self, name, content):
-        path =  self.storage.path(name)
-        image_path = ('/').join([path.split('/')[:-1]][0])
-        image_format = name.split('.')[-1:][0]
-        image_name = name.replace('.%s' % image_format, '')
+        ext = os.path.splitext(name)[-1]
+        image_name = os.path.basename(name).replace(ext, '')
+        image_dir = os.path.dirname(self.storage.path(name))
+
         content.seek(0)
         image = Image.open(content).convert('RGBA')
         for preview in self.field.previews:
-            o = cStringIO.StringIO()
-            newdir = ('/').join([image_path, '%s/%ss' % (self.field.upload_to, preview['name'])])
+            out = cStringIO.StringIO()
+            newdir = os.path.join(image_dir, self.field.upload_to, preview['name'])
             if self.field.dir_sort and not os.path.isdir(newdir):
                 try:
                     os.makedirs(newdir)
-                except:
+                except OSError:
                     self.field.dir_sort = False
-            if self.field.dir_sort:
-                preview_name = ('/').join([self.field.upload_to, '%ss' % preview['name'], name]) 
-            else:
-                preview_name = ('/').join([self.field.upload_to, '%s_%s.%s' % (image_name, preview['name'], image_format)]) 
-            try:
-                width = preview['width']
-            except:
-                width = float(image.size[0]) * (preview['height'] / float(image.size[1]))
-            try:
-                height = preview['height']
-            except:
-                height = float(image.size[1]) * (preview['width'] / float(image.size[0]))
+
+            preview_path = self.get_preview_path(preview['name'], image_name, ext)
+            width = preview['width'] if 'width' in preview else \
+                float(image.size[0]) * (preview['height'] / float(image.size[1]))
+            height = preview['height'] if 'height' in preview else \
+                float(image.size[1]) * (preview['width'] / float(image.size[0]))
+
             preview_file = image.resize((int(round(width)), int(round(height))), Image.ANTIALIAS)
-            preview_file.save(o, image_format.lower())
-            self.storage.save(preview_name, ContentFile(o.getvalue()))
-    
+            preview_file.save(out, ext)
+            self.storage.save(preview_path, ContentFile(out.getvalue()))
+
     def delete_previews(self, name):
-        image_format = '.' + name.split('.')[-1:][0] 
-        image_name = name.split('/')[-1:][0].replace(image_format, '')
+        ext = os.path.splitext(name)[-1]
+        image_name = os.path.basename(name).replace(ext, '')
+
         for preview in self.field.previews:
-            if self.field.dir_sort:
-                preview_name = ('/').join([self.field.upload_to, '%ss' % preview['name'], '%s%s' % (image_name, image_format)]) 
-            else:
-                preview_name = ('/').join([self.field.upload_to, '%s_%s%s' % (image_name, preview['name'], image_format)]) 
-            if self.storage.exists(preview_name):
-                self.storage.delete(preview_name)
+            preview_path = self.get_preview_path(preview['name'], image_name, ext)
+            if self.storage.exists(preview_path):
+                self.storage.delete(preview_path)
 
-    def gen_filename(self, name):
-        filename = u''
-        alphabet = u'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm_0123456789' * 10
-        image_format = name.split('.')[-1:][0].upper()
-        if image_format == 'JPG':
-            image_format = 'JPEG'
-        for a in xrange(10):
-            filename += random.choice(alphabet)
-        filename += '.' + image_format
-        return filename          
-        
-    def get_thumb_params(self, name):
-        preview_format = '.' + self.name.split('.')[-1:][0]
-        preview_name = self.name.split('/')[-1:][0].replace(preview_format, '')
+    def get_preview_path(self, thumb_name, file_name, ext):
         if self.field.dir_sort:
-            preview_path = ('/').join([self.field.upload_to, '%ss'  % name, '%s%s' % (preview_name, preview_format)])
+            preview_path = os.path.join(
+                self.field.upload_to, thumb_name, '%s%s' % (file_name, ext))
         else:
-            preview_path = ('/').join([self.field.upload_to, '%s_%s%s' % (preview_name, name, preview_format)])
+            preview_path = os.path.join(
+                self.field.upload_to, '%s_%s%s' % (file_name, thumb_name, ext))
+        return preview_path
+
+    def get_thumb_params(self, thumb_name):
+        ext = os.path.splitext(self.name)[-1]
+        preview_name = os.path.basename(self.name).replace(ext, '')
+
+        if self.field.dir_sort:
+            preview_path = os.path.join(
+                self.field.upload_to, thumb_name, '%s%s' % (preview_name, ext))
+        else:
+            preview_path = os.path.join(
+                self.field.upload_to, '%s_%s%s' % (preview_name, thumb_name, ext))
+
         if self.storage.exists(preview_path):
             preview = Image.open(self.storage.path(preview_path))
-            preview_dict = {'width': preview.size[0], 'height': preview.size[1], 'url': self.storage.url(preview_path)}
+            preview_dict = {
+                'width': preview.size[0],
+                'height': preview.size[1],
+                'url': self.storage.url(preview_path)}
             return preview_dict
-        else:
-            return {'width': 0, 'height':0, 'url':''}
+        return {}
 
 
 class ExtendedImageField(ImageField):
-    ''' Set attribute preview to tuple of dictonaries contains:
-        name - required. Name of preview.
-        width - preview's width. If not set it will calculate from
-                height on the basis of proportions
-        height - preview's height. If not set it will calculate from
-                width on the basis of proportions
-        Set attribute dir_sort to True is you want to sort your
-        previews to folders 
-        Set attribute widget to ExtendedImageField and set attr to 
-        dictonary contains name - name of preview you want to show
-        If you lose dir_sort it will set up to True by default
-        If you lose widget it will set up to ExtendedImageField with
-        base image as shown by default '''
+    '''
+    Set attribute preview to tuple of dictonaries contains:
+    name - required. Name of preview.
+    width - preview's width. If not set it will calculate from
+            height on the basis of proportions
+    height - preview's height. If not set it will calculate from
+            width on the basis of proportions
+    Set attribute dir_sort to True is you want to sort your previews to folders
+    Set attribute widget_preview to name of preview you want to show
+    If not - uploaded image will be shown in admin widget
+    Also you can pass yours own widget as widget arg
+
+    If you lose dir_sort it will set up to True by default
+    If you lose widget it will set up to ExtendedImageField with base image as shown by default
+    '''
     attr_class = ExtendedImageFieldFile
-    
-    def __init__(self, previews=None, dir_sort=None, widget=None, **kwargs):
+
+    def __init__(self, previews=None, dir_sort=None, widget=None, widget_preview=None, **kwargs):
         self.previews = previews
         self.dir_sort = dir_sort
         self.widget = widget
         if self.dir_sort is None:
             self.dir_sort = True
         if self.widget is None:
-            self.widget = ExtendedImageWidget(attrs={'preview': 'self'})
+            preview = widget_preview or 'self'
+            self.widget = ExtendedImageWidget(attrs={'preview': preview})
         super(ExtendedImageField, self).__init__(**kwargs)
-    
+
     def formfield(self, **kwargs):
         kwargs['widget'] = self.widget
         return super(ExtendedImageField, self).formfield(**kwargs)
-

File eif/utils.py

+import os
+import string
+import random
+
+
+def gen_filename(name, storage=os.path):
+    alphabet = '%s_%s' % (string.ascii_letters, string.digits)
+    filename = u''
+    ext = os.path.splitext(name)[-1].upper()
+
+    for _ in xrange(10):
+        filename += random.choice(alphabet)
+    filename += ext
+
+    if storage.exists(filename):
+        filename = gen_filename(name, storage)
+    return filename

File eif/widgets.py

 from django.forms.widgets import FileInput
 from django.utils.safestring import mark_safe
 
+
 class ExtendedImageWidget(FileInput):
     def __init__(self, attrs=None):
         super(ExtendedImageWidget, self).__init__(attrs)