diff --git a/symposion/proposals/models.py b/symposion/proposals/models.py index e70af55035d5caef2d5362dde52cefdd7c19637b..c12c5bcc768ca32c43c075da355f6ddd3af18e4c 100644 --- a/symposion/proposals/models.py +++ b/symposion/proposals/models.py @@ -21,20 +21,20 @@ from symposion.conference.models import Section 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) - + start = models.DateTimeField(null=True, blank=True) end = models.DateTimeField(null=True, blank=True) closed = models.NullBooleanField() published = models.NullBooleanField() - + @classmethod def available(cls): now = datetime.datetime.now() @@ -43,7 +43,7 @@ class ProposalSection(models.Model): Q(end__gt=now) | Q(end=None), Q(closed=False) | Q(closed=None), ) - + def is_available(self): if self.closed: return False @@ -53,7 +53,7 @@ class ProposalSection(models.Model): if self.end and self.end < now: return False return True - + def __unicode__(self): return self.section.name @@ -61,68 +61,77 @@ class ProposalSection(models.Model): 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") - + name = models.CharField(_("Name"), max_length=100) slug = models.SlugField() - + def __unicode__(self): return self.name class ProposalBase(models.Model): - + objects = InheritanceManager() - + kind = models.ForeignKey(ProposalKind) - + title = models.CharField(max_length=100) description = models.TextField( _("Brief Description"), max_length=400, # @@@ need to enforce 400 in UI - help_text="If your proposal is accepted this will be made public and printed in the program. Should be one paragraph, maximum 400 characters." + help_text=_("If your proposal is accepted this will be made public and printed in the " + "program. Should be one paragraph, maximum 400 characters.") ) abstract = MarkupField( _("Detailed Abstract"), - help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit using Markdown.") + help_text=_("Detailed outline. Will be made public if your proposal is accepted. Edit " + "using Markdown.") ) additional_notes = MarkupField( blank=True, - help_text=_("Anything else you'd like the program committee to know when making their selection: your past experience, etc. This is not made public. Edit using Markdown.") + help_text=_("Anything else you'd like the program committee to know when making their " + "selection: your past experience, etc. This is not made public. Edit using " + "Markdown.") ) submitted = models.DateTimeField( default=datetime.datetime.now, editable=False, ) speaker = models.ForeignKey("speakers.Speaker", related_name="proposals") - additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker", blank=True) + additional_speakers = models.ManyToManyField("speakers.Speaker", through="AdditionalSpeaker", + blank=True) cancelled = models.BooleanField(default=False) - + 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) - + def speakers(self): yield self.speaker - for speaker in self.additional_speakers.exclude(additionalspeaker__status=AdditionalSpeaker.SPEAKING_STATUS_DECLINED): + 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, @@ -135,21 +144,21 @@ reversion.register(ProposalBase) class AdditionalSpeaker(models.Model): - + SPEAKING_STATUS_PENDING = 1 SPEAKING_STATUS_ACCEPTED = 2 SPEAKING_STATUS_DECLINED = 3 - + SPEAKING_STATUS = [ (SPEAKING_STATUS_PENDING, _("Pending")), (SPEAKING_STATUS_ACCEPTED, _("Accepted")), (SPEAKING_STATUS_DECLINED, _("Declined")), ] - + speaker = models.ForeignKey("speakers.Speaker") proposalbase = models.ForeignKey(ProposalBase) status = models.IntegerField(choices=SPEAKING_STATUS, default=SPEAKING_STATUS_PENDING) - + class Meta: db_table = "proposals_proposalbase_additional_speakers" unique_together = ("speaker", "proposalbase") @@ -162,14 +171,15 @@ def uuid_filename(instance, filename): class SupportingDocument(models.Model): - + proposal = models.ForeignKey(ProposalBase, related_name="supporting_documents") - + uploaded_by = models.ForeignKey(User) created_at = models.DateTimeField(default=datetime.datetime.now) - + file = models.FileField(upload_to=uuid_filename) description = models.CharField(max_length=140) def download_url(self): - return reverse("proposal_document_download", args=[self.pk, os.path.basename(self.file.name).lower()]) + return reverse("proposal_document_download", + args=[self.pk, os.path.basename(self.file.name).lower()])