Esempio n. 1
0
class Post(TimeStampedModel):
    author = models.ForeignKey("users.User", on_delete=models.CASCADE)
    title = I18nCharField(_("title"), max_length=200)
    slug = I18nCharField(_("slug"), max_length=200, blank=True)
    content = I18nTextField(_("content"), blank=True)
    excerpt = I18nTextField(_("excerpt"), blank=False)
    published = models.DateTimeField(_("published"), default=timezone.now)
    image = models.ImageField(_("image"),
                              null=True,
                              blank=True,
                              upload_to="blog")

    objects = models.Manager()
    published_posts = PostManager()

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

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = copy(self.title)
            self.slug.map(slugify)

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

    class Meta:
        ordering = ["-published"]
Esempio n. 2
0
class Page(TimeStampedModel):
    title = I18nCharField(_("title"), max_length=200)
    slug = I18nCharField(_("slug"), max_length=200, blank=True)
    content = I18nTextField(_("content"), blank=False)
    published = models.BooleanField(_("published"), default=False)
    image = models.ImageField(_("image"), null=True, blank=True, upload_to="pages")
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="pages",
    )

    objects = models.Manager()
    published_pages = PageManager()

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

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = copy(self.title)
            self.slug.map(slugify)

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

    class Meta:
        unique_together = ["slug", "conference"]
Esempio n. 3
0
class Event(GeoLocalizedModel, TimeFramedModel, TimeStampedModel):
    slug = I18nCharField(_("slug"), blank=False)
    content = I18nTextField(_("content"), blank=False)
    title = I18nCharField(_("title"), blank=False)
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="events",
    )
    image = models.ImageField(_("image"),
                              null=True,
                              blank=True,
                              upload_to="events")
    location_name = models.CharField(_("location name"),
                                     max_length=200,
                                     blank=True)

    def __str__(self):
        return f"{self.title} ({self.conference.name})"

    class Meta:
        unique_together = ["slug", "conference"]
        verbose_name = _("Event")
        verbose_name_plural = _("Events")
Esempio n. 4
0
class Deadline(TimeFramedModel):
    TYPES = Choices(
        ("cfp", _("Call for proposal")),
        ("voting", _("Voting")),
        ("refund", _("Ticket refund")),
        ("grants", _("Grants")),
        ("custom", _("Custom deadline")),
    )

    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="deadlines",
    )

    name = I18nCharField(_("name"), max_length=100)
    description = I18nTextField(_("description"), blank=True, null=True)
    type = models.CharField(_("type"), choices=TYPES, max_length=10)

    def __str__(self):
        return f"{self.type} ({self.name}) <{self.conference.code}>"

    @property
    def status(self) -> DeadlineStatus:
        now = timezone.now()

        if now >= self.start and now <= self.end:
            return DeadlineStatus.HAPPENING_NOW

        if self.start > now:
            return DeadlineStatus.IN_THE_FUTURE

        return DeadlineStatus.IN_THE_PAST
Esempio n. 5
0
class JobListing(TimeStampedModel):
    title = I18nCharField(_("title"), max_length=200)
    slug = I18nCharField(_("slug"), max_length=200, blank=True)
    company = models.CharField(_("company"), max_length=100)
    company_logo = models.ImageField(_("company logo"),
                                     null=True,
                                     blank=True,
                                     upload_to="job-listings")
    description = I18nTextField(_("description"), blank=True)
    apply_url = models.URLField(_("URL where you can apply"), blank=True)

    objects = JobListingManager()

    class Meta:
        ordering = ["created"]

    def __str__(self):
        return f"[{self.company}] - {self.title}"

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = copy(self.title)
            self.slug.map(slugify)

        super().save(*args, **kwargs)
Esempio n. 6
0
class HotelRoom(models.Model):
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="hotel_rooms",
    )

    name = I18nCharField(_("name"), max_length=200)
    description = I18nTextField(_("description"), blank=True)

    total_capacity = models.PositiveIntegerField(_("total capacity"))
    price = models.DecimalField(_("price"), max_digits=7, decimal_places=2)

    @cached_property
    def capacity_left(self):
        return (self.total_capacity -
                HotelRoomReservation.objects.filter(room_id=self.pk).count())

    @property
    def is_sold_out(self):
        # TODO: run the check in the query instead of python
        return (HotelRoomReservation.objects.filter(room_id=self.pk).count() >=
                self.total_capacity)

    def __str__(self):
        return f"{self.name} ({self.conference.code})"

    class Meta:
        verbose_name = _("hotel room")
        verbose_name_plural = _("hotel rooms")
