Ejemplo n.º 1
0
class MatchAvailability(models.Model):
    """ Represents a member's availability (either playing or umpiring) for a specific match """

    member = models.ForeignKey(Member,
                               on_delete=models.CASCADE,
                               related_name="availabilities")
    """ The member that this availability relates to """

    match = models.ForeignKey(Match,
                              on_delete=models.CASCADE,
                              related_name="availabilities")
    """ The match that this availability relates to """

    playing_availability = models.CharField(choices=AVAILABILITY,
                                            max_length=20,
                                            null=True,
                                            blank=True)
    """ The member's availability to play this match """

    umpiring_availability = models.CharField(choices=AVAILABILITY,
                                             max_length=20,
                                             null=True,
                                             blank=True)
    """ The member's availability to umpire this match """

    comment = models.TextField(
        null=True,
        blank=True,
        help_text="Any additional details about this availability")

    playing_availability_changed = MonitorField(monitor='playing_availability')
    """ Automatically updated to the current datetime when the playing availability field is changed """

    umpiring_availability_changed = MonitorField(
        monitor='umpiring_availability')
    """ Automatically updated to the current datetime when the umpiring availability field is changed """

    objects = MatchAvailabilityQuerySet.as_manager()

    class Meta:
        """ Meta-info on the MatchAvailability model."""
        app_label = 'availability'
        verbose_name_plural = 'match availabilities'

    def clean(self):
        if self.playing_availability == AVAILABILITY.available and self.umpiring_availability == AVAILABILITY.available:
            raise ValidationError("You cannot play and umpire the same match!")

    def __str__(self):
        return "{} - {}".format(self.member, self.match)

    @property
    def can_play(self):
        """ Returns true if the member can play this match """
        return self.playing_availability == AVAILABILITY.available

    @property
    def can_umpire(self):
        """ Returns true if the member can umpire this match """
        return self.umpiring_availability == AVAILABILITY.available
Ejemplo n.º 2
0
class EmailMessage(Base):

    STATUS = Choices(_('Created'), _('Scheduled'), _('Sent'), _('Opened'),
                     _('Clicked'))
    status = StatusField(verbose_name=_('Status'))

    widget = models.ForeignKey('widgets.Widget', null=True)
    leed = models.ForeignKey('widgets.Leed', null=True)

    subject = models.CharField(max_length=50, null=True)
    text = models.CharField(max_length=500, null=True)
    html = models.CharField(max_length=1000, null=True)

    status_changed = MonitorField(monitor='status')

    scheduled_at = MonitorField(monitor='status',
                                when=['Sent'],
                                verbose_name=_('Email scheduled at'))
    sent_at = MonitorField(monitor='status',
                           when=['Scheduled'],
                           verbose_name=_('Email sent at'))
    opened_at = MonitorField(monitor='status',
                             when=['Opened'],
                             verbose_name=_('Email opened at'))
    clicked_at = MonitorField(monitor='status',
                              when=['Clicked'],
                              verbose_name=_('Email clicked at'))

    def get_absolute_url(self):
        return reverse('widgets:email_detail', kwargs={'pk': self.pk})
Ejemplo n.º 3
0
class StudentsWork(TimeStampedModel):

    courseevent = models.ForeignKey(CourseEvent)
    workers = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                     verbose_name="Team",
                                     related_name='teammembers')
    homework = models.ForeignKey(ClassLesson,
                                 verbose_name="Aufgabe")

    title = models.CharField(
        verbose_name="Titel",
        max_length=100)
    text = models.TextField(
        verbose_name="Text")
    comments = models.TextField(
        verbose_name="Kommentare",
        blank=True)
    feedback_spice = enum.EnumField(FeedbackSpice, default=FeedbackSpice.MEDIUM)
    published = models.BooleanField(verbose_name="veröffentlichen", default=False)
    published_at = MonitorField(monitor='published', when=[True])

    publish_count = models.IntegerField(default=0)
    republished_at = MonitorField(monitor='publish_count')

    objects = StudentsWorkManager()

    class Meta:
        verbose_name = _("Teilnehmer-Arbeit")
        verbose_name_plural = _("Teilnehmer-Arbeiten")

    def __unicode__(self):
        return self.title

    def team(self):
        """
        Returns all the accounts of users who are students in the courseevent
        """
        return self.workers.all().order_by('username').prefetch_related('teammembers')

    def team_display(self):
        """
        Returns all the accounts of users who are students in the courseevent
        """
        teachers = self.team
        namesstring = ""
        for worker in self.workers.all():
            if namesstring != "":
                namesstring += ", "
            namesstring += worker.get_full_name()
        return namesstring

    def workers_emails(self):
        return self.workers.all().values_list('email', flat=True, )

    def comment_count(self):
        return Comment.objects.filter(studentswork=self).count()

    def team_size(self):
        return self.team.count()
