Пример #1
0
class UserAgreement(models.TimestampModel):
    tos = models.ForeignKey(
        TermsOfService,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='terms',
        verbose_name=_('tos'),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='user_agreements',
        verbose_name=_('user'),
    )

    class Meta:
        unique_together = ('user', 'tos')
        ordering = ["-created_at"]

    def __str__(self):
        return '%(user)s agreed to TermsOfService %(tos)s at %(when)s' % {
            'user': self.user.username,
            'tos': self.tos,
            'when': self.created_at,
        }
Пример #2
0
class UserAgreementOption(models.Model):
    parent = models.ForeignKey(
        UserAgreement,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='options',
        verbose_name=_('user agreement'),
    )
    option = models.ForeignKey(
        Option,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='user_agreements',
        verbose_name=_('user agreement'),
    )
    value = models.BooleanField(
        default=False,
        verbose_name=_('value'),
    )

    def __str__(self):
        return '%(version)s %(option)s: %(value)s' % {
            'version': self.parent.tos.version,
            'option': self.option,
            'value': self.value,
        }
Пример #3
0
class OptionTranslation(models.TranslationModel):
    parent = models.ForeignKey(
        Option,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='translations',
        verbose_name=_('option'),
    )
    label = models.TextField(verbose_name=_('label'), )
    description = models.TextField(
        null=True,
        blank=True,
        verbose_name=_('description'),
    )
    error_message = models.TextField(
        blank=True,
        default='',
        verbose_name=_('error message'),
    )

    class Meta:
        unique_together = ('parent', 'language')
        verbose_name = _('translation')
        verbose_name_plural = _('translations')

    def __str__(self):
        return "%s %s translation" % (self.language, self.parent)
Пример #4
0
class Email(models.Model):
    service = models.ForeignKey(
        Service,
        related_name="emails",
        verbose_name=_("service"),
    )
    name = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        verbose_name=_("name"),
    )
    email = models.EmailField(
        max_length=255,
        verbose_name=_("email"),
    )

    class Meta:
        unique_together = [("service", "email")]
        verbose_name = _("Service email")
        verbose_name_plural = _("Service email")

    def __str__(self):
        return _("Email for {name}: {email}").format(
            name=self.service.name,
            email=self.email,
        )
Пример #5
0
class AdministrativeArea(models.Model):
    """
    Administrative Area level 1 for a country.
    For the US, this would be the states.
    """
    status = models.StatusField(
        verbose_name=_('Area is active'),
    )
    country = models.ForeignKey(
        Country,
        related_name='administrative_areas',
    )
    name = models.CharField(
        max_length=60,
        db_index=True,
        verbose_name=_('Admin Area name'),
    )
    abbrev = models.CharField(
        max_length=3,
        blank=True,
        null=True,
        verbose_name=_('Postal Abbreviation'),
    )

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Administrative Area')
        verbose_name_plural = _('Administrative Areas')
        ordering = ('name',)
Пример #6
0
class CountryTranslation(models.TranslationModel):
    country = models.ForeignKey(
        Country,
        related_name='translations',
    )
    name = models.CharField(
        max_length=128,
        db_index=True,
        verbose_name=_('Official name (CAPS)'),
    )
    printable_name = models.CharField(
        max_length=128,
        db_index=True,
        verbose_name=_('Country name'),
    )

    class Meta:
        verbose_name = _('Country Name Translation')
        verbose_name_plural = _('Country Name Translations')
        unique_together = (('language', 'country',),)

    def __str__(self):
        return '%(translation)s (%(country)s)' % {
            'country': self.country.printable_name,
            'translation': self.printable_name,
        }
Пример #7
0
class CouponUser(models.TimestampModel):
    coupon = models.ForeignKey(
        Coupon,
        on_delete=models.CASCADE,
        related_name="users",
        verbose_name=_("Coupon"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_("User"),
    )
    redeemed_at = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Redeemed at"),
    )
    source_type = models.ForeignKey(
        models.ContentType,
        db_index=True,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        verbose_name=_("source content type"),
    )
    source_id = models.PositiveIntegerField(
        blank=True,
        null=True,
        verbose_name=_("source id"),
    )
    source = models.GenericForeignKey(
        "source_type", "source_id",
    )

    class Meta:
        verbose_name = _("Coupon")
        verbose_name_plural = _("Coupons")

    def __str__(self):
        return str(self.user)
