Exemple #1
0
class ProductImage(models.Model):
    product = models.ForeignKey(Product,
                                on_delete=models.DO_NOTHING,
                                db_index=True)
    created_at = models.DateTimeField('date created', auto_now_add=True)
    link = models.ImageField(upload_to=upload_to)
    full = ImageSpecField(source='link',
                          processors=[],
                          format='PNG',
                          options={'quality': 60})
    thumbnail = ImageSpecField(
        source='link',
        processors=[ResizeToCover(width=370, height=370)],
        format='PNG',
        options={'quality': 60})

    x600 = ImageSpecField(source='link',
                          processors=[ResizeToCover(width=600, height=600)],
                          format='PNG',
                          options={'quality': 60})

    paging = ImageSpecField(source='link',
                            processors=[ResizeToFit(147, 143)],
                            format='PNG',
                            options={'quality': 60})
    is_delete = models.BooleanField(default=False, blank=True)

    def __str__(self):
        return "{} - {}".format(self.product.pk, self.product.title)

    class Meta:
        verbose_name = 'Изображение товара'
        verbose_name_plural = 'Изображения товаров'
class Musician(models.Model):
    user = models.OneToOneField(User,
                                on_delete=models.CASCADE,
                                primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True)
    bio = models.TextField()
    city = models.CharField(max_length=255)
    latitude = models.FloatField(blank=True, null=True)
    longitude = models.FloatField(blank=True, null=True)

    # fields having to do with money
    cashapp_name = models.CharField(max_length=255, blank=True, null=True)
    paypal_donation_url = models.CharField(max_length=255,
                                           blank=True,
                                           null=True)
    cashapp_qr = models.ImageField(upload_to="images/", null=True, blank=True)
    paypal_qr = models.ImageField(upload_to="images/", null=True, blank=True)
    venmo_qr = models.ImageField(upload_to="images/", null=True, blank=True)
    favorited_by = models.ManyToManyField(User,
                                          related_name="favorite_musician",
                                          blank=True)

    # fields having to do with images
    headshot = models.ImageField(upload_to="images/", null=True, blank=False)
    thumbnail = ImageSpecField(
        source="headshot",
        processors=[Transpose(),
                    ResizeToCover(200, 200),
                    SmartCrop(200, 200)],
        format="JPEG",
        options={"quality": 100},
    )
    full_cover = ImageSpecField(
        source="headshot",
        processors=[Transpose(),
                    ResizeToFit(600, 600),
                    SmartCrop(400, 400)],
        format="JPEG",
        options={"quality": 100},
    )
    very_small_thumb = ImageSpecField(
        source="headshot",
        processors=[Transpose(),
                    ResizeToCover(100, 100),
                    SmartCrop(100, 100)],
        format="JPEG",
        options={"quality": 100},
    )

    def __str__(self):
        return f'{self.name}'
Exemple #3
0
class ProductImage(models.Model):
    product = models.ForeignKey(Product,
                                related_name='images',
                                verbose_name=_('ProductImage|name'))
    image = ProcessedImageField(upload_to='images',
                                processors=[
                                    ResizeToFit(800, 600),
                                    ImageWatermark(
                                        'media/default_images/watermark.png', )
                                ],
                                format='PNG',
                                default='media/default.png',
                                verbose_name=_('ProductImage|image'))
    image_preview = ImageSpecField(
        source='image',
        processors=[ResizeToCover(300, 400)],
        format='PNG',
    )

    class Meta:
        verbose_name = _('ProductImage')
        verbose_name_plural = _('ProductImage|plural')

    def __str__(self):
        return self.product.name
Exemple #4
0
class ImageMixin(models.Model):
    class Meta:
        abstract = True

    upload_image_to = None
    image_key_attribute = None

    thumbnail_width = 317
    thumbnail_height = 255
    thumbnail_upscale = True
    thumbnail_quality = 90

    image = models.ImageField(upload_to='images/',
                              default='images/no_photo.png',
                              blank=False,
                              max_length=512)

    thumbnail = ImageSpecField(source='image',
                               processors=[
                                   ResizeToCover(
                                       width=thumbnail_width,
                                       height=thumbnail_height,
                                       upscale=thumbnail_upscale,
                                   )
                               ],
                               options={'quality': thumbnail_quality})

    @property
    def has_image(self):
        return self.image != self.image.field.default
Exemple #5
0
class WorkPriceImage(models.Model):

    work = models.CharField('Название работы', max_length=100)
    price = models.PositiveIntegerField('Цена')
    image = ProcessedImageField(
        verbose_name='Изображение',
        upload_to='price_images/',
        format='JPEG',
        options={'quality': 85},
        processors=[ResizeToCover(width=350, height=350)],
    )

    block_float_roof = models.ForeignKey(BlockFlatRoof,
                                         verbose_name='Блок с ценой',
                                         on_delete=models.PROTECT,
                                         related_name='float_prices',
                                         null=True,
                                         blank=True)

    block_slop_roof = models.ForeignKey(BlockSlopRoof,
                                        verbose_name='Блок с ценой',
                                        on_delete=models.PROTECT,
                                        related_name='slop_prices',
                                        null=True,
                                        blank=True)

    def __str__(self):
        return self.work

    class Meta:
        verbose_name = 'Работа с ценой'
        verbose_name_plural = 'Работа с ценой'
