You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

189 lines
6.9 KiB

# encoding=utf-8
import os
from PIL import Image
from uuid import uuid4
from django.db import models
from lms import settings
from lms.settings import DOMAIN
from lms.tools import random_string
import django.utils.timezone
from django.core.files.base import File
from django.utils.deconstruct import deconstructible
@deconstructible
class PathAndRename(object):
def __init__(self, sub_path):
self.path = sub_path
def __call__(self, instance, filename):
ext = filename.split('.')[-1]
# set filename as random string
filename = '{}.{}'.format(uuid4().hex, ext)
# return the whole path to the file
return os.path.join(self.path, filename)
path_and_rename = PathAndRename("personal_files")
class FormatIndex(models.Model):
FILETYPES = (
('F', 'FILE'),
('I', 'IMAGE')
)
f_type = models.CharField(verbose_name=u'Тип файла', choices=FILETYPES, max_length=1, default='F')
name = models.CharField(verbose_name=u'Формат', max_length=255)
description = models.CharField(verbose_name=u'Имя', max_length=255, default='')
icon = models.ImageField(verbose_name=u'Иконка', upload_to='formatindex', blank=True)
icon_class = models.CharField(verbose_name=u'Иконка', max_length=255, blank=True)
def __unicode__(self):
return u'%s' % self.name
def __str__(self):
return '%s' % self.name
class Meta:
verbose_name = u'Формат'
verbose_name_plural = u'Индекс форматов'
class Storage(models.Model):
loaded = models.BooleanField(verbose_name=u'Загруженно', default=False)
name = models.CharField(verbose_name=u'Имя файла', max_length=255, blank=True, default='')
key = models.CharField(verbose_name=u'Ключь файла', max_length=255, null=True, unique=True, blank=True)
original = models.FileField(verbose_name=u'Файл', upload_to=path_and_rename)
f_format = models.ForeignKey(FormatIndex, verbose_name=u'Формат файла', blank=True, null=True)
description = models.TextField(verbose_name=u'Дополнение к файлам', default='', blank=True)
date = models.DateTimeField(verbose_name=u'Дата загрузки', default=django.utils.timezone.now)
error = models.BooleanField(verbose_name=u'Ошибка', default=False)
def __unicode__(self):
return u'%s' % self.name
def __str__(self):
return '%s' % self.name
def save(self, *args, **kwargs):
if self.original:
if not self.f_format:
try:
self.f_format = FormatIndex.objects.get(name=str(self.original.name.split('.')[1]).upper())
except FormatIndex.DoesNotExist:
self.f_format = FormatIndex.objects.get(name='*')
if not self.name:
self.name = str(self.original.name.split('.')[0].encode('utf-8'))
if not self.key:
self.key = random_string().upper()
super(Storage, self).save(*args, **kwargs)
def get_name_for_user(self):
return self.name if self.name else self.f_format.description
def get_file_name(self):
return self.original.name.split('/')[1]
def get_url(self, type_in):
if self.f_format.f_type == 'F':
return self.original.url
elif self.f_format.f_type == 'I':
try:
file_ = CroppedImage.objects.get(original=self)
except CroppedImage.DoesNotExist:
file_ = CroppedImage.objects.create(original=self)
if type_in:
if type_in == 'big' or type_in == 'middle' or type_in == 'small':
if not file_.big or not file_.middle or not file_.small:
fix_crop(file_)
return file_.get_cart(type_in)
else:
return '{0}{1}'.format(DOMAIN, self.original.url)
return '{0}{1}'.format(DOMAIN, self.original.url)
class Meta:
verbose_name = u'Файл'
verbose_name_plural = u'Файлы'
class CroppedImage(models.Model):
original = models.ForeignKey('Storage', verbose_name=u'Оригинал')
big = models.ImageField(verbose_name=u'Большое изображение', upload_to='personal_files', blank=True, null=True)
middle = models.ImageField(verbose_name=u'Среднее изображение', upload_to='personal_files', blank=True, null=True)
small = models.ImageField(verbose_name=u'Маленькое изображение', upload_to='personal_files', blank=True, null=True)
cropped = models.BooleanField(verbose_name=u'Обрезан', default=False)
def __unicode__(self):
return u'%s' % self.original.key
def __str__(self):
return '%s' % self.original.key
def get_cart(self, type_in):
if type_in == 'big':
return self.big.url
elif type_in == 'middle':
return self.middle.url
elif type_in == 'small':
return self.small.url
class Meta:
verbose_name = u'Картинка'
verbose_name_plural = u'Картинки'
IMAGE_TMP = settings.MEDIA_ROOT + '/personal_files/'
def save_resize_image(filename, pil_img, save_field, file_format):
temp_image = open(os.path.join(IMAGE_TMP, filename), 'wb')
if file_format.upper() == 'GIF':
save_gif(pil_img, temp_image)
else:
pil_img.save(temp_image, file_format)
thumb_data = open(os.path.join(IMAGE_TMP, filename), 'rb')
thumb_file = File(thumb_data)
save_field.save(filename + '.' + file_format, thumb_file)
def save_gif(pil_img, path):
if 'transparency' in pil_img.info:
transparency = pil_img.info['transparency']
pil_img.save(path, 'GIF', transparency=transparency)
else:
pil_img.save(path, 'GIF')
def fix_crop(crop):
if not crop.cropped or not crop.big or not crop.middle or not crop.small:
clip_ip = crop.original.key
small = (50, 50)
middle = (100, 100)
big = (256, 256)
file_format = str(crop.original.original.name.split('.')[1])
file_format = 'jpeg' if file_format == 'jpg' else file_format
im = Image.open(crop.original.original.path)
if not crop.big:
big_img = im.copy()
big_img.thumbnail(big, Image.ANTIALIAS)
save_resize_image(clip_ip+'_big', big_img, crop.big, file_format)
if not crop.middle:
middle_img = im.copy()
middle_img.thumbnail(middle, Image.ANTIALIAS)
save_resize_image(clip_ip+'_middle', middle_img, crop.middle, file_format)
if not crop.small:
small_img = im.copy()
small_img.thumbnail(small, Image.ANTIALIAS)
save_resize_image(clip_ip+'_small', small_img, crop.small, file_format)
if crop.big and crop.middle and crop.small:
crop.cropped = True
crop.save()