Source code for shuup.notify.typology

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import unicode_literals

import enumfields
from django import forms
from django.apps import apps
from django.core.exceptions import ObjectDoesNotExist
from django.core.validators import validate_email
from django.utils.text import camel_case_to_spaces
from django.utils.translation import ugettext_lazy as _


[docs]class MultiEmailField(forms.Field): """ From https://docs.djangoproject.com/en/1.11/ref/forms/validation/#form-field-default-cleaning """
[docs] def validate(self, value): """Check if value consists only of valid emails.""" # Use the parent's handling of required fields, etc. super().validate(value) if value: for email in value.split(","): if email: validate_email(email)
[docs]class Type(object): name = None identifier = None
[docs] def get_field(self, **kwargs): """ Get a Django form field for this type. The kwargs are passed directly to the field constructor. :param kwargs: Kwargs for field constructor. :type kwargs: dict :return: Form field. :rtype: django.forms.Field """ return forms.CharField(**kwargs)
[docs] def unserialize(self, value): return self.get_field().to_python(value)
[docs] def validate(self, value): return self.get_field().validate(value)
[docs] def is_coercible_from(self, other_type): return self.identifier == other_type.identifier
class _String(Type): pass class _Number(Type): pass
[docs]class Boolean(Type): name = _("Boolean") identifier = "boolean"
[docs] def get_field(self, **kwargs): return forms.BooleanField(**kwargs)
[docs]class Integer(_Number): name = _("Integer Number") identifier = "integer"
[docs] def get_field(self, **kwargs): return forms.IntegerField(**kwargs)
[docs]class Decimal(_Number): name = _("Decimal Number") identifier = "decimal"
[docs] def get_field(self, **kwargs): return forms.DecimalField(**kwargs)
[docs]class Text(_String): name = _("Text") identifier = "text"
[docs] def is_coercible_from(self, other_type): # All variables can be used as raw text return True
[docs]class Language(_String): name = _("Language") identifier = "language"
[docs]class Email(_String): name = _("Email Address") identifier = "email"
[docs] def get_field(self, **kwargs): return MultiEmailField(**kwargs)
[docs]class URL(_String): name = _("URL Address") identifier = "url"
[docs] def get_field(self, **kwargs): return forms.URLField(**kwargs)
[docs]class Phone(_String): name = _("Phone Number") identifier = "phone"
[docs]class Model(Type): model_label = None identifier = "model" @property def name(self): return self.get_model()._meta.verbose_name def __init__(self, model_label): """ :param model_label: Model label in Django `app.Model` format (e.g. `shuup.Order`). :type model_label: str """ self.model_label = model_label
[docs] def unserialize(self, value): if isinstance(value, self.get_model()): return value try: return self.get_model().objects.get(pk=value) except ObjectDoesNotExist: return None
[docs] def is_coercible_from(self, other_type): return isinstance(other_type, Model) and self.get_model() == other_type.get_model()
[docs] def get_model(self): """ :rtype: django.db.models.Model """ return apps.get_model(self.model_label)
[docs] def get_field(self, **kwargs): kwargs.setdefault("queryset", self.get_model().objects.all()) return forms.ModelChoiceField(**kwargs)
[docs]class Enum(Type): enum_class = None identifier = "enum" @property def name(self): if self.enum_class: return camel_case_to_spaces(self.enum_class.__class__.__name__) return "<Invalid Enum>" def __init__(self, enum_class): self.enum_class = enum_class assert issubclass(enum_class, enumfields.Enum), "%r is not an enum" % enum_class
[docs] def unserialize(self, value): if isinstance(value, self.enum_class): return value try: return self.enum_class(value) except ValueError: try: return self.enum_class(int(value)) except ValueError: pass return None
[docs] def get_field(self, **kwargs): return enumfields.EnumField(self.enum_class).formfield(**kwargs)