Exemple #6
0
class Photo(TimeStampedModel):
    image = models.ImageField(
        verbose_name=_("field-image"),
        height_field="height",
        width_field="width",
        upload_to='var/texts',
    )
    image_thumb_detail = ImageSpecField(
        source='image',
        format='JPEG',
        options={'quality': 95},
        processors=[
            ResizeToCover(600, 600),
        ],
    )
    height = models.PositiveIntegerField(null=True)
    width = models.PositiveIntegerField(null=True)
    description = models.TextField(
        help_text=_('field-text-help-text'),
        null=True,
        blank=True,
    )
    weight = models.PositiveIntegerField(default=0)

    class Meta:
        abstract = True
        verbose_name = _('Photo')
        verbose_name_plural = _('Photos')
Exemple #7
0
class FindingImage(models.Model):
    image = models.ImageField(upload_to='finding_images', null=True)
    image_thumbnail = ImageSpecField(source='image',
                                     processors=[ResizeToCover(100, 100)],
                                     format='JPEG',
                                     options={'quality': 70})
    image_small = ImageSpecField(source='image',
                                 processors=[ResizeToCover(640, 480)],
                                 format='JPEG',
                                 options={'quality': 100})
    image_medium = ImageSpecField(source='image',
                                  processors=[ResizeToCover(800, 600)],
                                  format='JPEG',
                                  options={'quality': 100})
    image_large = ImageSpecField(source='image',
                                 processors=[ResizeToCover(1024, 768)],
                                 format='JPEG',
                                 options={'quality': 100})

    def __unicode__(self):
        return self.image.name
class Illustration(TimeStampedModel):
    objects = IllustrationManager()
    image = ImageField(
        height_field="image_height",
        upload_to='var/illustration',
        verbose_name=_("field-drawing-image"),
        width_field="image_width",
    )
    position = PositiveIntegerField(choices=ILLUSTRATION_POSITION_CHOICES)
    weight = PositiveIntegerField(default=0)
    image_thumb_detail = ImageSpecField(
        source='image',
        format='JPEG',
        options={'quality': 95},
        processors=[
            ResizeToCover(300, 300),
        ],
    )
    image_thumb_admin = ImageSpecField(
        source='image',
        format='JPEG',
        options={'quality': 95},
        processors=[
            ResizeToCover(100, 100),
        ],
    )
    image_height = PositiveIntegerField(null=True)
    image_width = PositiveIntegerField(null=True)

    class Meta:
        abstract = True
        verbose_name = _('Illustration')
        verbose_name_plural = _('Illustrations')

    def image_tag(self):
        return u'<img src="%s" />' % self.image_thumb_admin.url

    image_tag.short_description = 'Image'
    image_tag.allow_tags = True
Exemple #9
0
class Content(models.Model):
    event = models.OneToOneField(Event, related_name='content')
    # image = models.ImageField(upload_to=get_image_path, blank=True, null=True)
    image = ProcessedImageField(upload_to=get_image_path,
                                blank=True,
                                null=True,
                                processors=[ResizeToCover(300, 300)
                                            ])  #(width,height)
    description = models.TextField(max_length=500)
    addedby = models.ForeignKey(User, null=True, blank=True)

    def __unicode__(self):
        return self.event.name
Exemple #10
0
class Image(models.Model):
    """
    Image - примесь для объекта с каринкой

    image - Картинка

    upload_image_to - Путь сохранения в папке MEDIA_DIR ('image/goods')
    image_key_attribute - Атрибут в который переименовывается картинка
        может быть проперти в том числе

    По умолчанию image = 'images/no_photo.png'
    upload_image_to должен иметь вид "path/to/dir". (Нет разделителя ни в
    конце ни в начале.)
    """
    class Meta:
        abstract = True

    def __init__(self, *args, **kwargs):
        super(Image, self).__init__(*args, **kwargs)

    upload_image_to = None
    image_key_attribute = None

    thumbnail_width = 317
    thumbnail_height = 255
    thumbnail_upscale = True
    thumbnail_quality = 85

    # Images
    image = models.ImageField(
        upload_to=UploadTo,
        default='images/no_photo.png',
        verbose_name='Картинка',
        blank=True,
    )

    thumbnail = ImageSpecField(source='image',
                               processors=[
                                   ResizeToCover(
                                       width=thumbnail_width,
                                       height=thumbnail_height,
                                       upscale=thumbnail_upscale,
                                   )
                               ],
                               options={'quality': thumbnail_quality})

    @property
    def has_image(self):
        return self.image != self.image.field.default
