Changeset - 782e5c9ea21d
[Not reviewed]
0 1 0
Christopher Neugebauer - 8 years ago 2016-06-19 03:30:10
chrisjrn@gmail.com
Tidies up some of the proposal fields
1 file changed with 3 insertions and 7 deletions:
0 comments (0 inline, 0 general)
symposion/proposals/models.py
Show inline comments
 
from __future__ import unicode_literals
 
import os
 
import uuid
 

	
 
from django.core.urlresolvers import reverse
 
from django.db import models
 
from django.db.models import Q
 
from django.utils.encoding import python_2_unicode_compatible
 
from django.utils.translation import ugettext_lazy as _
 
from django.utils.timezone import now
 

	
 
from django.contrib.auth.models import User
 
from django.core.exceptions import ObjectDoesNotExist
 
from django.core.exceptions import ValidationError
 

	
 
from model_utils.managers import InheritanceManager
 
from reversion import revisions as reversion
 

	
 
from symposion.markdown_parser import parse
 
from symposion.conference.models import Section
 
from symposion.speakers.models import Speaker
 

	
 

	
 
@python_2_unicode_compatible
 
class ProposalSection(models.Model):
 
    """
 
    configuration of proposal submissions for a specific Section.
 

	
 
    a section is available for proposals iff:
 
      * it is after start (if there is one) and
 
      * it is before end (if there is one) and
 
      * closed is NULL or False
 
    """
 

	
 
    section = models.OneToOneField(Section, verbose_name=_("Section"))
 

	
 
    start = models.DateTimeField(null=True, blank=True, verbose_name=_("Start"))
 
    end = models.DateTimeField(null=True, blank=True, verbose_name=_("End"))
 
    closed = models.NullBooleanField(verbose_name=_("Closed"))
 
    published = models.NullBooleanField(verbose_name=_("Published"))
 

	
 
    @classmethod
 
    def available(cls):
 
        return cls._default_manager.filter(
 
            Q(start__lt=now()) | Q(start=None),
 
            Q(end__gt=now()) | Q(end=None),
 
            Q(closed=False) | Q(closed=None),
 
        )
 

	
 
    def is_available(self):
 
        if self.closed:
 
            return False
 
        if self.start and self.start > now():
 
            return False
 
        if self.end and self.end < now():
 
            return False
 
        return True
 

	
 
    def __str__(self):
 
        return self.section.name
 

	
 

	
 
@python_2_unicode_compatible
 
class ProposalKind(models.Model):
 
    """
 
    e.g. talk vs panel vs tutorial vs poster
 

	
 
    Note that if you have different deadlines, reviewers, etc. you'll want
 
    to distinguish the section as well as the kind.
 
    """
 

	
 
    section = models.ForeignKey(Section, related_name="proposal_kinds", verbose_name=_("Section"))
 

	
 
    name = models.CharField(_("Name"), max_length=100)
 
    slug = models.SlugField(verbose_name=_("Slug"))
 

	
 
    def __str__(self):
 
        return self.name
 

	
 

	
 
@python_2_unicode_compatible
 