Пример #8
0
class TermsOfServiceTranslation(models.TranslationModel):
    parent = models.ForeignKey(
        TermsOfService,
        db_index=True,
        on_delete=models.CASCADE,
        related_name='translations',
        verbose_name=_('TermsOfService'),
    )
    label = models.TextField(
        blank=True,
        default='',
        verbose_name=_('label'),
    )
    title = models.CharField(
        max_length=255,
        blank=True,
        default='',
        verbose_name=_('legal title'),
        help_text=_('legal tos title'),
    )
    text = models.TextField(
        blank=True,
        default='',
        verbose_name=_('legal text'),
        help_text=_('legal tos text'),
    )
    human_title = models.CharField(
        max_length=255,
        blank=True,
        default='',
        verbose_name=_('human title'),
        help_text=_('human readable tos title'),
    )
    human_text = models.TextField(
        blank=True,
        default='',
        verbose_name=_('human text'),
        help_text=_('human readable tos text'),
    )
    changelog = models.TextField(
        blank=True,
        default='',
        verbose_name=_('changelog'),
        help_text=_('difference(s) from previous version'),
    )

    class Meta:
        unique_together = (('language', 'parent'), ('human_title',
                                                    'human_text'))
        verbose_name = _('TermsOfService Translation')
        verbose_name_plural = _('TermsOfService Translations')

    def __str__(self):
        return self.title
Пример #9
0
class Attachment(models.Model):
    email = models.ForeignKey(Email,
                              on_delete=models.CASCADE,
                              related_name="attachments",
                              verbose_name=_("email"))
    filename = models.StringField(blank=True, verbose_name=_("filename"))
    content = models.BinaryField(null=True,
                                 blank=True,
                                 default=None,
                                 verbose_name=_("content"))
    mimetype = models.StringField(blank=True, verbose_name=_("mimetype"))

    class Meta:
        verbose_name = _("attachment")
        verbose_name_plural = _("attachments")
Пример #10
0
class FaqTranslation(PostModelTranslation):
    parent = models.ForeignKey(
        Faq,
        on_delete=models.CASCADE,
        related_name='translations',
        verbose_name=_('faq'),
    )

    class Meta:
        unique_together = (('parent', 'language'), ('title', 'slug'))
        verbose_name = _('faq translation')
        verbose_name_plural = _('faq translations')

    def __str__(self):
        return '%(parent)s [%(language)s]' % {
            'parent': self.parent,
            'language': self.language,
        }
Пример #11
0
class EmailTemplateTranslation(models.TranslationModel):
    parent = models.ForeignKey(
        EmailTemplate,
        on_delete=models.CASCADE,
        related_name="translations",
        verbose_name=_("parent"),
    )
    subject = models.StringField(verbose_name=_("subject"))
    body = models.TextField(verbose_name=_("body"))
    body_html = models.TextField(blank=True, verbose_name=_("body"))

    class Meta:
        unique_together = [("language", "parent")]
        verbose_name = _("mail translation")
        verbose_name_plural = _("mail translations")

    def __str__(self):
        return "%(name)s [%(lang)s]" % {
            "name": self.parent.name,
            "lang": self.language[:2],
        }
Пример #12
0
class CommentModel(models.TimestampModel):
    """
    A user comment about some object.
    """

    objects = CommentManager()

    site = models.ForeignKey(
        Site, default=get_current_site, on_delete=models.CASCADE, related_name="comments", verbose_name=_("site"),
    )
    parent = models.ForeignKey(
        "self",
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name="children",
        verbose_name=_("parent comment"),
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        related_name="%(app_label)s_%(class)s_comments",
        verbose_name=_("user"),
    )
    user_name = models.CharField(max_length=255, blank=True, verbose_name=_("user's name"))
    user_email = models.EmailField(max_length=255, blank=True, verbose_name=_("user's email address"))
    user_url = models.URLField(blank=True, verbose_name=_("user's URL"))

    comment = models.TextField(max_length=settings.MAX_LENGTH, verbose_name=_("comment"))

    notify_by_email = models.BooleanField(default=True, verbose_name=_("notify by email for updates"))

    ip_address = models.GenericIPAddressField(blank=True, null=True, verbose_name=_("IP address"))
    is_public = models.BooleanField(
        default=True,
        help_text=_("Uncheck this box to make the comment effectively disappear from the site."),
        verbose_name=_("is public"),
    )
    is_removed = models.BooleanField(
        default=False,
        help_text=_(
            "Check this box if the comment is inappropriate. A "
            '"This comment has been removed" message will be displayed instead.'
        ),
        verbose_name=_("is removed"),
    )

    class Meta:
        abstract = True
        ordering = ["created_at"]
        permissions = [("can_moderate", "Can moderate comments")]
        verbose_name = _("comment")
        verbose_name_plural = _("comments")

    def __str__(self):
        return "{name}: {comment}...".format(name=self.name, comment=self.comment[:50])

    @property
    def name(self):
        return self.userinfo["name"]

    @name.setter
    def name(self, val):
        if self.user_id:
            raise AttributeError(_("This comment was posted by an authenticated user and thus the name is read-only."))
        self.user_name = val

    @property
    def email(self):
        return self.userinfo["email"]

    @email.setter
    def email(self, val):
        if self.user_id:
            raise AttributeError(_("This comment was posted by an authenticated user and thus the email is read-only."))
        self.user_email = val

    @property
    def url(self):
        return self.userinfo["url"]

    @url.setter
    def url(self, val):
        self.user_url = val

    @property
    def userinfo(self):
        if not hasattr(self, "_userinfo"):
            userinfo = {"name": self.user_name, "email": self.user_email, "url": self.user_url}
            if self.user_id:
                u = self.user
                if u.email:
                    userinfo["email"] = u.email

                # If the user has a full name, use that for the user name.
                # However, a given user_name overrides the raw user.username,
                # so only use that if this comment has no associated name.
                if u.get_full_name():
                    userinfo["name"] = self.user.get_full_name()
                elif not self.user_name:
                    userinfo["name"] = u.get_username()
            self._userinfo = userinfo
        return self._userinfo