Exemple #11
0
class Portfolio(models.Model):
    """Галерея Наши работы"""

    alt = models.TextField('Описание картинки - АЛЬТ')
    image = ProcessedImageField(
        verbose_name='Изображение',
        upload_to='portfolio/',
        format='JPEG',
        options={'quality': 85},
        processors=[ResizeToCover(width=800, height=800)],
    )

    def __str__(self):
        return f'Работа id - {self.id}'

    class Meta:
        verbose_name = 'Блок - Наши работы'
        verbose_name_plural = 'Блок - Наши работы'
Exemple #12
0
class Product(models.Model):
    TYPES = ((1, _('Product|Insert')), (2, _('Product|Accessory')))
    name = models.CharField(max_length=40, verbose_name=_('Product|name'))
    slug = models.SlugField(unique=True,
                            blank=True,
                            verbose_name=_('Product|slug'))
    desc = models.TextField(verbose_name=_('Product|desc'))
    type = models.IntegerField(choices=TYPES, verbose_name=_('Product|type'))
    price_byn = models.DecimalField(max_digits=5,
                                    decimal_places=2,
                                    verbose_name=_('Product|BYN'))
    price_usd = models.DecimalField(max_digits=5,
                                    decimal_places=2,
                                    verbose_name=_('Product|USD'))
    base_image = ProcessedImageField(upload_to='images',
                                     processors=[ResizeToFit(300, 300)],
                                     format='PNG',
                                     default='media/default.png',
                                     verbose_name=_("Product|base_image"))
    base_image_thumbnail = ImageSpecField(
        source='base_image',
        processors=[ResizeToCover(100, 50)],
        format='PNG',
    )
    created_at = models.DateTimeField(auto_now_add=True,
                                      verbose_name=_('Product|created_at'))
    updated_at = models.DateTimeField(auto_now=True,
                                      verbose_name=_('Product|updated_at'))

    class Meta:
        verbose_name = _('Product')
        verbose_name_plural = _('Product|plural')

    def __str__(self):
        return self.name

    def admin_image_tag(self):
        return u'<img src="%s" />' % self.base_image_thumbnail.url

    admin_image_tag.allow_tags = True
    admin_image_tag.short_description = _('Product|image')
Exemple #13
0
class News(models.Model):
    body = RichTextField(verbose_name=_('News|body'))
    carousel = models.BooleanField(default=False,
                                   verbose_name=_('News|carousel'))
    image = ProcessedImageField(upload_to='images/base',
                                processors=[Resize(800, 600, False)],
                                format='JPEG',
                                verbose_name=_('News|image'))
    cropped_image = ImageSpecField(source='image',
                                   processors=[Crop(400, 400)],
                                   format='JPEG')
    image_thumbnail = ImageSpecField(
        source='image',
        processors=[ResizeToCover(100, 100)],
        format='JPEG',
    )
    created_at = models.DateTimeField(auto_now_add=True,
                                      verbose_name=_('News|created'))
    updated_at = models.DateTimeField(auto_now=True,
                                      verbose_name=_('News|updated'))

    class Meta:
        verbose_name = _('News')
        verbose_name_plural = _('News|plural')

    def __str__(self):
        return str(self.id)

    def admin_image_tag(self):
        return u'<img src="%s" />' % self.image_thumbnail.url

    def admin_body(self):
        s = strip_tags(self.body)[:40]
        if len(strip_tags(self.body)) > 40:
            s += '...'
        return s

    admin_image_tag.allow_tags = True
    admin_body.allow_tags = True
    admin_body.short_description = _('News|body')
    admin_image_tag.short_description = _('News|Image')
Exemple #14
0
class Images(models.Model):
    image = ProcessedImageField(upload_to='main',
                                processors=[ResizeToCover(500, 500)],
                                format='JPEG',
                                options={'quality': 100})
    image_thumbnail = ProcessedImageField(upload_to='thumbnails',
                                          processors=[SmartResize(200, 200)],
                                          format='JPEG',
                                          options={'quality': 100})
    # caption = models.CharField(max_length=255)
    time = models.TimeField(auto_now_add=True)
    # slug = models.SlugField(max_length=20, null=True)
    user = models.ForeignKey(User)

    def __str__(self):
        return str(self.pk)

    def upload_image(self, image, user):
        i = Images.objects.create(image=image,
                                  image_thumbnail=image,
                                  user=user)
        return i