Ejemplo n.º 4
0
class Mesa(models.Model):
    ESTADOS_ = ('EN ESPERA', 'ABIERTA', 'CERRADA', 'ESCRUTADA')
    ESTADOS = Choices(*ESTADOS_)
    estado = StatusField(choices_name='ESTADOS', default='EN ESPERA')
    hora_abierta = MonitorField(monitor='estado', when=['ABIERTA'])
    hora_cerrada = MonitorField(monitor='estado', when=['CERRADA'])
    hora_escrutada = MonitorField(monitor='estado', when=['ESCRUTADA'])

    eleccion = models.ForeignKey('Eleccion')
    numero = models.PositiveIntegerField()
    es_testigo = models.BooleanField(default=False)
    circuito = models.ForeignKey(Circuito)  #
    lugar_votacion = models.ForeignKey(LugarVotacion,
                                       verbose_name='Lugar de votacion',
                                       null=True,
                                       related_name='mesas')
    url = models.URLField(blank=True, help_text='url al telegrama')
    foto_del_acta = models.ImageField(upload_to=path_foto_acta,
                                      null=True,
                                      blank=True)
    electores = models.PositiveIntegerField(null=True, blank=True)
    taken = models.DateTimeField(null=True)

    def get_absolute_url(self):
        return reverse('detalle-mesa', args=(
            self.eleccion.id,
            self.numero,
        ))

    @property
    def asignacion_actual(self):
        return self.asignacion.order_by('-ingreso').last()

    @property
    def computados(self):
        return self.votomesaoficial_set.aggregate(Sum('votos'))['votos__sum']

    @property
    def tiene_reporte(self):
        return self.votomesareportado_set.aggregate(Sum('votos'))['votos__sum']

    @property
    def foto_o_attachment(self):
        from adjuntos.models import Attachment
        try:
            return self.foto_del_acta or self.attachment.file
        except Attachment.DoesNotExist:
            return None

    @property
    def proximo_estado(self):
        if self.estado == 'ESCRUTADA':
            return self.estado
        pos = Mesa.ESTADOS_.index(self.estado)
        return Mesa.ESTADOS_[pos + 1]

    def __str__(self):
        return f"Mesa {self.numero}"
Ejemplo n.º 5
0
class Command(TimeStampedModel):
    STATUS = Choices(
        (0, 'created', 'Created'),
        (1, 'sent', 'Sent'),
        (2, 'completed', 'Completed'),
        (3, 'error', 'Error'),
    )
    COMMAND_TYPES = Choices(
        (0, 'change_setting', 'Change Setting'),
        (1, 'launch_payload', 'Launch Payload'),
        (2, 'uninstall', 'Uninstall'),
    )

    implant = models.ForeignKey(Implant)
    uuid = UUIDField(auto=True)
    status = models.IntegerField(choices=STATUS, default=STATUS.created)
    sent_at = MonitorField(monitor='status',
                           when=[STATUS.sent],
                           blank=True,
                           null=True)
    resolved_at = MonitorField(monitor='status',
                               when=[STATUS.completed, STATUS.error],
                               blank=True,
                               null=True)

    command_type = models.IntegerField(choices=COMMAND_TYPES)
    argument = models.TextField(blank=True)

    def __unicode__(self):
        return '{command} for {implant}'.format(
            command=self.get_command_type_display(), implant=self.implant)

    def mark_sent(self):
        logger.info(
            'Command {uuid} ({implant} - {type}) marked as sent'.format(
                uuid=self.uuid,
                implant=self.implant,
                type=self.get_command_type_display()))
        self.status = self.STATUS.sent
        self.save()

    def resolve(self, error=False):
        if error:
            self.status = self.STATUS.error
            logger.info(
                'Command {uuid} ({implant} - {type}) marked as error'.format(
                    uuid=self.uuid,
                    implant=self.implant,
                    type=self.get_command_type_display()))
        else:
            self.status = self.STATUS.completed
            logger.info(
                'Command {uuid} ({implant} - {type}) marked as completed'.
                format(uuid=self.uuid,
                       implant=self.implant,
                       type=self.get_command_type_display()))
        self.save()
