|
|
@ -1,14 +1,15 @@ |
|
|
|
import logging |
|
|
|
import logging |
|
|
|
import posixpath |
|
|
|
import posixpath |
|
|
|
import re |
|
|
|
import re |
|
|
|
|
|
|
|
from functools import partial |
|
|
|
|
|
|
|
|
|
|
|
from django.db import models |
|
|
|
from django.db import models |
|
|
|
from django.utils.html import strip_tags |
|
|
|
from django.utils.html import strip_tags |
|
|
|
|
|
|
|
from django.utils.text import Truncator |
|
|
|
from django.utils.translation import ugettext_lazy as _ |
|
|
|
from django.utils.translation import ugettext_lazy as _ |
|
|
|
|
|
|
|
|
|
|
|
from imagefield.fields import ImageField, PPOIField |
|
|
|
from imagefield.fields import ImageField, PPOIField |
|
|
|
from imagekit.models import ImageSpecField |
|
|
|
from shared.utils.text import html_to_text, sanitized_html |
|
|
|
from imagekit.processors import Adjust, Thumbnail, ResizeToFit, ResizeToFill |
|
|
|
|
|
|
|
from shared.utils.models.slugs import DowngradingSlugField, slugify |
|
|
|
from shared.utils.models.slugs import DowngradingSlugField, slugify |
|
|
|
|
|
|
|
|
|
|
|
from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS |
|
|
|
from .conf import UPLOAD_TO, USE_TRANSLATABLE_FIELDS |
|
|
@ -34,7 +35,7 @@ class MediaCategoryManager(models.Manager): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MediaCategory(models.Model): |
|
|
|
class MediaCategory(models.Model): |
|
|
|
name = models.CharField(_("name"), max_length=200) |
|
|
|
name = models.CharField(_("name"), blank=True, max_length=200) |
|
|
|
parent = models.ForeignKey( |
|
|
|
parent = models.ForeignKey( |
|
|
|
'self', blank=True, null=True, |
|
|
|
'self', blank=True, null=True, |
|
|
|
on_delete=models.CASCADE, |
|
|
|
on_delete=models.CASCADE, |
|
|
@ -78,7 +79,8 @@ class Gallery(models.Model): |
|
|
|
help_text=_("Publicly visible name.")) |
|
|
|
help_text=_("Publicly visible name.")) |
|
|
|
slug = models.SlugField(_("Slug"), null=True, blank=True) |
|
|
|
slug = models.SlugField(_("Slug"), null=True, blank=True) |
|
|
|
credits = TranslatableCharField(_("Credits"), null=True, blank=True, max_length=500) |
|
|
|
credits = TranslatableCharField(_("Credits"), null=True, blank=True, max_length=500) |
|
|
|
caption = TranslatableCleansedRichTextField(_("Caption"), null=True, blank=True) |
|
|
|
caption = TranslatableCleansedRichTextField(_("Caption"), |
|
|
|
|
|
|
|
null=True, blank=True, config_name='caption') |
|
|
|
is_public = models.BooleanField(_("Active"), default=False) |
|
|
|
is_public = models.BooleanField(_("Active"), default=False) |
|
|
|
order_index = models.PositiveIntegerField(_("Order Index"), default=0) |
|
|
|
order_index = models.PositiveIntegerField(_("Order Index"), default=0) |
|
|
|
# background_color = models.ForeignKey('site_pages.Color', on_delete=models.PROTECT, |
|
|
|
# background_color = models.ForeignKey('site_pages.Color', on_delete=models.PROTECT, |
|
|
@ -165,8 +167,8 @@ class MediaRole(models.Model): |
|
|
|
name = TranslatableCharField(_("name"), max_length=200) |
|
|
|
name = TranslatableCharField(_("name"), max_length=200) |
|
|
|
|
|
|
|
|
|
|
|
class Meta: |
|
|
|
class Meta: |
|
|
|
verbose_name = _("Bild-Typ") |
|
|
|
verbose_name = _("Art") |
|
|
|
verbose_name_plural = _("Bild-Typen") |
|
|
|
verbose_name_plural = _("Arten") |
|
|
|
ordering = i18n_fields('name') |
|
|
|
ordering = i18n_fields('name') |
|
|
|
|
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
def __str__(self): |
|
|
@ -194,7 +196,9 @@ class MediaBase(DeleteOldFileMixin, models.Model): |
|
|
|
verbose_name=_("Typ"), |
|
|
|
verbose_name=_("Typ"), |
|
|
|
null=True, blank=True) |
|
|
|
null=True, blank=True) |
|
|
|
name = TranslatableCharField(_("Name"), max_length=200, null=True, blank=True) |
|
|
|
name = TranslatableCharField(_("Name"), max_length=200, null=True, blank=True) |
|
|
|
caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True) |
|
|
|
caption = TranslatableCleansedRichTextField(_("Bildunterschrift"), blank=True, |
|
|
|
|
|
|
|
config_name='caption', |
|
|
|
|
|
|
|
cleanse=partial(sanitized_html, config_name='caption')) |
|
|
|
credits = TranslatableCharField(_("Credits"), max_length=500, null=True, blank=True) |
|
|
|
credits = TranslatableCharField(_("Credits"), max_length=500, null=True, blank=True) |
|
|
|
copyright = TranslatableCharField(_('Rechteinhaber/in'), max_length=2000, blank=True) |
|
|
|
copyright = TranslatableCharField(_('Rechteinhaber/in'), max_length=2000, blank=True) |
|
|
|
|
|
|
|
|
|
|
@ -211,6 +215,11 @@ class MediaBase(DeleteOldFileMixin, models.Model): |
|
|
|
return self.name or strip_tags(self.caption) or posixpath.basename(self.file.name) |
|
|
|
return self.name or strip_tags(self.caption) or posixpath.basename(self.file.name) |
|
|
|
|
|
|
|
|
|
|
|
def save(self, *args, **kwargs): |
|
|
|
def save(self, *args, **kwargs): |
|
|
|
|
|
|
|
if not self.name: |
|
|
|
|
|
|
|
if self.caption: |
|
|
|
|
|
|
|
self.name = Truncator(html_to_text(self.caption)).chars(200, truncate=' …') |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
self.name = Truncator(posixpath.basename(self.file.name)).chars(200, truncate=' …') |
|
|
|
if self.file: |
|
|
|
if self.file: |
|
|
|
try: |
|
|
|
try: |
|
|
|
self.file_size = self.file.size |
|
|
|
self.file_size = self.file.size |
|
|
@ -221,14 +230,6 @@ class MediaBase(DeleteOldFileMixin, models.Model): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Image(MediaBase): |
|
|
|
class Image(MediaBase): |
|
|
|
image_width = models.PositiveIntegerField( |
|
|
|
|
|
|
|
_("image width"), blank=True, null=True, editable=False |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
image_height = models.PositiveIntegerField( |
|
|
|
|
|
|
|
_("image height"), blank=True, null=True, editable=False |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
image_ppoi = PPOIField(_("primary point of interest")) |
|
|
|
|
|
|
|
# file = models.ImageField(_("Datei")) |
|
|
|
|
|
|
|
file = ImageField( |
|
|
|
file = ImageField( |
|
|
|
_("image"), |
|
|
|
_("image"), |
|
|
|
max_length=200, |
|
|
|
max_length=200, |
|
|
@ -238,43 +239,11 @@ class Image(MediaBase): |
|
|
|
ppoi_field="image_ppoi", |
|
|
|
ppoi_field="image_ppoi", |
|
|
|
blank=True, |
|
|
|
blank=True, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
image_width = models.PositiveIntegerField( |
|
|
|
logo_image = ImageSpecField(source='file', |
|
|
|
_("image width"), blank=True, null=True, editable=False) |
|
|
|
processors=[ResizeToFit(150, 150)]) |
|
|
|
image_height = models.PositiveIntegerField( |
|
|
|
|
|
|
|
_("image height"), blank=True, null=True, editable=False) |
|
|
|
thumbnail = ImageSpecField(source='file', |
|
|
|
image_ppoi = PPOIField(_("primary point of interest")) |
|
|
|
processors=[Adjust(contrast=1.2, sharpness=1.1), |
|
|
|
|
|
|
|
Thumbnail(100, 50)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
square_image = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ResizeToFill(800, 800)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
small_article_image = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ResizeToFit(400, 400)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
article_image = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ResizeToFit(800, 800)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gallery_image = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ResizeToFit(1200, 1200)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gallery_image_thumbnail = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ |
|
|
|
|
|
|
|
Adjust(contrast=1.2, sharpness=1.1), |
|
|
|
|
|
|
|
# ResizeToFit(180, 120) |
|
|
|
|
|
|
|
ResizeToFit(220, 155) |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lightbox_image = ImageSpecField(source='file', |
|
|
|
|
|
|
|
processors=[ResizeToFit(1600, 1600)], |
|
|
|
|
|
|
|
format='JPEG', options={'quality': 90}) |
|
|
|
|
|
|
|
highres_image = lightbox_image |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type = 'image' |
|
|
|
type = 'image' |
|
|
|
|
|
|
|
|
|
|
|