Пример #13
0
class Coupon(models.TimestampModel):
    Error = exceptions.CouponError
    ExpiredError = exceptions.CouponExpiredError
    IsUsableError = exceptions.CouponIsUsableError

    objects = CouponManager()

    value = models.IntegerField(
        verbose_name=_("Value"),
        help_text=_("Arbitrary coupon value"),
    )
    code = models.CharField(
        max_length=30,
        unique=True,
        blank=True,
        verbose_name=_("Code"),
        help_text=_("Leaving this field empty will generate a random code."),
    )
    type = models.CharField(
        choices=COUPON_TYPES,
        max_length=20,
        verbose_name=_("Type"),
    )
    action = models.CharField(
        choices=ACTION_TYPES,
        max_length=20,
        blank=True,
        default=DEFAULT_ACTION_TYPE,
        verbose_name=_("Action"),
    )
    user_limit = models.PositiveIntegerField(
        default=1,
        verbose_name=_("User limit"),
    )
    valid_from = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Valid from"),
        help_text=_("Coupons are valid from this date"),
    )
    valid_until = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Valid until"),
        help_text=_("Coupons expire at this date"),
    )
    campaign = models.ForeignKey(
        Campaign,
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        related_name="coupons",
        verbose_name=_("Campaign"),
    )

    class Meta:
        ordering = ["created_at"]
        verbose_name = _("Coupon")
        verbose_name_plural = _("Coupons")

    def __str__(self):
        return self.code

    def save(self, *args, **kwargs):
        if not self.code:
            self.code = Coupon.generate_code()
        super().save(*args, **kwargs)

    def expired(self):
        return self.is_expired

    @property
    def is_expired(self):
        return self.valid_until is not None and self.valid_until < timezone.now()

    @property
    def is_redeemed(self):
        """ Returns true is a coupon is redeemed (completely for all users) otherwise returns false. """
        return self.users.filter(
            redeemed_at__isnull=False
        ).count() >= self.user_limit and self.user_limit is not 0

    @property
    def redeemed_at(self):
        try:
            return self.users.filter(redeemed_at__isnull=False).order_by('redeemed_at').last().redeemed_at
        except self.users.through.DoesNotExist:
            return None

    @classmethod
    def generate_code(cls, prefix="", segmented=SEGMENTED_CODES, code_chars=CODE_CHARS, code_length=CODE_LENGTH):
        code = "".join(random.choice(code_chars) for i in range(code_length))
        if segmented:
            code = SEGMENT_SEPARATOR.join([code[i:i + SEGMENT_LENGTH] for i in range(0, len(code), SEGMENT_LENGTH)])
            return prefix + code
        else:
            return prefix + code

    @property
    def is_usable(self):
        user_limit = self.user_limit
        is_usable = -1 < CouponUser.objects.filter(coupon=self).count() < user_limit
        if is_usable:
            is_usable = self.do_is_usable_pipeline()
        return is_usable

    @transaction.atomic
    def redeem(self, user=None, source=None, **kwargs):
        if not self.is_usable:
            raise Coupon.IsUsableError()

        coupon_user = CouponUser(coupon=self, user=user)
        coupon_user.redeemed_at = timezone.now()
        if source is not None:
            coupon_user.source_type = models.ContentType.objects.get_for_model(source)
            coupon_user.source_id = source.pk

        coupon_user.save()

        self.do_redeem_pipeline(coupon_user=coupon_user, user=user, source=source, **kwargs)

        return coupon_user

    def do_is_usable_pipeline(self, **kwargs):
        coupon = self
        for name in getattr(settings, "COUPONS_IS_USABLE_PIPELINE", []):
            pipeline = import_string(name)
            coupon, is_usable = pipeline(coupon=coupon, **kwargs)
            if not is_usable:
                return False
        return True

    def do_redeem_pipeline(self, **kwargs):
        coupon = self
        for name in getattr(settings, "COUPONS_REDEEM_PIPELINE", []):
            pipeline = import_string(name)
            coupon = pipeline(coupon=coupon, **kwargs)
