"""Utils app models.""" from os.path import exists from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.contrib.gis.db import models from django.contrib.postgres.fields import JSONField from django.contrib.postgres.fields.jsonb import KeyTextTransform from django.utils import timezone from django.utils.html import mark_safe from django.utils.translation import ugettext_lazy as _, get_language from easy_thumbnails.fields import ThumbnailerImageField from utils.methods import image_path, svg_image_path from utils.validators import svg_image_validator class ProjectBaseMixin(models.Model): """Base mixin model.""" created = models.DateTimeField(default=timezone.now, editable=False, verbose_name=_('Date created')) modified = models.DateTimeField(auto_now=True, verbose_name=_('Date updated')) class Meta: """Meta class.""" abstract = True class TJSONField(JSONField): """Overrided JsonField.""" def translate_field(self, field_name): def translate(self): field = getattr(self, field_name) if isinstance(field, dict): return field.get(get_language()) return None return translate class TraslatedFieldsMixin: def __init__(self, *args, **kwargs): super(TraslatedFieldsMixin, self).__init__(*args, **kwargs) cls = self.__class__ for field in cls._meta.fields: field_name = field.name if isinstance(field, TJSONField): setattr(cls, f'{field.name}_translated', property(translate_field(self, field_name))) class OAuthProjectMixin: """OAuth2 mixin for project GM""" def get_source(self): """Method to get of platform""" return NotImplemented basemixin_fields = ['created', 'modified'] class BaseAttributes(ProjectBaseMixin): created_by = models.ForeignKey( 'account.User', on_delete=models.SET_NULL, verbose_name=_('created by'), null=True, related_name='%(class)s_records_created' ) modified_by = models.ForeignKey( 'account.User', on_delete=models.SET_NULL, verbose_name=_('modified by'), null=True, related_name='%(class)s_records_modified' ) class Meta: """Meta class.""" abstract = True class ImageMixin(models.Model): """Avatar model.""" THUMBNAIL_KEY = 'default' image = ThumbnailerImageField(upload_to=image_path, blank=True, null=True, default=None, verbose_name=_('Image')) class Meta: """Meta class.""" abstract = True def get_image(self, key=None): """Get thumbnailed image file.""" return self.image[key or self.THUMBNAIL_KEY] if self.image else None def get_image_url(self, key=None): """Get image thumbnail url.""" return self.get_image(key).url if self.image else None def image_tag(self): """Admin preview tag.""" if self.image: return mark_safe('' % self.get_image_url()) else: return None def get_full_image_url(self, request, thumbnail_key=None): """Get full image url""" if self.image and exists(self.image.path): return request.build_absolute_uri(self.get_image(thumbnail_key).url) else: return None image_tag.short_description = _('Image') image_tag.allow_tags = True class SVGImageMixin(models.Model): """SVG image model.""" svg_image = models.FileField(upload_to=svg_image_path, blank=True, null=True, default=None, validators=[svg_image_validator, ], verbose_name=_('SVG image')) class Meta: abstract = True class PlatformMixin(models.Model): """Platforms""" MOBILE = 0 WEB = 1 SOURCES = ( (MOBILE, _('Mobile')), (WEB, _('Web')), ) source = models.PositiveSmallIntegerField(choices=SOURCES, default=MOBILE, verbose_name=_('Source')) class Meta: """Meta class""" abstract = True class LocaleManagerMixin(models.Manager): """Manager for locale""" def annotate_localized_fields(self, locale): """Return queryset by locale""" prefix = 'trans' # Prepare fields to localization (only JSONField can be localized) fields = [field.name for field in self.model._meta.fields if isinstance(field, JSONField)] # Check filters to check if field has localization filters = {f'{field}__has_key': locale for field in fields} # Filter QuerySet by prepared filters queryset = self.filter(**filters) # Prepare field for annotator localized_fields = {f'{field}_{prefix}': KeyTextTransform(f'{locale}', field) for field in fields} # Annotate them for _ in fields: queryset = queryset.annotate(**localized_fields) return queryset class GMTokenGenerator(PasswordResetTokenGenerator): def _make_hash_value(self, user, timestamp): return ( str(user.pk) + str(user.email_confirmed) + str(timestamp) + str(user.is_active) ) gm_token_generator = GMTokenGenerator()