Ejemplo n.º 6
0
class Course(TimeStampedModel):
    STATUS = Choices((0, "writing", "writing"), (1, "finished", "finished"),)
    LEVEL = Choices(
        (0, "introductory", "入门"), (1, "intermediate", "进阶"), (2, "advanced", "高级"),
    )

    title = models.CharField(_("title"), max_length=150)
    slug = models.SlugField(_("slug"), unique=True)
    description = models.TextField(_("description"), blank=True)
    brief = models.CharField(_("brief"), max_length=200, blank=True)
    cover = models.ImageField(_("cover"), upload_to="courses/covers/")
    cover_thumbnail = ImageSpecField(
        source="cover",
        format="JPEG",
        processors=[ResizeToFill(540, 300)],
        options={"quality": 90},
    )
    cover_caption = models.CharField(_("cover_caption"), max_length=100, blank=True)
    status = models.IntegerField(_("status"), choices=STATUS, default=STATUS.writing)
    status_changed = MonitorField(_("status_changed"), monitor="status")
    level = models.IntegerField(_("level"), choices=LEVEL, default=LEVEL.introductory)
    level_changed = MonitorField(_("level_changed"), monitor="level")
    rank = models.IntegerField(_("rank"), default=0)

    creator = models.ForeignKey(
        settings.AUTH_USER_MODEL, verbose_name=_("creator"), on_delete=models.CASCADE
    )
    category = models.ForeignKey(
        Category,
        verbose_name=_("category"),
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )

    class Meta:
        ordering = ("rank", "-created")
        verbose_name = _("course")
        verbose_name_plural = _("courses")

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("courses:course_detail", kwargs={"slug": self.slug})

    @cached_property
    def first_material(self):
        return self.material_set.order_by("rank", "created").first()

    @cached_property
    def rich_content(self):
        return generate_rich_content(self.description)
Ejemplo n.º 7
0
class CourseEventParticipation(TimeStampedModel):

    courseevent = models.ForeignKey(CourseEvent)
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    hidden = models.BooleanField(verbose_name=_('versteckt'), default=False)
    hidden_status_changed = MonitorField(monitor='hidden')
    notification_forum = enum.EnumField(NotificationSettings,
                                        default=NotificationSettings.ALL)
    notification_work = enum.EnumField(NotificationSettings,
                                       default=NotificationSettings.ALL)

    objects = ParticipationManager()

    class Meta:
        verbose_name = _("Kurs-Teilnehmer")
        verbose_name_plural = _("Kurs-Teilnehmer")
        unique_together = ('user', 'courseevent')

    def __unicode__(self):
        return u'%s / %s' % (self.courseevent, self.user)

    @cached_property
    def course(self):
        return self.courseevent.course

    def hide(self):
        self.hidden = True
        self.save()

    def unhide(self):
        self.hidden = False
        self.save()
Ejemplo n.º 8
0
class Fragment(Commentable, Votable, models.Model):
    STATUS = Choices('OPEN', 'CLOSED')

    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
    )
    title = models.CharField(max_length=256)
    content = models.CharField(max_length=2048)
    tags = models.ManyToManyField(Tag)
    status = StatusField(choices=STATUS, default=STATUS.OPEN)
    date_created = models.DateTimeField(auto_now_add=True, editable=False)
    date_modified = models.DateTimeField(auto_now=True, editable=False)
    date_closed = MonitorField(monitor='status',
                               when=[STATUS.CLOSED],
                               default=None,
                               null=True,
                               blank=True,
                               editable=False)

    def __str__(self):
        return f"{ self.pk } { self.title[:10] if len(self.title) > 10 else self.title }"

    def get_answer_count(self):
        return self.answer_set.count()
Ejemplo n.º 9
0
class Task(Uuidable, Orderable, Authorable, models.Model):
    name = models.CharField(_("nombre"), max_length=2000, blank=False)
    user_story = models.ForeignKey(
        UserStory,
        verbose_name=_("historia de usuario"),
        related_name="tasks",
        blank=False,
        null=False,
        on_delete=models.CASCADE,
    )
    weight = models.PositiveSmallIntegerField(
        _("peso"),
        blank=False,
        null=False,
        default=1,
        validators=[MinValueValidator(1)])
    done = models.BooleanField(_("finalizada"), default=False)
    done_changed = MonitorField(_("último cambio en finalizada"),
                                monitor="done")

    order_with_respect_to = ("user_story", )

    def __str__(self):
        return f"{self.user_story} / {self.order}.{self.name} / {self.done}"

    class Meta(Orderable.Meta):
        verbose_name = _("tarea")
        verbose_name_plural = _("tareas")
        constraints = [
            models.UniqueConstraint(fields=["name", "user_story"],
                                    name="unique_task")
        ]