Esempio n. 7
0
class Keynote(OrderedModel, TimeStampedModel):
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="keynotes",
        null=False,
    )
    slug = I18nCharField(_("slug"), max_length=200, unique=True)
    title = I18nCharField(_("keynote title"),
                          blank=False,
                          max_length=512,
                          default="")
    description = I18nTextField(_("keynote description"),
                                blank=False,
                                default="")
    topic = models.ForeignKey(
        "conferences.Topic",
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        default=None,
    )
    order_with_respect_to = "conference"
    objects = KeynoteManager()

    def __str__(self) -> str:
        return f"{self.title} at {self.conference.code}"

    class Meta(OrderedModel.Meta):
        verbose_name = _("Keynote")
        verbose_name_plural = _("Keynotes")
Esempio n. 8
0
class FAQ(TimeStampedModel):
    question = I18nTextField(_("question"), blank=False)
    answer = I18nTextField(_("answer"), blank=False)
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="faqs",
    )

    def __str__(self):
        return f"{self.question} ({self.conference.name})"

    class Meta:
        unique_together = ["question", "conference"]
        verbose_name = _("FAQ")
        verbose_name_plural = _("FAQs")
Esempio n. 9
0
class MenuLink(OrderedModel, TimeStampedModel):
    menu = models.ForeignKey(Menu,
                             on_delete=models.CASCADE,
                             verbose_name=_("menu"),
                             related_name="links")
    title = I18nTextField(_("title"), blank=False)
    href = I18nTextField(_("Link url"), blank=True)
    is_primary = models.BooleanField(_("Is primary"), default=False)
    page = models.ForeignKey(
        "pages.Page",
        on_delete=models.CASCADE,
        verbose_name=_("page"),
        related_name="links",
        null=True,
        blank=True,
    )

    def __str__(self):
        return f"{self.title} ({self.menu})"
Esempio n. 10
0
class KeynoteSpeaker(TimeStampedModel, OrderedModel):
    keynote = models.ForeignKey(
        "conferences.Keynote",
        on_delete=models.CASCADE,
        verbose_name=_("keynote"),
        related_name="speakers",
        null=False,
    )

    name = models.CharField(
        _("fullname"),
        max_length=512,
        blank=False,
    )
    photo = models.ImageField(_("photo"),
                              null=False,
                              blank=False,
                              upload_to="keynotes")
    bio = I18nTextField(
        _("bio"),
        blank=False,
    )
    pronouns = I18nCharField(
        _("pronouns"),
        max_length=512,
    )
    highlight_color = models.CharField(choices=COLORS,
                                       max_length=15,
                                       blank=True,
                                       verbose_name=_("highlight color"))
    twitter_handle = models.CharField(
        _("twitter handle"),
        max_length=1024,
        default="",
        blank=True,
    )
    instagram_handle = models.CharField(
        _("instagram handle"),
        max_length=1024,
        default="",
        blank=True,
    )
    website = models.URLField(_("website"),
                              blank=True,
                              default="",
                              max_length=2049)
    order_with_respect_to = "keynote"

    class Meta(OrderedModel.Meta):
        verbose_name = _("Keynote Speaker")
        verbose_name_plural = _("Keynote Speakers")
Esempio n. 11
0
class Menu(TimeStampedModel):
    identifier = models.SlugField(_("identifier"))
    title = I18nTextField(_("title"), blank=False)
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="menus",
    )

    def __str__(self):
        return f"{self.identifier} ({self.conference.name})"

    class Meta:
        unique_together = ["identifier", "conference"]
Esempio n. 12
0
class GenericCopy(TimeStampedModel):
    key = models.SlugField(_("slug"), max_length=200)
    content = I18nTextField(_("content"), blank=False)
    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="copy",
    )

    def __str__(self):
        return f"{self.key} ({self.conference.name})"

    class Meta:
        unique_together = ["key", "conference"]
        verbose_name = _("Generic Copy")
        verbose_name_plural = _("Generic Copy")
Esempio n. 13
0
def test_i18n_textarea():
    widget = I18nTextarea(
        locales=[("en", "English"), ("it", "Italian")], field=I18nTextField()
    )
    output = widget.render("msg", "value")

    assert (
        output
        == """<div class="i18n-form-group"><div>
  <label style="width: auto; margin-right: 20px;">
    <strong style="display:block; margin-bottom: 10px;">English:</strong>\n
    <textarea name="msg_0" cols="40" rows="10" lang="en">
</textarea>\n
  </label>
</div><div>
  <label style="width: auto; margin-right: 20px;">
    <strong style="display:block; margin-bottom: 10px;">Italian:</strong>\n
    <textarea name="msg_1" cols="40" rows="10" lang="it">
value</textarea>\n
  </label>
</div></div>"""
    )