Пример #14
0
class PostModel(models.TimestampModel, models.OrderedModel, models.I18NModel):
    STATUS_DRAFT = "draft"
    STATUS_PUBLISHED = "published"
    STATUS_CHOICES = [
        (STATUS_DRAFT, _("Draft")),
        (STATUS_PUBLISHED, _("Published")),
    ]

    objects = PostModelManager()

    uuid = models.StringField(
        max_length=36,
        blank=True,
        verbose_name=_("uuid field"),
        help_text=_("for preview."),
    )
    status = models.StatusField(
        choices=STATUS_CHOICES,
        default=STATUS_DRAFT,
        help_text=_("If should be displayed or not."),
    )
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        related_name="%(app_label)s_%(class)s_owned",
        verbose_name=_("owned by"),
        help_text=_("Post owner."),
    )
    users = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        blank=True,
        related_name="%(app_label)s_%(class)s_visible",
        verbose_name=_("Visible only to"),
        help_text=_(
            "Post visible to these users, if empty is visible to all users."),
    )
    event_date = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Post date"),
        help_text=_("Date which post refers to."),
    )
    pub_date_begin = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Publication date begin"),
        help_text=_("When post publication date begins."),
    )
    pub_date_end = models.DateTimeField(
        blank=True,
        null=True,
        verbose_name=_("Publication date end"),
        help_text=_("When post publication date ends."),
    )
    title = models.StringField(unique=True, verbose_name=_("Title"))
    slug = models.SlugField(unique=True, verbose_name=_("Slug field"))
    abstract = models.TextField(
        blank=True,
        verbose_name=_("Abstract"),
        help_text=_("A brief description of the post"),
    )
    text = models.TextField(blank=True, verbose_name=_("Default text"))
    note = models.TextField(blank=True, verbose_name=_("Note"))

    class Meta:
        abstract = True
        unique_together = [("title", "slug")]

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        now = timezone.now()
        if not self.event_date and self.status == PostModel.STATUS_PUBLISHED:
            self.event_date = now
        if not self.pub_date_begin and self.status == PostModel.STATUS_PUBLISHED:
            self.pub_date_begin = now
        if not self.uuid:
            self.uuid = uuid1()
        super().save(*args, **kwargs)

    @property
    def next(self):
        return (self._meta.model.objects.filter(
            status=self.status,
            pub_date_begin__gt=self.pub_date_begin).order_by(
                "pub_date_begin").first())

    @property
    def prev(self):
        return (self._meta.model.objects.filter(
            status=self.status,
            pub_date_begin__lt=self.pub_date_begin).order_by(
                "pub_date_begin").first())
Пример #15
0
class Log(models.Model):
    NOTSET = "notset"
    DEBUG = "debug"
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"

    objects = LogManager()

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        blank=True,
        null=True,
        verbose_name=_("user"),
    )
    timestamp = models.CreationDateTimeField(
        null=True,
        blank=True,
        verbose_name=_("timestamp"),
    )
    level = models.CharField(
        max_length=255,
        default=NOTSET,
        choices=(
            (NOTSET, _("Not set")),
            (DEBUG, _("Debug")),
            (INFO, _("Info")),
            (WARNING, _("Warning")),
            (ERROR, _("Error")),
            (CRITICAL, _("Critical")),
        ),
        verbose_name=_("level"),
    )
    content_type = models.ForeignKey(
        ContentType,
        blank=True,
        null=True,
        verbose_name=_("content type"),
    )
    object_id = models.TextField(
        default="",
        blank=True,
        #null=True,
        verbose_name=_("object id"),
    )
    object_repr = models.CharField(
        max_length=255,
        default="",
        blank=True,
        verbose_name=_("object repr"),
    )
    message = models.TextField(
        default="",
        blank=True,
        verbose_name=_("message"),
    )
    realm = models.TextField(
        blank=True,
        null=True,
        verbose_name=_("realm"),
        help_text=_("realm"),
    )

    class Meta:
        ordering = ["-timestamp"]
        verbose_name = _("log")
        verbose_name_plural = _("logs")

    def __str__(self):
        msg = ugettext("{timestamp} {level} {message}")
        return msg.format(
            timestamp=self.timestamp,
            level=self.level,
            message=self.message[:255],
        )