Ejemplo n.º 10
0
class ExporterChunk(TimeStampedModel):
    STATUS_CHOICES = Choices(("created", _("created")),
                             ("processing", _("processing")),
                             ("success", _("success")), ("error", _("error")))

    exporter = models.ForeignKey(Exporter, related_name="chunks")
    page = models.IntegerField()
    file = models.FileField(blank=True,
                            null=True,
                            default=None,
                            storage=default_storage)
    status = models.CharField(max_length=16,
                              choices=STATUS_CHOICES,
                              default=STATUS_CHOICES.created)
    done_at = MonitorField(monitor='status',
                           when=['success', 'error'],
                           default=None,
                           null=True)

    objects = ExporterChunkManager()

    def set_status(self, status):
        """ Sets the status to one of the choices """
        if status not in self.STATUS_CHOICES:
            raise ExporterStatusException("Invalid status.")

        self.status = status
        self.save()
Ejemplo n.º 11
0
class Product(TimeStampedModel):

    description = FroalaField(blank=True)

    # price with currency
    price = models.DecimalField(max_digits=12,
                                decimal_places=2,
                                null=True,
                                blank=True,
                                verbose_name=_('Verkaufspreis'))
    currency = enum.EnumField(Currency, default=Currency.EUR)
    price_changed = MonitorField(monitor='price',
                                 verbose_name=_("letzte Preisänderung am"))

    display_nr = models.IntegerField(default=1)

    # product type
    product_type = enum.EnumField(Producttype, default=Producttype.OTHER)

    objects = ProductManager()

    class Meta:
        abstract = True

    def __unicode__(self):
        return "%s: %s" % (self.name)
Ejemplo n.º 12
0
class StatusModel(models.Model):
    """
    An abstract base class model with a ``status`` field that
    automatically uses a ``STATUS`` class attribute of choices, a
    ``status_changed`` date-time field that records when ``status``
    was last modified, and an automatically-added manager for each
    status that returns objects with that status only.

    """
    status = StatusField(_('status'))
    status_changed = MonitorField(_('status changed'), monitor='status')

    def save(self, *args, **kwargs):
        """
        Overriding the save method in order to make sure that
        status_changed field is updated even if it is not given as
        a parameter to the update field argument.
        """
        if ('update_fields' in kwargs and 'status' in kwargs['update_fields']
                and 'status_changed' not in kwargs['update_fields']):
            kwargs['update_fields'] += ['status_changed']
        super().save(*args, **kwargs)

    class Meta:
        abstract = True
Ejemplo n.º 13
0
class SubjectTaskStatusModel(StatusModel):
    """Abstract class that tracks the various states a subject might
    be in relation to either an experiment or a battery"""

    STATUS = Choices("not-started", "started", "completed", "failed")
    status = StatusField(default="not-started")
    started_at = MonitorField(monitor="status", when=["started"])
    completed_at = MonitorField(monitor="status", when=["completed"])
    failed_at = MonitorField(monitor="status", when=["failed"])

    @property
    def completed(self):
        return self.status == self.STATUS.completed

    class Meta:
        abstract = True
class Organization(DjangoOrganization, TimeStampedModel):
    # Stripe data
    subscription_stripe_customer_id = models.CharField(max_length=255, default="")
    subscription_stripe_checkout_session_id = models.CharField(
        max_length=255, default=""
    )
    subscription_stripe_subscription_id = models.CharField(max_length=255, default="")

    # Subscription data
    SUBSCRIPTION_CHOICES = Choices("free", "basic")
    subscription_type = StatusField(choices_name="SUBSCRIPTION_CHOICES", default="free")
    # Differs from the creation date of the organization, tracks when the subscription is changed
    subscription_date = MonitorField(monitor="subscription_type")

    # Organization data
    contact_email = models.EmailField(max_length=254, unique=True)
    description = models.TextField()
    currency = models.CharField(
        choices=CURRENCY_CHOICES, default=CURRENCY_CHOICES.euro, max_length=255
    )

    @property
    def stats(self):
        # TODO: fix circulair import
        # To prevent a circular import reference, we import these here
        from organization.models.inventory import Product, Location, Mutation

        return {
            "product_count": Product.objects.for_organization(self).count(),
            "location_count": Location.objects.for_organization(self).count(),
            "mutation_count": Mutation.objects.for_organization(self).count(),
        }

    def __str__(self):
        return self.name