class ProductImage(models.Model):

    product = models.ForeignKey(Product,
                                verbose_name='product',
                                related_name='images',
                                on_delete=models.CASCADE)
    sort = models.PositiveSmallIntegerField('sorting', default=1)
    image = models.ImageField('picture', upload_to=upload_to('products'))

    image_admin = ImageSpecField(source='image',
                                 processors=[ResizeToCover(100, 100)],
                                 format='JPEG',
                                 options={'quality': 90})

    image_banner = ImageSpecField(source='image',
                                  processors=[
                                      ResizeToFit(250, 250),
                                      ResizeCanvas(250,
                                                   250,
                                                   anchor=Anchor.CENTER)
                                  ],
                                  format='PNG')

    image_product = ImageSpecField(source='image',
                                   processors=[
                                       ResizeToFit(280, 280),
                                       ResizeCanvas(280,
                                                    280,
                                                    anchor=Anchor.CENTER)
                                   ],
                                   format='PNG')

    image_category = ImageSpecField(source='image',
                                    processors=[
                                        ResizeToFit(160, 160),
                                        ResizeCanvas(160,
                                                     160,
                                                     anchor=Anchor.CENTER)
                                    ],
                                    format='PNG')

    image_list = ImageSpecField(source='image',
                                processors=[
                                    ResizeToFit(160, 160),
                                    ResizeCanvas(160,
                                                 160,
                                                 anchor=Anchor.CENTER)
                                ],
                                format='PNG')

    image_cart = ImageSpecField(source='image',
                                processors=[
                                    ResizeToFit(86, 86),
                                    ResizeCanvas(86, 86, anchor=Anchor.CENTER)
                                ],
                                format='PNG')

    class Meta:
        verbose_name = 'product image'
        verbose_name_plural = 'product images'
        ordering = ('sort', )
