diff --git a/symposion/reviews/models.py b/symposion/reviews/models.py index 2f596744db7c08686fb9c67d1a709363ae30d4f2..d47feff58f2185f233416ffa4eec23328b6bbf86 100644 --- a/symposion/reviews/models.py +++ b/symposion/reviews/models.py @@ -361,6 +361,12 @@ def promote_proposal(proposal): if hasattr(proposal, "presentation") and proposal.presentation: # already promoted presentation = proposal.presentation + presentation.title = proposal.title + presentation.abstract = proposal.abstract + presentation.speaker = proposal.speaker + presentation.proposal_base = proposal + presentation.save() + presentation.additional_speakers.clear() else: presentation = Presentation( title=proposal.title, @@ -370,9 +376,9 @@ def promote_proposal(proposal): proposal_base=proposal, ) presentation.save() - for speaker in proposal.additional_speakers.all(): - presentation.additional_speakers.add(speaker) - presentation.save() + for speaker in proposal.additional_speakers.all(): + presentation.additional_speakers.add(speaker) + presentation.save() return presentation diff --git a/symposion/reviews/views.py b/symposion/reviews/views.py index eff2f92980ae0f8721be11cb664eeb7af7aa3099..8c8015f94552b5ed08c2974a88439296be0b247a 100644 --- a/symposion/reviews/views.py +++ b/symposion/reviews/views.py @@ -23,7 +23,7 @@ from symposion.reviews.forms import ReviewForm, SpeakerCommentForm from symposion.reviews.forms import BulkPresentationForm from symposion.reviews.models import ( ReviewAssignment, Review, LatestVote, ProposalResult, NotificationTemplate, - ResultNotification + ResultNotification, promote_proposal ) @@ -422,8 +422,11 @@ def review_detail(request, pk): elif result == "standby": proposal.result.status = "standby" proposal.result.save() - - return redirect(request.path) + return redirect(request.path) + elif "publish_changes" in request.POST: + if admin and proposal.result.status == "accepted": + promote_proposal(proposal) + return redirect(request.path) else: initial = {} if latest_vote: diff --git a/symposion/schedule/migrations/0002_presentation_unpublish.py b/symposion/schedule/migrations/0002_presentation_unpublish.py new file mode 100644 index 0000000000000000000000000000000000000000..8e2a7caba275a2718dd9cfb6540c7acc2d50ab31 --- /dev/null +++ b/symposion/schedule/migrations/0002_presentation_unpublish.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-18 00:43 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('symposion_schedule', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='presentation', + name='unpublish', + field=models.BooleanField(default=False, verbose_name='Do not publish'), + ), + ] diff --git a/symposion/schedule/models.py b/symposion/schedule/models.py index c21a4367b0bd06210fbb89a8e5b3e1ab1749eb4d..cfa366624af673e0cb548f9359557a47c894b4e4 100644 --- a/symposion/schedule/models.py +++ b/symposion/schedule/models.py @@ -190,6 +190,10 @@ class Presentation(models.Model): speaker = models.ForeignKey(Speaker, related_name="presentations", verbose_name=_("Speaker")) additional_speakers = models.ManyToManyField(Speaker, related_name="copresentations", blank=True, verbose_name=_("Additional speakers")) + unpublish = models.BooleanField( + default=False, + verbose_name=_("Do not publish"), + ) cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled")) proposal_base = models.OneToOneField(ProposalBase, related_name="presentation", verbose_name=_("Proposal base")) section = models.ForeignKey(Section, related_name="presentations", verbose_name=_("Section")) diff --git a/symposion/schedule/views.py b/symposion/schedule/views.py index 75472fc53b1f575f0cdaf8975a164a52e515bd94..08a50cbbc458ad29d74587ae3c352bdc01682dcf 100644 --- a/symposion/schedule/views.py +++ b/symposion/schedule/views.py @@ -78,6 +78,9 @@ def schedule_list(request, slug=None): presentations = Presentation.objects.filter(section=schedule.section) presentations = presentations.exclude(cancelled=True) + if not request.user.is_staff: + presentations = presentations.exclude(unpublish=True) + ctx = { "schedule": schedule, "presentations": presentations, @@ -91,7 +94,10 @@ def schedule_list_csv(request, slug=None): raise Http404() presentations = Presentation.objects.filter(section=schedule.section) - presentations = presentations.exclude(cancelled=True).order_by("id") + presentations = presentations.exclude(cancelled=True) + if not request.user.is_staff: + presentations = presentations.exclude(unpublish=True) + presentations = presentations.order_by("id") response = HttpResponse(content_type="text/csv") if slug: @@ -174,12 +180,18 @@ def schedule_slot_edit(request, slug, slot_pk): def schedule_presentation_detail(request, pk): presentation = get_object_or_404(Presentation, pk=pk) + if presentation.slot: + # 1) Schedule from presentation's slot schedule = presentation.slot.day.schedule - if not schedule.published and not request.user.is_staff: - raise Http404() else: - schedule = None + # 2) Fall back to the schedule for this proposal + schedule = presentation.proposal.kind.section.schedule + + if not request.user.is_staff: + # 3) Is proposal unpublished? + if presentation.unpublish or not (schedule and schedule.published): + raise Http404() ctx = { "presentation": presentation, @@ -214,10 +226,11 @@ def schedule_json(request): "tags": "", "released": True, "contact": [], - - } if hasattr(slot.content, "proposal"): + if slot.content.proposal.unpublish and not request.user.is_staff: + continue + slot_data.update({ "name": slot.content.title, "authors": [s.name for s in slot.content.speakers()],