Ejemplo n.º 15
0
class User(AbstractUser):
    HAPPINESS_CHOICES = Choices(
        (1, "Unhappy", _("Unhappy")),
        (3, "Neutral", _("Neutral")),
        (5, "Very Happy", _("Very Happy")),
    )

    # First Name and Last Name do not cover name patterns around the globe
    name = CharField(_("Name of User"), blank=True, max_length=255)
    timezone = TimeZoneField(_("Timezone of User"), blank=True, default="UTC")
    happiness_level = IntegerField(choices=HAPPINESS_CHOICES,
                                   default=HAPPINESS_CHOICES.Neutral)
    happiness_level_changed = MonitorField(monitor="happiness_level",
                                           blank=True,
                                           null=True)
    team = ForeignKey("users.Team", on_delete=SET_NULL, blank=True, null=True)

    def __str__(self):
        return f"{self.username} ({self.id})"

    def get_absolute_url(self):
        return reverse("users:detail", kwargs={"username": self.username})

    @property
    def can_change_happiness_level(self):
        if not self.happiness_level_changed:
            return
        user_tz_now = datetime.now(self.timezone)
        return user_tz_now - self.happiness_level_changed > timedelta(days=1)
Ejemplo n.º 16
0
class TrainingResult(models.Model):
    """Training result information obtained once deployed a model"""

    STATUS = Choices('created', 'deployed', 'stopped', 'finished')
    """Sets its default value to the first item in the STATUS choices:"""
    status = StatusField()
    status_changed = MonitorField(monitor='status')
    deployment = models.ForeignKey(Deployment,
                                   default=None,
                                   related_name='results',
                                   on_delete=models.CASCADE)
    model = models.ForeignKey(MLModel,
                              related_name='trained',
                              on_delete=models.CASCADE)
    train_loss = models.DecimalField(max_digits=15,
                                     decimal_places=10,
                                     blank=True,
                                     null=True)
    train_metrics = models.TextField(blank=True)
    val_loss = models.DecimalField(max_digits=15,
                                   decimal_places=10,
                                   blank=True,
                                   null=True)
    val_metrics = models.TextField(blank=True)
    trained_model = models.FileField(upload_to=settings.TRAINED_MODELS_DIR,
                                     blank=True)

    class Meta(object):
        ordering = ('-status_changed', )
Ejemplo n.º 17
0
class Inference(models.Model):
    """Training result information obtained once deployed a model"""
    INPUT_FORMAT = Choices('RAW', 'AVRO')
    STATUS = Choices('deployed', 'stopped')
    """Sets its default value to the first item in the STATUS choices:"""

    status = StatusField()
    status_changed = MonitorField(monitor='status')
    model_result = models.ForeignKey(TrainingResult,
                                     null=True,
                                     related_name='inferences',
                                     on_delete=models.SET_NULL)
    replicas = models.IntegerField(default=1)
    input_format = StatusField(choices_name='INPUT_FORMAT')
    input_config = models.TextField(blank=True)
    input_topic = models.TextField(blank=True)
    output_topic = models.TextField(blank=True)
    time = models.DateTimeField(default=now, editable=False)
    limit = models.DecimalField(max_digits=15,
                                decimal_places=10,
                                blank=True,
                                null=True)
    output_upper = models.TextField(blank=True)

    class Meta(object):
        ordering = ('-time', )
Ejemplo n.º 18
0
class Exporter(TimeStampedModel):
    """ Exporter model handles the initial creation of the exportation. All the info needed for the exportation comes
    from here  """

    STATUS_CHOICES = Choices(("created", _("created")),
                             ("processing", _("processing")),
                             ("done", _("done")), ("error", _("error")))

    uuid = models.UUIDField(default=uuid4)
    email = models.EmailField()
    content_type = models.ForeignKey(ContentType)
    query = models.FileField(blank=True,
                             null=True,
                             default=None,
                             storage=default_storage)
    attrs = jsonfield.JSONField(blank=True, null=True, default=None)
    limit_per_task = models.IntegerField(default=100)
    total = models.IntegerField(editable=False)
    file = models.FileField(blank=True,
                            null=True,
                            default=None,
                            storage=default_storage)
    status = models.CharField(max_length=16,
                              choices=STATUS_CHOICES,
                              default=STATUS_CHOICES.created)
    done_at = MonitorField(monitor='status',
                           when=['done', 'error'],
                           default=None,
                           null=True)

    objects = ExporterManager()

    def set_status(self, status):
        """ Sets the status to one of the status choices """
        if status not in self.STATUS_CHOICES:
            raise ExporterStatusException("Invalid status.")

        self.status = status
        self.save()

    @property
    def chunks_is_successful(self):
        """ Check if its chunks are completed succesful """
        return self.chunks.filter(status=ExporterChunk.STATUS_CHOICES.success
                                  ).count() == self.chunks.all().count()

    @property
    def has_chunk_errors(self):
        """ Check if any of the created chunks have returned errors """
        return self.chunks.filter(
            status=ExporterChunk.STATUS_CHOICES.error).exists()

    @property
    def is_pending(self):
        """ Check if it is pending """
        return self.status == self.STATUS_CHOICES.processing

    @property
    def is_done(self):
        return self.status == self.STATUS_CHOICES.done
