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
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 + 'tmp/'
|
|
|
|
|
|
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()
|
|
|