Exemple #16
0
class LDPI(ImageSpec):
    processors = [ResizeToCover(270, 120)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #17
0
class XXXHDPI(ImageSpec):
    processors = [ResizeToCover(1440, 640)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #18
0
class XHDPI(ImageSpec):
    processors = [ResizeToCover(720, 320)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #19
0
class Source(models.Model):
    source_type = _('Base source class')
    renderers = (RENDERER_JSON, RENDERER_BROWSEABLE_API, RENDERER_XML,
                 RENDERER_YAML, RENDERER_DATAGRID)
    preview_renderer = RENDERER_DATAGRID
    support_column_regex = False

    # Base data
    name = models.CharField(max_length=128,
                            verbose_name=_('name'),
                            help_text=('Human readable name for this source.'))
    slug = models.SlugField(
        unique=True,
        blank=True,
        max_length=48,
        verbose_name=_('slug'),
        help_text=
        ('URL friendly description of this source. If none is specified the name will be used.'
         ))
    description = models.TextField(blank=True, verbose_name=_('description'))

    # Images
    image = models.ImageField(null=True,
                              blank=True,
                              upload_to='images',
                              verbose_name=_('image'))
    showcase_image = ImageSpecField(source='image',
                                    processors=[ResizeToCover(140, 140)],
                                    format='PNG',
                                    options={'quality': 90})
    thumbnail_image = ImageSpecField(source='image',
                                     processors=[ResizeToFit(50, 50)],
                                     format='PNG',
                                     options={'quality': 60})

    # Data engine
    published = models.BooleanField(default=False, verbose_name=_('published'))
    allowed_groups = models.ManyToManyField(Group,
                                            verbose_name=_('allowed groups'),
                                            blank=True,
                                            null=True)
    limit = models.PositiveIntegerField(
        default=DEFAULT_LIMIT,
        verbose_name=_('limit'),
        help_text=_(
            'Maximum number of items to show when all items are requested.'))
    origin = models.ForeignKey(Origin, verbose_name=_('origin'))

    # Scheduling
    schedule_string = models.CharField(max_length=128,
                                       blank=True,
                                       verbose_name=_('schedule string'),
                                       help_text=_('Use CRON style format.'))
    schedule_enabled = models.BooleanField(
        default=False,
        verbose_name=_('schedule enabled'),
        help_text=_('Enabled scheduled check for source\' origin updates.'))

    # Managers
    objects = InheritanceManager()
    allowed = SourceAccessManager()

    def check_source_data(self):
        logger.info('Checking for new data for source: %s' % self.slug)

        try:
            lock_id = u'check_source_data-%d' % self.pk
            logger.debug('trying to acquire lock: %s' % lock_id)
            lock = Lock.acquire_lock(lock_id, 60)
            logger.debug('acquired lock: %s' % lock_id)
            try:
                self.check_origin_data()
                pass
            except Exception as exception:
                logger.debug('unhandled exception: %s' % exception)
                logger.error('Error when checking data for source: %s; %s' %
                             (self.slug, exception))
                raise
            finally:
                lock.release()
        except LockError:
            logger.debug('unable to obtain lock')
            logger.info(
                'Unable to obtain lock to check for new data for source: %s' %
                self.slug)
            pass

    def check_origin_data(self):
        self.origin_subclass_instance = Origin.objects.get_subclass(
            pk=self.origin.pk)
        self.origin_subclass_instance.copy_data()

        logger.debug('new_hash: %s' % self.origin_subclass_instance.new_hash)

        try:
            source_data_version = self.versions.get(
                checksum=self.origin_subclass_instance.new_hash)
        except SourceDataVersion.DoesNotExist:
            logger.info('New origin data version found for source: %s' %
                        self.slug)
            source_data_version = SourceDataVersion.objects.create(
                source=self, checksum=self.origin_subclass_instance.new_hash)
            job = Job(target=self.import_origin_data,
                      args=[source_data_version])
            job.submit()
            logger.debug('launching import job: %s' % job)
        else:
            source_data_version.active = True
            source_data_version.save()

    def _get_metadata(self):
        """Source models are responsible for overloading this method"""
        return ''

    @transaction.commit_on_success
    def import_origin_data(self, source_data_version):
        source_data_version = SourceDataVersion.objects.get(
            pk=source_data_version.pk)

        source_data_version.metadata = self._get_metadata()
        source_data_version.save()

        if self.support_column_regex:
            self.get_regex_maps()

        logger.info('Importing new data for source: %s' % self.slug)

        row_count = 0
        try:
            for row_id, row in enumerate(self._get_rows(), 1):
                SourceData.objects.create(
                    source_data_version=source_data_version,
                    row_id=row_id,
                    row=dict(row, **{'_id': row_id}))
                row_count += 1
        except Exception as exception:
            transaction.rollback()
            logger.error('Error importing rows; %s' % exception)
            if getattr(settings, 'DEBUG', False):
                raise
            else:
                return

        logger.debug('finished importing rows')

        source_data_version.ready = True
        source_data_version.active = True
        source_data_version.elements = row_count
        source_data_version.save()

        self.origin_subclass_instance.discard_copy()
        logger.info('Imported %d rows for source: %s' % (row_count, self.slug))

    class AlwaysFalseSearch(object):
        def search(self, string):
            return False

    class AlwaysTrueSearch(object):
        def search(self, string):
            return True

    def get_regex_maps(self):
        self.skip_regex_map = {}
        for name, skip_regex in self.columns.values_list('name', 'skip_regex'):
            if skip_regex:
                self.skip_regex_map[name] = re.compile(skip_regex)
            else:
                self.skip_regex_map[name] = self.__class__.AlwaysFalseSearch()

        self.import_regex_map = {}
        for name, import_regex in self.columns.values_list(
                'name', 'import_regex'):
            if import_regex:
                self.import_regex_map[name] = re.compile(import_regex)
            else:
                self.import_regex_map[name] = self.__class__.AlwaysTrueSearch()

    def process_regex(self, row):
        skip_result = [
            True if self.skip_regex_map[name].search(unicode(value)) else False
            for name, value in row.items() if name in self.skip_regex_map
        ]
        import_result = [
            True
            if self.import_regex_map[name].search(unicode(value)) else False
            for name, value in row.items() if name in self.import_regex_map
        ]

        return all(cell_skip is False
                   for cell_skip in skip_result) and all(import_result)

    def get_all(self, id=None, parameters=None):
        logger.debug('parameters: %s' % parameters)
        initial_datetime = datetime.datetime.now()
        timestamp, parameters = Source.analyze_request(parameters)
        logger.debug('timestamp: %s', timestamp)

        try:
            if timestamp:
                source_data_version = self.versions.get(timestamp=timestamp)
            else:
                source_data_version = self.versions.get(active=True)
        except SourceDataVersion.DoesNotExist:
            return []

        self.base_iterator = (item.row for item in SourceData.objects.filter(
            source_data_version=source_data_version).iterator())

        if id:
            self.base_iterator = islice(self.base_iterator, id - 1, id)

        results = Query(self).execute(parameters)
        logger.debug('query elapsed time: %s' %
                     (datetime.datetime.now() - initial_datetime))

        return results

    def get_one(self, id, parameters=None):
        # ID are all base 1
        if id == 0:
            raise LIBREAPIError('Invalid ID; IDs are base 1')
        return self.get_all(id, parameters)

    @staticmethod
    def analyze_request(parameters=None):
        kwargs = {}
        if not parameters:
            parameters = {}
        else:
            for i in parameters:
                if not i.startswith('_'):
                    kwargs[i] = parameters[i]

        timestamp = parameters.get('_timestamp', None)

        return timestamp, parameters

    def get_functions_map(self):
        """Calculate the column name to data type conversion map"""
        return dict([(column, DATA_TYPE_FUNCTIONS[data_type])
                     for column, data_type in self.columns.values_list(
                         'name', 'data_type')])

    def apply_datatypes(self, properties, functions_map):
        result = {}

        for key, value in properties.items():
            try:
                result[key] = functions_map[key](value)
            except KeyError:
                # Is not to be converted
                result[key] = value
            except ValueError:
                # Fallback for failed conversion
                logger.error('Unable to apply data type for field: %s' % key)
                result[key] = value

        return result

    def clear_versions(self):
        """Delete all the versions of this source"""
        for version in self.versions.all():
            version.delete()

    def __unicode__(self):
        return self.name

    def clean(self):
        """Validation method, to avoid adding a source without a slug value"""
        if not self.slug:
            self.slug = slugify(self.name)

    @models.permalink
    def get_absolute_url(self):
        return ('source_view', [self.slug])

    class Meta:
        verbose_name = _('source')
        verbose_name_plural = _('sources')
        ordering = ['name', 'slug']
Exemple #20
0
class HQ(ImageSpec):
    processors = [ResizeToCover(854, 480)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #21
0
class HD(ImageSpec):
    processors = [ResizeToCover(1280, 720)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #22
0
class FullHD(ImageSpec):
    processors = [ResizeToCover(1920, 1080)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #23
0
class Drawing(TimeStampedModel):
    objects = DrawingManager()
    name = CharField(
        max_length=255,
        verbose_name=_('field-name'),
        help_text=_('field-name-help-text'),
    )
    size = ForeignKey(
        'DrawingSize',
        related_name='drawings',
        verbose_name=_('field-size'),
    )
    status = PositiveIntegerField(
        choices=DRAWING_STATUS_CHOICES,
        default=DRAWING_STATUS_STORED,
        verbose_name=_('field-drawing-status'),
    )
    image = ImageField(
        height_field="image_height",
        upload_to='var/drawings',
        verbose_name=_("field-drawing-image"),
        width_field="image_width",
    )
    image_thumb_detail = ImageSpecField(
        source='image',
        format='JPEG',
        options={'quality': 95},
        processors=[
            ResizeToCover(600, 600),
            Watermark(
                'web/static/images/watermark-black.png',
                0.09,
            )
        ],
    )
    image_thumb_list = ImageSpecField(
        source='image',
        format='JPEG',
        options={'quality': 95},
        processors=[
            ResizeToCover(300, 300),
            Watermark(
                'web/static/images/watermark-white.png',
                0.1,
            ),
        ],
    )
    image_height = PositiveIntegerField(null=True)
    image_width = PositiveIntegerField(null=True)
    tags = ManyToManyField(
        'DrawingTag',
        verbose_name=_('field-tags'),
        related_name='drawings',
    )

    class Meta:
        verbose_name = _('Drawing')
        verbose_name_plural = _('Drawings')

    def __str__(self):
        return '%s (%s)' % (self.name, self.size)

    def get_active_price_level(self):
        now = datetime.now()
        return self.price_levels.filter(
            (Q(valid_from__isnull=True) | Q(valid_from__gte=now)) &
            (Q(valid_until__isnull=True)
             | Q(valid_until__lte=now)), ).order_by('-created').first()

    def get_price(self):
        price_level = self.get_active_price_level()
        return price_level.price if price_level else None

    def is_price_visible(self):
        return self.status in DRAWING_AVAILABLE_STATES

    def is_status_visible(self):
        return self.status not in DRAWING_AVAILABLE_STATES

    def mark_as_reserved(self):
        self.status = DRAWING_STATUS_RESERVED

    def mark_as_sold(self):
        self.status = DRAWING_STATUS_SOLD

    def get_title(self):
        return '%s %s' % (self.size.name, self.name
                          ) if self.size.standalone_name else self.name
Exemple #24
0
class LQ(ImageSpec):
    processors = [ResizeToCover(640, 360)]
    format = 'JPEG'
    options = {'quality': 100}
Exemple #25
0
class Image(models.Model):

    source = ProcessedImageField(upload_to='images',
                                 processors=[
                                     ResizeToCover(
                                         width=settings.GALLERY_MIN_WIDTH,
                                         height=settings.GALLERY_MIN_HEIGHT,
                                         upscale=False)
                                 ],
                                 options={'keep_exif': True})
    thumbnail = ImageSpecField(
        source='source',
        processors=[
            ResizeToFit(height=settings.GALLERY_THUMBNAIL_SIZE *
                        settings.GALLERY_HDPI_FACTOR)
        ],
        format='JPEG',
        options={'quality': settings.GALLERY_RESIZE_QUALITY})
    preview = ImageSpecField(
        source='source',
        processors=[
            ResizeToFit(
                width=settings.
                GALLERY_PREVIEW_SIZE,  #* settings.GALLERY_HDPI_FACTOR,
                height=settings.
                GALLERY_PREVIEW_SIZE,  #* settings.GALLERY_HDPI_FACTOR
            )
        ],
        format='JPEG',
        options={'quality': settings.GALLERY_RESIZE_QUALITY})
    date_uploaded = models.DateTimeField(auto_now_add=True)
    date_taken = models.DateTimeField(null=True, blank=True)

    @cached_property
    def size_str(self):
        if not hasattr(self, 'width'):
            #try:
            with pImage.open(self.source.path) as img:
                self.width = img.width
                self.height = img.height
                img.close()
            #except (ValueError,):
            # storage/cache seems to have not been created yet,
            # this happens only on first admin pImage.open access,
            # ok next time (fixme: sync)
            #    self.width = 0
            #    self.height = 0
        return '%d x %d' % (self.width, self.height)

    @cached_property
    def exif(self):
        """ Retrieve exif data using PIL as a dictionary """
        exif_data = {}
        self.source.open()
        with pImage.open(self.source) as img:
            if hasattr(img, '_getexif'):
                info = img._getexif()
                if not info:
                    return {}
                for tag, value in info.items():
                    decoded = TAGS.get(tag, tag)
                    exif_data[decoded] = value
                # Process some data for easy rendering in template
                exif_data['Camera'] = exif_data.get('Model', '')
                if exif_data.get(
                        'Make', ''
                ) not in exif_data['Camera']:  # Work around for Canon
                    exif_data['Camera'] = "{0} {1}".format(
                        exif_data['Make'].title(), exif_data['Model'])
                if 'FNumber' in exif_data:
                    exif_data['Aperture'] = str(
                        exif_data['FNumber'].numerator /
                        exif_data['FNumber'].denominator)
                if 'ExposureTime' in exif_data:
                    exif_data['Exposure'] = "{0}/{1}".format(
                        exif_data['ExposureTime'].numerator,
                        exif_data['ExposureTime'].denominator)
            img.close()
        self.source.close()
        return exif_data

    def _date_taken(self):
        exif_data = piexif.load(self.source.path)
        taken_bytes = exif_data['Exif'].get(
            piexif.ExifIFD.DateTimeOriginal) if exif_data.get('Exif') else None
        if not taken_bytes:
            return self.mtime
        try:
            return datetime.strptime(taken_bytes.decode(), "%Y:%m:%d %H:%M:%S")
        except Exception:  # Fall back to file modification time
            return self.mtime

    @cached_property
    def mtime(self):
        return datetime.fromtimestamp(os.path.getmtime(self.source.path))

    @property
    def title(self):
        """ Derive a title from the original filename """
        if hasattr(self, '_title'):
            return self._title
        name = Path(self.source.name)
        # remove extension
        name = name.with_suffix('').name
        # convert spacing characters to whitespaces
        return name.translate(str.maketrans('_', ' '))

    # Temporary override for album highlights
    @title.setter
    def title(self, name):
        self._title = name

    def get_absolute_url(self):
        return reverse('gallery:image_detail', kwargs={'pk': self.pk})

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        # The first save commits the uploaded file and creates self.source.file
        super().save(*args, **kwargs)
        # Preset date_taken: get exif date if exif exists else file
        # modified date and save to allow db queries, and admin overrides
        if not self.date_taken:
            self.date_taken = self._date_taken()
            # and re-save. (images are added/saved to db only once per 'lifetime')
            kwargs.update({'force_insert': False, 'force_update': True})
            super().save(*args, **kwargs)
Exemple #26
0
class Picture(models.Model):
    class Meta:
        ordering = ['-id']

    class NonTrashManager(models.Manager):
        """ Query only objects which have not been trashed. """
        def get_queryset(self):
            query_set = super(Picture.NonTrashManager, self).get_queryset()
            return query_set.filter(trashed_time__isnull=True)

    class TrashManager(models.Manager):
        """ Query only objects which have been trashed. """
        def get_queryset(self):
            query_set = super(Picture.TrashManager, self).get_queryset()
            return query_set.filter(trashed_time__isnull=False)

    id = models.AutoField(primary_key=True)
    image = models.ImageField(upload_to='uploads/')
    image_small = ImageSpecField(source='image',
                                 processors=[ResizeToCover(450, 450)],
                                 format='JPEG',
                                 options={'quality': 80})
    category = models.ForeignKey('Category', on_delete=models.PROTECT)
    title = models.CharField(max_length=128)
    description = models.TextField(max_length=5120, blank=True)

    upload_time = models.DateField(auto_now_add=True)
    trashed_time = models.DateTimeField(blank=True, null=True)

    objects = NonTrashManager()
    trash = TrashManager()

    @property
    def is_narrow(self):
        return self.image.width / self.image.height < 3 / 4

    @property
    def is_wide(self):
        return self.image.width / self.image.height > 4 / 3

    @property
    def is_trashed(self):
        return self.trashed_time is not None

    def delete(self, trash=True, **kwargs):
        """
        Moves the picture to trash
        """
        if self.is_trashed or not trash:
            super(Picture, self).delete()
            return

        self.trashed_time = datetime.now()
        self.save()

    def restore(self, commit=True):
        """
        Restores the picture from the trash
        """
        self.trashed_time = None
        if commit:
            self.save()

    def __str__(self):
        if self.title:
            return f'An image #{self.id} with title \'{self.title}\''
        if self.description:
            description = (
                self.description[:128] +
                '...') if len(self.description) > 128 else self.description
            return f'An image #{self.id} with description \'{description}\''
        return f'An image #{self.id}'

    @staticmethod
    def clear_obsolete_trash():
        """
        Permanently deletes all pictures from the trash
        which were trashed minute ago or later
        """
        minute_ago = datetime.now() - timedelta(minutes=1)
        Picture.trash.filter(trashed_time__lt=minute_ago).delete()
Exemple #27
0
class Session(models.Model):
    name = models.CharField(max_length=SESSION_NAME_LEN)
    description = models.CharField(max_length=SESSION_DESCRIPTION_LEN)

    #Session size
    session_type = models.CharField(max_length=3, choices=session_types.SESSION_TYPES, default=session_types.REGIONAL_SESSION)

    picture = models.ImageField(upload_to='session_pictures/')
    # Session picture used on front-page to help loading times
    picture_thumbnail = ImageSpecField(source='picture',
                                               processors=[ResizeToCover(400, 400)],
                                               format='JPEG',
                                               options={'quality': 80})
    # Session picture used on session page to help loading times and still acceptable image quality
    picture_large_fast = ImageSpecField(source='picture',
                                               processors=[ResizeToCover(1280, 400)],
                                               format='JPEG',
                                               options={'quality': 100})


    # Session picture author link allows users to credit photographers e.g. for Creative Commons content
    picture_author = models.CharField(max_length=SESSION_AUTHOR_LEN, blank=True)
    picture_author_link = models.URLField(blank=True)
    picture_licence = models.CharField(max_length=SESSION_LICENCE_LEN, blank=True)
    picture_license_link = models.URLField(blank=True)

    email = models.EmailField()

    # The following links will be displayed on the sessions main page if a link is provided
    resolution_link = models.URLField(blank=True)
    website_link = models.URLField(blank=True)
    facebook_link = models.URLField(blank=True)
    twitter_link = models.URLField(blank=True)
    country = models.CharField(max_length=2, choices=countries.SESSION_COUNTRIES, default=countries.ALBANIA)

    #Date Options
    start_date = models.DateTimeField('start date')
    end_date = models.DateTimeField('end date')

    #Setting up statistic types
    STATISTICS = 'S'
    CONTENT = 'C'
    JOINTFORM = 'JF'
    SPLITFORM = 'SF'
    RUNNINGORDER = 'R'
    RUNNINGCONTENT = 'RC'
    STATISTIC_TYPES = (
        (STATISTICS, 'Statistics Only'),
        (CONTENT, 'Point Content Only'),
        (JOINTFORM, 'Joint Form Statistics'),
        (SPLITFORM, 'Split Form Statistics'),
        (RUNNINGORDER, 'Running Order Statistics'),
        (RUNNINGCONTENT, 'Running Order Statistics with Point Content')
    )
    session_statistics = models.CharField(max_length=3, choices=STATISTIC_TYPES, default=JOINTFORM)

    is_visible = models.BooleanField('is visible')

    voting_enabled = models.BooleanField('session-wide voting enabled', default=True)
    gender_enabled = models.BooleanField('gender statistics enabled', default=False)
    max_rounds = models.PositiveSmallIntegerField(default=3)

    gender_number_female = models.IntegerField(blank=True, null=True)
    gender_number_male = models.IntegerField(blank=True, null=True)
    gender_number_other = models.IntegerField(blank=True, null=True)

    # If the session has had technical problems some data is probably missing. If this is activated a message will be shown to indidate this.
    has_technical_problems = models.BooleanField('session has technical problems', default=False)

    #Defining two users for the session. The Admin user who can alter active debates, change points etc. and the
    #submit user, which will be the login for everyone at any given session who wants to submit a point.
    admin_user = models.ForeignKey(User, related_name = 'session_admin', blank = True, null = True)
    submission_user = models.ForeignKey(User, related_name = 'session_submit', blank = True, null = True)

    def __unicode__(self):
        return unicode(self.name)

    def session_ongoing(self):
        return (self.start_date <= timezone.now() and self.end_date >= timezone.now())
    session_ongoing.admin_order_field = 'start_date'
    session_ongoing.boolean = True
    session_ongoing.short_description = 'Session Ongoing'

    def session_latest_activity(self):
        """
        Returns date and time of the latest activity of the session. If there was never any activity, return 1972 as latest activity.
        """
        initialising_datetime = timezone.make_aware(datetime.datetime(1972, 1, 1, 2), timezone.get_default_timezone())
        latest_point = initialising_datetime
        latest_content = initialising_datetime
        latest_vote = initialising_datetime

        if Point.objects.filter(session=self):
            latest_point = Point.objects.filter(session=self).order_by('-timestamp')[0].timestamp
        if ContentPoint.objects.filter(session=self):
            latest_content = ContentPoint.objects.filter(session=self).order_by('-timestamp')[0].timestamp
        if Vote.objects.filter(session=self):
            latest_vote = Vote.objects.filter(session=self).order_by('-timestamp')[0].timestamp

        # This sorts the list of datetimes and the latest datetime is the third element of the list, which is saved to latest_activity
        latest_activity = sorted([latest_vote, latest_point, latest_content])[2]

        if latest_activity > initialising_datetime:
            return latest_activity
        else:
            return False

    def minutes_per_point(self):
        if self.session_statistics != 'C':
            all_points = Point.objects.filter(session=self).order_by('timestamp')
        else:
            all_points = ContentPoint.objects.filter(session=self).order_by('timestamp')

        if all_points.count() == 0:
            return 0

        total_points = all_points.count()
        first_point = all_points.first().timestamp
        latest_point = all_points.last().timestamp
        time_diff = latest_point - first_point
        minutes = (time_diff.days * 1440) + (time_diff.seconds / 60)

        return Decimal(minutes) / Decimal(total_points)