Ejemplo n.º 19
0
class Feedback(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             help_text=_("Author"),
                             null=True)
    text = models.TextField(verbose_name=_("Comment"),
                            help_text=_("Text reported by user"))
    status = models.BooleanField(default=False,
                                 verbose_name=_("Status"),
                                 help_text=_("Feedback has been served"))
    status_changed = MonitorField(monitor='status',
                                  verbose_name=_("Status change date"))
    created = models.DateTimeField(auto_now_add=True,
                                   verbose_name=_("Creation date"))

    def get_status_display(self):
        return _('open') if self.status else _('closed')

    def __unicode__(self):
        return str(self.created)

    def get_absolute_url(self):
        return reverse("tasty_feedback:details", kwargs={'pk': str(self.pk)})

    def get_github_link(self):
        if hasattr(settings, 'FEEDBACK_GITHUB_REPO'):
            body = quote(githubify(self.text).encode('utf-8'))
            return "%s/issues/new?body=%s" % (settings.FEEDBACK_GITHUB_REPO,
                                              body)
        return

    class Meta:
        verbose_name = _("Feedback")
        verbose_name_plural = _("Feedbacks")
Ejemplo n.º 20
0
class StatusModel(models.Model):
    """
    An abstract base class model with a ``status`` field that
    automatically uses a ``STATUS`` class attribute of choices, a
    ``status_changed`` date-time field that records when ``status``
    was last modified, and an automatically-added manager for each
    status that returns objects with that status only.

    """

    status = StatusField(_("status"))
    status_changed = MonitorField(_("status changed"), monitor="status")

    def save(self, *args, **kwargs):
        """
        Overriding the save method in order to make sure that
        status_changed field is updated even if it is not given as
        a parameter to the update field argument.
        """
        update_fields = kwargs.get("update_fields", None)
        if update_fields and "status" in update_fields:
            kwargs["update_fields"] = set(update_fields).union(
                {"status_changed"})

        super().save(*args, **kwargs)

    class Meta:
        abstract = True
Ejemplo n.º 21
0
class Marca(models.Model):
    """
    Es el marca comercial de un producto.
    Ejemplo: Rosamonte
    """
    fabricante = models.ForeignKey('EmpresaFabricante', null=True, blank=True)
    nombre = models.CharField(max_length=100,
                              unique=True,
                              verbose_name=u"Nombre de la marca")
    logo = ImageCropField(null=True, blank=True, upload_to='marcas')

    # size is "width x height"
    logo_cropped = ImageRatioField('logo',
                                   '150x125',
                                   verbose_name=u'Recortar logo',
                                   free_crop=True)
    logo_changed = MonitorField(monitor='logo', editable=False)

    def __unicode__(self):
        return self.nombre

    class Meta:
        unique_together = (('nombre', 'fabricante'))
        verbose_name = u"marca"
        verbose_name_plural = u"marcas"
Ejemplo n.º 22
0
class Material(AbstractEntry):
    STATUS = Choices(
        (0, "writing", "writing"),
        (1, "draft", "draft"),
        (2, "published", "published"),
        (3, "hidden", "hidden"),
    )

    status = models.IntegerField(_("status"), choices=STATUS, default=STATUS.draft)
    status_changed = MonitorField(_("status_changed"), monitor="status")
    cover = models.ImageField(_("cover"), upload_to="covers/materials/", blank=True)
    cover_thumbnail = ImageSpecField(
        source="cover",
        format="JPEG",
        processors=[ResizeToFill(60, 60)],
        options={"quality": 90},
    )
    cover_caption = models.CharField(_("cover_caption"), max_length=100, blank=True)
    rank = models.IntegerField(_("rank"), default=0)
    course = models.ForeignKey(
        Course, verbose_name=_("course"), on_delete=models.CASCADE
    )

    objects = MaterialManager()
    index = IndexMaterialManager()

    class Meta:
        ordering = ["rank", "created"]
        verbose_name = _("material")
        verbose_name_plural = _("materials")

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse(
            "courses:material_detail", kwargs={"pk": self.pk, "slug": self.course.slug}
        )

    @property
    def type(self):
        return "m"

    @cached_property
    def prev(self):
        return self.get_next_or_previous(
            is_next=False,
            value_fields=["id", "title", "course__slug"],
            course_id=self.course_id,
        )

    @cached_property
    def next(self):
        return self.get_next_or_previous(
            is_next=True,
            value_fields=["id", "title", "course__slug"],
            course_id=self.course_id,
        )
