def adjust(uploaded_file: 'SimpleUploadedFile', **options): buffer = BytesIO() img = Image.open(uploaded_file) processor = Adjust(**options) new_img = processor.process(img) new_img.save(buffer, format='png') return SimpleUploadedFile(name=utils.replace_extension( uploaded_file.name, 'png'), content=buffer.getvalue(), content_type=uploaded_file.content_type)
class Mascara(EditorialModel): NORMAL = 0 SAZONAL = 1 CATEGORIAS = ( (NORMAL, u'Normal'), (SAZONAL, u'Sazonal') ) def new_filename(instance, filename): fname, dot, extension = filename.rpartition('.') fname = slugify(fname) return os.path.join('mascaras', '%s.%s' % (fname, extension)) imagem = models.ImageField(u'Imagem', upload_to=new_filename, null=True, blank=True) img_250x250 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(250, 250)], source='imagem', format='PNG', options={'quality': 90}) img_376x376 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(376, 376)], source='imagem', format='PNG', options={'quality': 90}) thumb = models.ImageField(u'Thumbnail', upload_to=new_filename, null=True, blank=True) thumb_98x98 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(98, 98)], source='thumb', format='PNG', options={'quality': 90}) tipo = models.IntegerField(u'Tipo de categoria', choices=CATEGORIAS, null=True, blank=False, default=NORMAL) categoria = models.ForeignKey(Categoria, null=True, blank=True, verbose_name=u'Categoria', related_name='mascaras') class Meta: verbose_name = u'Imagem para compartilhar' verbose_name_plural = u'Imagens para compartilhar' def __unicode__(self): return u'%s' % self.imagem @classmethod def normais_serializadas(cls): return [i.to_dict() for i in cls.objects.filter(tipo=cls.NORMAL, publicada=True)] def to_dict(self): return {'id': self.id, 'imagem': self.img_376x376.url, 'thumb': self.thumb_98x98.url}
def generate_image(source, outname, settings, options=None): """Image processor, rotate and resize the image. :param source: path to an image :param outname: output filename :param settings: settings dict :param options: dict with PIL options (quality, optimize, progressive) """ logger = logging.getLogger(__name__) img = PILImage.open(source) original_format = img.format if settings['copy_exif_data'] and settings['autorotate_images']: logger.warning("The 'autorotate_images' and 'copy_exif_data' settings " "are not compatible because Sigal can't save the " "modified Orientation tag.") # Preserve EXIF data if settings['copy_exif_data'] and _has_exif_tags(img): if options is not None: options = deepcopy(options) else: options = {} options['exif'] = img.info['exif'] # Rotate the img, and catch IOError when PIL fails to read EXIF if settings['autorotate_images']: try: img = Transpose().process(img) except (IOError, IndexError): pass # Resize the image if settings['img_processor']: try: logger.debug('Processor: %s', settings['img_processor']) processor_cls = getattr(pilkit.processors, settings['img_processor']) except AttributeError: logger.error('Wrong processor name: %s', settings['img_processor']) sys.exit() processor = processor_cls(*settings['img_size'], upscale=False) img = processor.process(img) # Adjust the image after resizing img = Adjust(**settings['adjust_options']).process(img) if settings['copyright']: add_copyright(img, settings['copyright']) outformat = img.format or original_format or 'JPEG' logger.debug(u'Save resized image to {0} ({1})'.format(outname, outformat)) save_image(img, outname, outformat, options=options, autoconvert=True)
class Categoria(EditorialModel): shopping = models.ForeignKey(Shopping, verbose_name=u'Shopping', related_name='categorias', null=True, blank=True) nome = models.CharField(u'Nome', max_length=100, blank=False, null=True) slug = models.SlugField(max_length=150, blank=False, null=False, unique=False) sazonal = models.BooleanField(u'Categoria sazonal?', default=False) imagem = models.ImageField(u'Imagem', upload_to='categorias', null=True, blank=True) img_162x27 = ImageSpecField( [Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(162, 27)], source='imagem', format='PNG', options={'quality': 90}) class Meta: verbose_name = u'Categoria' verbose_name_plural = u'Categorias' ordering = ['nome'] unique_together = ('shopping', 'slug') def __unicode__(self): shopping = ' (%s)' % self.shopping.nome if self.shopping else '' return u'%s%s' % (self.nome, shopping) def to_dict(self): contexto = {'id': self.id, 'nome': self.nome, 'slug': self.slug} if self.sazonal: contexto.update( {'imagem': self.img_162x27.url if self.imagem else None}) return contexto @classmethod def publicadas_com_oferta(cls, shopping=1): categorias = cls.objects.filter(shopping_id=shopping, sazonal=False, publicada=True).select_related() categorias = categorias.filter(ofertas__status=1, ofertas__fim__gte=date.today()) \ .order_by('nome') \ .distinct() # categorias = cls.objects.filter(ofertas__fim__gt=date.today(), ofertas__status=1, shopping_id=shopping, sazonal=False, publicada=True) \ # .order_by('nome') \ # .distinct() return categorias '''return separa_tres_colunas([c.to_dict() for c in categorias])'''
class ImagemOferta(OrderedModel): def new_filename(instance, filename): fname, dot, extension = filename.rpartition('.') fname = '%s_%s' % (slugify(unicode(fname)), datetime.now().strftime("%Y%m%d%H%M%S")) return os.path.join('ofertas', '%s.%s' % (fname, extension)) oferta = models.ForeignKey(Oferta, verbose_name=u'Oferta', related_name='imagens') imagem = models.ImageField(u'Imagem', upload_to=new_filename, null=True, blank=True) img_600x600 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(600, 600)], source='imagem', format='PNG', options={'quality': 90}) img_376x376 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(376, 376)], source='imagem', format='PNG', options={'quality': 90}) img_250x250 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(250, 250)], source='imagem', format='PNG', options={'quality': 90}) img_172x172 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(172, 172)], source='imagem', format='PNG', options={'quality': 90}) img_120x120 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(120, 120)], source='imagem', format='PNG', options={'quality': 90}) img_94x94 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(94, 94)], source='imagem', format='PNG', options={'quality': 90}) evento_180x445 = ImageSpecField([Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(180, 445)], source='imagem', format='PNG', options={'quality': 90}) principal = models.BooleanField(u'Imagem principal', default=False) vertical = models.BooleanField(u'Imagem vertical', default=False) class Meta: verbose_name = u'Imagem' verbose_name_plural = u'Imagens das ofertas' ordering = ['oferta', 'ordem'] def __unicode__(self): return u'%s - %s' % (self.oferta.nome, self.ordem)
class Loja(EditorialModel): def new_filename(instance, filename): fname, dot, extension = filename.rpartition('.') fname = slugify(fname) return os.path.join('lojas', '%s.%s' % (fname, extension)) shopping = models.ForeignKey(Shopping, verbose_name=u'Shopping', related_name='lojas') id_multilan = models.IntegerField('Id na Multiplan', null=True, blank=False) nome = models.CharField(u'Nome', max_length=100, null=True, blank=False) slug = models.CharField(u'Slug', max_length=150, null=True, blank=True) logo = models.ImageField(u'Imagem', upload_to=new_filename, null=True, blank=True) logo_120x50 = ImageSpecField( [Adjust(contrast=1.1, sharpness=1.1), resize.ResizeToFill(120, 50)], source='logo', format='PNG', options={'quality': 90}) telefone = models.CharField(u'telefone', max_length=100, null=True, blank=True) class Meta: verbose_name = u'Loja' verbose_name_plural = u'Lojas' ordering = ['nome'] def __unicode__(self): return u'%s - %s' % (self.nome, self.shopping) def to_dict(self): return { 'id': self.id, 'nome': self.nome, 'slug': self.slug, 'logo': self.logo_120x50.url if self.logo else None, 'telefone': self.telefone, 'shopping': self.shopping.to_dict() } @classmethod def publicadas_com_oferta(cls, shopping): lojas = cls.objects.filter(ofertas__status=1, ofertas__inicio__lte=date.today(), ofertas__fim__gt=datetime.now(), ofertas__loja__shopping_id=shopping)\ .order_by('nome')\ .distinct() return lojas '''return separa_tres_colunas([l.to_dict() for l in lojas])''' @classmethod def publicadas_sem_oferta(cls, shopping): lojas = cls.objects.filter(publicada=True, shopping_id=shopping).order_by('nome') return [l.to_dict() for l in lojas if not l.ofertas.filter(status=1)] @classmethod def relatorio_visitas(cls, shopping_id, date=None): if not date: return Loja.objects.annotate(vistas=Count( 'pk', only=Q(ofertas__logs__acao=1, shopping=shopping_id))).order_by('-vistas') else: return Loja.objects.annotate(vistas=Count('pk', only=Q(ofertas__logs__acao=1, shopping=shopping_id, ofertas__logs__data_criacao__gte=date)))\ .order_by('-vistas') @classmethod def relatorio_solicitacoes(cls, shopping_id, date=None): if not date: return Loja.objects.annotate( pedidos=Count('solicitacoes', only=Q( shopping=shopping_id))).order_by('-pedidos') else: return Loja.objects.annotate( pedidos=Count('solicitacoes', only=Q(shopping=shopping_id, solicitacoes__data_criacao__gte=date) )).order_by('-pedidos')
def adjust(img, settings=None): logger.debug('Adjust image %r', img) return Adjust(**settings['adjust_options']).process(img)
class Competition(models.Model): competition_text = models.CharField(max_length=100) competition_name = models.CharField(max_length=600) competition_game = models.CharField(max_length=50) origin_image = models.ImageField(upload_to="competition/images", blank=True) formatted_image = ImageSpecField( [Adjust(contrast=1.2, sharpness=1.1), ResizeToFill(1200, 600)], source='origin_image', format='JPEG', options={'quality': 100}) pub_date = models.DateTimeField('date published', auto_now_add=True) edit_date = models.DateTimeField('date edited', auto_now=True) date_start = models.DateTimeField('date_start') date_end = models.DateTimeField('date_end') attend_start = models.DateTimeField('attend_start') attend_end = models.DateTimeField('attend_end') state = models.CharField(max_length=50, choices=STATE, default='none') page_num = models.IntegerField(default=0) master = models.ForeignKey(User, null=True, on_delete=models.CASCADE, verbose_name='대회관리자') # 작성자 is_public = models.BooleanField(default=True, verbose_name='공개 대회') tournament_type = models.IntegerField( default=-1, verbose_name='대회 방식') # -1=싱글, -2=더블 / 양수 1이상=라운드로빈(모든팀이 서로 값만큼 경기) required_tier = models.CharField(max_length=200, verbose_name='참가 최소 티어') total_teams = models.IntegerField( default=8, verbose_name='전체 모집 팀', validators=[MinValueValidator(2), MaxValueValidator(128)]) # 대회 참가팀수, 마감시 모집종료 current_teams = models.IntegerField( default=0, verbose_name='현재 모집 팀') # 대회 참가팀수, 마감시 모집종료 rounds = models.IntegerField( default=7, verbose_name='승자조 라운드수', null=True, validators=[MinValueValidator(1), MaxValueValidator(8)]) # 전체 라운드수는 single elimination 에서 2인대회 일때 1로 최소 ,128인대회일때 7로 최대) # dobule이면 패자전이 각각 진행되므로 1라운드 추가 rounds_loser = models.IntegerField( default=7, verbose_name='패자조 라운드수', null=True, validators=[MinValueValidator(1), MaxValueValidator(9)]) def __str__(self): return '{}'.format(self.competition_name) @staticmethod def total_competition(): return Competition.objects.count() def get_image_url(self): return '%s%s' % (settings.MEDIA_URL, self.formatted_image) def delete(self, *args, **kwargs): self.origin_image.delete() self.formatted_image.delete() super(Competition, self).delete(*args, **kwargs) def can_attend(self): return self.attend_start.strftime('%Y-%m-%d') <= NOW.strftime('%Y-%m-%d') \ and self.attend_end.strftime('%Y-%m-%d') >= NOW.strftime('%Y-%m-%d')