class ProposalBase(models.Model):
 

	
 
    objects = InheritanceManager()
 

	
 
    kind = models.ForeignKey(ProposalKind, verbose_name=_("Kind"))
 

	
 
    title = models.CharField(max_length=100, verbose_name=_("Title"))
 
    abstract = models.TextField(
 
        _("Abstract"),
 
        help_text=_("This will appear in the conference programme. You will "
 
                    "have an opportunity to update it once the proposal is "
 
                    "accepted, but it should reasonably reflect what you will "
 
                    "be presenting, and in any case it will appear as-is on "
 
                    "the website in the draft programme. Up to about 500 "
 
                    "words. Edit using <a "
 
        help_text=_("This will appear in the conference programme. Up to about "
 
                    "500 words. Edit using <a "
 
                    "href='http://daringfireball.net/projects/markdown/basics' " "target='_blank'>Markdown</a>.")
 
    )
 
    abstract_html = models.TextField(blank=True)
 

	
 
    private_abstract = models.TextField(
 
        _("Private Abstract"),
 
        help_text=_("This will only be shown to organisers and reviewers. You "
 
                    "should provide any details about your proposal that you "
 
                    "don't want to be public here. Edit using <a " "href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    private_abstract_html = models.TextField(blank=True)
 

	
 
    technical_requirements = models.TextField(
 
        _("Special Requirements"),
 
        blank=True,
 
        help_text=_("Speakers will be provided with: Internet access, power, "
 
                    "projector, audio.  If you require anything in addition, "
 
                    "please list your technical requirements here.  Such as: a "
 
                    "static IP address, A/V equipment or will be demonstrating "
 
                    "security-related techniques on the conference network. "
 
                    "Edit using <a "
 
                    "href='http://daringfireball.net/projects/markdown/basics' "
 
                    "target='_blank'>Markdown</a>.")
 
    )
 
    technical_requirements_html = models.TextField(blank=True)
 

	
 
    project = models.TextField(
 
    project = models.CharField(
 
        max_length=100,
 
        blank=True,
 
        help_text=_("The name of the project you will be talking about."),
 
    )
 
    project_url = models.URLField(
 
        _("Project URL"),
 
        blank=True,
 
        help_text=_("If your project has a webpage, specify the URL here so "
 
                    "the committee can find out more about your proposal.")
 
    )
 
    video_url = models.URLField(
 
        _("Video"),
 
        blank=True,
 
        help_text=_("You may optionally provide us with a link to a video of "
 
                    "you speaking at another event, or of a short 'elevator "
 
                    "pitch' of your proposed talk.")
 
    )
 

	
 
    submitted = models.DateTimeField(
 
        default=now,
 
        editable=False,
 
        verbose_name=_("Submitted")
 
    )
 
    speaker = models.ForeignKey(Speaker, related_name="proposals", verbose_name=_("Speaker"))
 

	
 
    # @@@ this validation used to exist as a validators keyword on additional_speakers
 
    #     M2M field but that is no longer supported by Django. Should be moved to
 
    #     the form level
 
    def additional_speaker_validator(self, a_speaker):
 
        if a_speaker.speaker.email == self.speaker.email:
 
            raise ValidationError(_("%s is same as primary speaker.") % a_speaker.speaker.email)
 
        if a_speaker in [self.additional_speakers]:
 
            raise ValidationError(_("%s has already been in speakers.") % a_speaker.speaker.email)
 

	
 
    additional_speakers = models.ManyToManyField(Speaker, through="AdditionalSpeaker",
 
                                                 blank=True, verbose_name=_("Addtional speakers"))
 
    cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled"))
 

	
 
    def save(self, *args, **kwargs):
 
        self.abstract_html = parse(self.abstract)
 
        self.private_abstract_html = parse(self.private_abstract)
 
        self.technical_requirements_html = parse(self.technical_requirements)
 
        return super(ProposalBase, self).save(*args, **kwargs)
 

	
 
    def can_edit(self):
 
        return True
 

	
 
    @property
 
    def section(self):
 
        return self.kind.section
 

	
 
    @property
 
    def speaker_email(self):
 
        return self.speaker.email
 

	
 
    @property
 
    def number(self):
 
        return str(self.pk).zfill(3)
 

	
 
    @property
 
    def status(self):
 
        try:
 
            return self.result.status
 
        except ObjectDoesNotExist:
 
            return _('Undecided')
 

	
 
    def speakers(self):
 
        yield self.speaker
 
        speakers = self.additional_speakers.exclude(
 
            additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED)
 
        for speaker in speakers:
 
            yield speaker
 

	
 
    def notification_email_context(self):
 
        return {
 
            "title": self.title,
 
            "speaker": self.speaker.name,
 
            "speakers": ', '.join([x.name for x in self.speakers()]),
 
            "kind": self.kind.name,
 
        }
 

	
 
    def __str__(self):
 
        return self.title
 

	
 
reversion.register(ProposalBase)
 

	
 

	
 
@python_2_unicode_compatible
 
class AdditionalSpeaker(models.Model):
 

	
 
    SPEAKING_STATUS_PENDING = 1
 
    SPEAKING_STATUS_ACCEPTED = 2
 
    SPEAKING_STATUS_DECLINED = 3
 

	
 
    SPEAKING_STATUS = [
 
        (SPEAKING_STATUS_PENDING, _("Pending")),
0 comments (0 inline, 0 general)