Ejemplo n.º 23
0
class BasicContentModel(TimeStampedModel):
    """
    内容基类,包含功能:
        created, modified
        status 默认:0 draft, 1 published
        is_removed: 软删除标记
    Demo1: find list
       draft_books = Book.draft.all()
       published_books = Book.published.all()
       not_deleted_books = Book.objects.all()
       all_books = Book.all_objects.all()
    Demo2: status change
       book.status = Book.STATUS.draft
       book.status = Book.STATUS.published
    Demo3: status_display
        status_display = Article.STATUS[article.status]
    注意:
        1. 子类如果需要替换objects,自定义的Manager需要继承BasicContentManager
        2. track=FieldTracker 不能在基类中定义,需要在子类中实现时定义:
        https://django-model-utils.readthedocs.io/en/latest/utilities.html#field-tracker
    """

    STATUS = Choices((0, "draft", _("草稿")), (1, "published", _("已发布")))

    status = models.IntegerField(choices=STATUS, default=STATUS.draft)
    status_changed = MonitorField(_("status changed"), monitor="status")
    is_removed = models.BooleanField(default=False)

    def delete(self, using=None, soft=True, *args, **kwargs):
        """
        Soft delete object (set its ``is_removed`` field to True).
        Actually delete object if setting ``soft`` to False.
        """
        if soft:
            self.is_removed = True
            self.save(using=using)
        else:
            return super().delete(using=using, *args, **kwargs)

    objects = BasicContentManager()
    all_objects = models.Manager()

    def save(self, *args, **kwargs):
        """
        Overriding the save method in order to make sure that
        status_changed field is updated even if it is not given as
        a parameter to the update field argument.
        """
        update_fields = kwargs.get("update_fields", None)
        if update_fields and "status" in update_fields:
            kwargs["update_fields"] = set(update_fields).union(
                {"status_changed"})

        super().save(*args, **kwargs)

    class Meta:
        abstract = True
Ejemplo n.º 24
0
class Comment(models.Model):
    STATUS = Choices("name", "email", "address")
    name = models.CharField(max_length=100)
    email = models.EmailField(max_length=30)
    address = models.CharField(max_length=40)

    status = StatusField()
    published_at = MonitorField(monitor='status',
                                when=['name', "email", "address"])
Ejemplo n.º 25
0
class Url(TimeStampedModel):
    '''
    Url model

    shortcode -> str pk 
    url -> str 
    redirect_count -> int:  amount of redirect calls
    last_redirect -> datetime: last redirect timestamp

    created -> datetime
    modified -> datetime
    '''

    shortcode = models.CharField(
        _('shorcode'),
        primary_key=True,
        max_length=6,
        help_text=_('url shortname'),
        validators=[
            RegexValidator(
                regex=r'^[a-z0-9_]{6}',
                message=_(REGEX_VALIDATOR_MSG),
                code='invalid shortcode',
            ),
        ],
    )
    url = models.CharField(_('url'),
                           max_length=256,
                           validators=[URLValidator()])
    _redirect_count = models.IntegerField(
        default=0, help_text=_('Number of times shortcode has been retreived'))
    last_redirect = MonitorField(monitor='redirect_count')

    objects = UrlManager()

    @property
    def redirect_count(self) -> int:
        return self._redirect_count

    def increment_redirect_count(self) -> None:
        """
        increment redirect count by one.
        :return :type Url
        """
        self._redirect_count += 1
        self.save()

    class Meta:
        ordering: Tuple[str] = ('created', 'modified')

    def __str__(self) -> str:
        return self.url

    def __repr__(self) -> str:
        return f'<{self.__class__.__name__}({self.__str__()!r})>'
Ejemplo n.º 26
0
class ForumContributionModel(TimeStampedModel):

    courseevent = models.ForeignKey(CourseEvent)

    hidden = models.BooleanField(verbose_name=_('versteckt'), default=False)
    hidden_status_changed = MonitorField(monitor='hidden')

    text = models.TextField()

    class Meta:
        abstract = True