Esempio n. 14
0
class Deadline(TimeFramedModel):
    TYPES = Choices(
        ("cfp", _("Call for proposal")),
        ("voting", _("Voting")),
        ("refund", _("Ticket refund")),
        ("custom", _("Custom deadline")),
    )

    conference = models.ForeignKey(
        "conferences.Conference",
        on_delete=models.CASCADE,
        verbose_name=_("conference"),
        related_name="deadlines",
    )

    name = I18nCharField(_("name"), max_length=100)
    description = I18nTextField(_("description"), blank=True, null=True)
    type = models.CharField(_("type"), choices=TYPES, max_length=10)

    def clean(self):
        super().clean()

        if self.start > self.end:
            raise exceptions.ValidationError(_("Start date cannot be after end"))

        if self.type != Deadline.TYPES.custom:
            if (
                Deadline.objects.filter(conference=self.conference, type=self.type)
                .exclude(id=self.id)
                .exists()
            ):
                raise exceptions.ValidationError(
                    _("You can only have one deadline of type %(type)s")
                    % {"type": self.type}
                )

    def __str__(self):
        return f"{self.type} ({self.name}) <{self.conference.code}>"
Esempio n. 15
0
class Conference(GeoLocalizedModel, TimeFramedModel, TimeStampedModel):
    name = I18nCharField(_("name"), max_length=100)
    code = models.CharField(_("code"), max_length=10, unique=True)
    timezone = TimeZoneField()

    topics = models.ManyToManyField(
        "conferences.Topic", verbose_name=_("topics"), blank=True
    )
    languages = models.ManyToManyField(
        "languages.Language", verbose_name=_("languages"), blank=True
    )
    audience_levels = models.ManyToManyField(
        "conferences.AudienceLevel", verbose_name=_("audience levels"), blank=True
    )
    submission_types = models.ManyToManyField(
        "submissions.SubmissionType", verbose_name=_("submission types"), blank=True
    )

    pretix_organizer_id = models.CharField(
        _("pretix organizer id"), max_length=200, blank=True, default=""
    )
    pretix_event_id = models.CharField(
        _("pretix event id"), max_length=200, blank=True, default=""
    )
    pretix_event_url = models.URLField(_("pretix event url"), blank=True, default="")

    pretix_hotel_ticket_id = models.IntegerField(
        _("pretix hotel ticket id"), blank=True, null=True
    )
    pretix_hotel_room_type_question_id = models.IntegerField(
        _("pretix hotel room type question id"), blank=True, null=True
    )
    pretix_hotel_checkin_question_id = models.IntegerField(
        _("pretix hotel check-in question id"), blank=True, null=True
    )
    pretix_hotel_checkout_question_id = models.IntegerField(
        _("pretix hotel checkout question id"), blank=True, null=True
    )

    introduction = I18nTextField(_("introduction"), blank=False)

    @property
    def is_cfp_open(self):
        try:
            cfp_deadline = self.deadlines.get(type=Deadline.TYPES.cfp)

            now = timezone.now()
            return cfp_deadline.start <= now <= cfp_deadline.end
        except Deadline.DoesNotExist:
            return False

    @property
    def is_voting_open(self):
        try:
            voting_deadline = self.deadlines.get(type=Deadline.TYPES.voting)

            now = timezone.now()
            return voting_deadline.start <= now <= voting_deadline.end
        except Deadline.DoesNotExist:
            return False

    @cached_property
    def is_voting_closed(self):
        try:
            voting_deadline = self.deadlines.get(type=Deadline.TYPES.voting)

            now = timezone.now()
            return voting_deadline.end <= now
        except Deadline.DoesNotExist:
            return False

    @cached_property
    def is_grants_open(self):
        try:
            grants_deadline = self.deadlines.get(type=Deadline.TYPES.grants)

            return grants_deadline.status == DeadlineStatus.HAPPENING_NOW
        except Deadline.DoesNotExist:
            return False

    def __str__(self):
        return f"{self.name} <{self.code}>"

    class Meta:
        verbose_name = _("Conference")
        verbose_name_plural = _("Conferences")