Ejemplo n.º 27
0
class JoinRequest(TimeStampedModel):
    class Status(models.TextChoices):
        PENDING = "pending", _("Pending")
        ACCEPTED = "accepted", _("Accepted")
        REJECTED = "rejected", _("Rejected")

    community = models.ForeignKey(Community, on_delete=models.CASCADE)

    sender = models.ForeignKey(settings.AUTH_USER_MODEL,
                               on_delete=models.CASCADE)

    status = models.CharField(max_length=100,
                              choices=Status.choices,
                              default=Status.PENDING,
                              db_index=True)
    status_changed = MonitorField(monitor="status")

    sent = models.DateTimeField(null=True, blank=True)

    intro = models.TextField(
        blank=True,
        verbose_name=_("Introduction"),
        help_text=_("Tell us a little bit about yourself and why you "
                    "would like to join this community (Optional)."),
    )

    objects = JoinRequestQuerySet.as_manager()

    class Meta:
        unique_together = ("community", "sender")
        indexes = [models.Index(fields=["status"])]

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

    def get_absolute_url(self):
        return reverse("join_requests:detail", args=[self.id])

    def is_pending(self):
        return self.status == self.Status.PENDING

    def is_accepted(self):
        return self.status == self.Status.ACCEPTED

    def is_rejected(self):
        return self.status == self.Status.REJECTED

    def accept(self):
        self.status = JoinRequest.Status.ACCEPTED
        self.save()

    def reject(self):
        self.status = JoinRequest.Status.REJECTED
        self.save()
class ConversionQueueItem(models.Model):
    """Represents an item in the conversion queue."""
    url = models.ForeignKey(
        Version,
        null=False,
        verbose_name='URL',
        on_delete=models.CASCADE,
    )

    file = models.CharField(max_length=4096, verbose_name='Fil')
    type = models.CharField(max_length=256, verbose_name='Type')
    page_no = models.IntegerField(null=True, verbose_name='Side')

    # Note that SUCCESS is indicated by just deleting the record
    NEW = "NEW"
    PROCESSING = "PROCESSING"
    FAILED = "FAILED"

    STATUS = (
        (NEW, "Ny"),
        (PROCESSING, "I gang"),
        (FAILED, "Mislykket"),
    )

    status = StatusField(max_length=10, default=NEW, verbose_name='Status')

    process_id = models.IntegerField(blank=True,
                                     null=True,
                                     verbose_name='Proces id')

    process_start_time = MonitorField(monitor='status',
                                      when=[PROCESSING],
                                      blank=True,
                                      null=True,
                                      verbose_name='Proces starttidspunkt')

    @property
    def file_path(self):
        """Return the full path to the conversion queue item's file."""
        return self.file

    @property
    def tmp_dir(self):
        """The path to the temporary dir associated with this queue item."""
        return os.path.join(self.url.scan.scan_dir,
                            'queue_item_%d' % (self.pk))

    def delete_tmp_dir(self):
        """Delete the item's temp dir if it is writable."""
        if os.access(self.tmp_dir, os.W_OK):
            shutil.rmtree(self.tmp_dir, True)

    class Meta:
        abstract = False
Ejemplo n.º 29
0
class Invite(TimeStampedModel):
    class Status(models.TextChoices):
        PENDING = "pending", _("Pending")
        ACCEPTED = "accepted", _("Accepted")
        REJECTED = "rejected", _("Rejected")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

    email = models.EmailField()

    community = models.ForeignKey(Community, on_delete=models.CASCADE)

    status = models.CharField(max_length=100,
                              choices=Status.choices,
                              default=Status.PENDING,
                              db_index=True)
    status_changed = MonitorField(monitor="status")

    sent = models.DateTimeField(null=True, blank=True)

    sender = models.ForeignKey(settings.AUTH_USER_MODEL,
                               on_delete=models.CASCADE)

    objects = InviteQuerySet.as_manager()

    class Meta:
        unique_together = ("email", "community")

    def __str__(self):
        return self.email

    def is_pending(self):
        return self.status == self.Status.PENDING

    def is_accepted(self):
        return self.status == self.Status.ACCEPTED

    def is_rejected(self):
        return self.status == self.Status.REJECTED

    def set_status(self, status):
        self.status = status
        self.save()

    @transaction.atomic
    def accept(self, user):
        self.set_status(self.Status.ACCEPTED)
        try:
            Membership.objects.create(member=user, community=self.community)
        except IntegrityError:
            pass

    def reject(self):
        self.set_status(self.Status.REJECTED)
Ejemplo n.º 30
0
class TelegramMessage(Base):

    STATUS = Choices(_('Created'), _('Scheduled'), _('Sent'))
    status = StatusField(verbose_name=_('Status'))

    widget = models.ForeignKey('widgets.Widget', null=True)
    leed = models.ForeignKey('widgets.Leed', null=True)

    message = models.CharField(max_length=500, null=True)

    status_changed = MonitorField(monitor='status')

    scheduled_at = MonitorField(monitor='status',
                                when=['Scheduled'],
                                verbose_name=_('SMS sheduled at'))
    sent_at = MonitorField(monitor='status',
                           when=['Sent'],
                           verbose_name=_('SMS sent at'))

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