0a77592bd9
When only one topic is available, havign a column to display topic (or mentioning topic) is a bit confusing. Simplify the UI so that you can safely ignore this concept if there is only one topic available. Change-Id: I69ddef83b586a81df75e04579125681cbe067151
210 lines
8.1 KiB
Python
210 lines
8.1 KiB
Python
# Copyright 2011 Thierry Carrez <thierry@openstack.org>
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib.auth.models import User
|
|
from django.conf import settings
|
|
from django.contrib.auth import logout
|
|
from django.core.mail import EmailMessage
|
|
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
|
from django.template.response import TemplateResponse
|
|
from django.utils.encoding import smart_str
|
|
|
|
from cfp.models import Proposal, Topic, Comment
|
|
from cfp.forms import ProposalForm, ProposalEditForm, CommentForm
|
|
from cfp.forms import ProposalReviewForm, ProposalSwitchForm
|
|
from cfp.utils import linkify, is_editable, topiclead
|
|
|
|
|
|
@login_required
|
|
def list(request):
|
|
multitopic = Topic.objects.count() > 1
|
|
proposals = Proposal.objects.all()
|
|
reviewable_topics = Topic.objects.filter(
|
|
lead_username=request.user.username)
|
|
request.session['lastlist'] = ""
|
|
return TemplateResponse(request, "cfplist.html",
|
|
{'proposals': proposals,
|
|
'multitopic': multitopic,
|
|
'reviewable_topics': reviewable_topics})
|
|
|
|
|
|
@login_required
|
|
def topiclist(request, topicid):
|
|
multitopic = Topic.objects.count() > 1
|
|
topic = Topic.objects.get(id=topicid)
|
|
if not topiclead(request.user, topic):
|
|
return HttpResponseForbidden("Forbidden")
|
|
proposals = Proposal.objects.filter(topic=topicid)
|
|
request.session['lastlist'] = "cfp/topic/%s" % topicid
|
|
return TemplateResponse(request, "topiclist.html",
|
|
{'proposals': proposals,
|
|
'multitopic': multitopic,
|
|
'sched': 'scheduling' in settings.INSTALLED_APPS,
|
|
'topic': topic})
|
|
|
|
|
|
@login_required
|
|
def topicstatus(request):
|
|
topics = Topic.objects.all()
|
|
return TemplateResponse(request, "topicstatus.html", {'topics': topics})
|
|
|
|
|
|
@login_required
|
|
def create(request):
|
|
if request.method == 'POST':
|
|
form = ProposalForm(request.POST)
|
|
if form.is_valid():
|
|
proposal = form.save(commit=False)
|
|
proposal.proposer = request.user
|
|
proposal.status = 'U'
|
|
proposal.save()
|
|
return list(request)
|
|
else:
|
|
form = ProposalForm()
|
|
|
|
topics = Topic.objects.all()
|
|
return TemplateResponse(request, 'cfpcreate.html',
|
|
{'topics': topics,
|
|
'form': form})
|
|
|
|
|
|
@login_required
|
|
def details(request, proposalid):
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
if request.method == 'POST':
|
|
form = CommentForm(request.POST)
|
|
if form.is_valid():
|
|
comment = form.save(commit=False)
|
|
comment.proposal = proposal
|
|
comment.author = request.user
|
|
comment.save()
|
|
form = CommentForm()
|
|
comments = Comment.objects.filter(proposal=proposal)
|
|
return TemplateResponse(request, "cfpdetails.html",
|
|
{'proposal': proposal,
|
|
'form': form,
|
|
'comments': comments,
|
|
'editable': is_editable(proposal, request.user),
|
|
'blueprints': linkify(proposal.blueprints)})
|
|
|
|
|
|
@login_required
|
|
def edit(request, proposalid):
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
if not is_editable(proposal, request.user):
|
|
return HttpResponseForbidden("Forbidden")
|
|
if request.method == 'POST':
|
|
form = ProposalEditForm(request.POST, instance=proposal)
|
|
if form.is_valid():
|
|
form.save()
|
|
return HttpResponseRedirect('/%s' % request.session['lastlist'])
|
|
else:
|
|
form = ProposalEditForm(instance=proposal)
|
|
return TemplateResponse(request, 'cfpedit.html', {'form': form,
|
|
'proposal': proposal})
|
|
|
|
|
|
@login_required
|
|
def delete(request, proposalid):
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
if ((proposal.proposer != request.user) or proposal.status in ['A', 'S']):
|
|
return HttpResponseForbidden("Forbidden")
|
|
if request.method == 'POST':
|
|
proposal.delete()
|
|
return HttpResponseRedirect('/%s' % request.session['lastlist'])
|
|
return TemplateResponse(request, 'cfpdelete.html', {'proposal': proposal})
|
|
|
|
|
|
@login_required
|
|
def switch(request, proposalid):
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
if ((proposal.proposer != request.user)
|
|
and not topiclead(request.user, proposal.topic)) or proposal.scheduled:
|
|
return HttpResponseForbidden("Forbidden")
|
|
if request.method == 'POST':
|
|
form = ProposalSwitchForm(request.POST, instance=proposal)
|
|
if form.is_valid():
|
|
form.save()
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
proposal.status = 'U'
|
|
proposal.save()
|
|
return HttpResponseRedirect('/%s' % request.session['lastlist'])
|
|
else:
|
|
form = ProposalSwitchForm(instance=proposal)
|
|
return TemplateResponse(request, 'cfpswitch.html', {'form': form,
|
|
'proposal': proposal})
|
|
|
|
|
|
@login_required
|
|
def review(request, proposalid):
|
|
proposal = Proposal.objects.get(id=proposalid)
|
|
if not topiclead(request.user, proposal.topic):
|
|
return HttpResponseForbidden("Forbidden")
|
|
current_status = proposal.status
|
|
status_long = proposal.get_status_display()
|
|
if request.method == 'POST':
|
|
form = ProposalReviewForm(request.POST, instance=proposal)
|
|
if form.is_valid():
|
|
form.save()
|
|
reviewer_notes = ''
|
|
if form.cleaned_data['comment']:
|
|
reviewer_notes = form.cleaned_data['comment']
|
|
c = Comment()
|
|
c.proposal = proposal
|
|
c.author = request.user
|
|
c.content = reviewer_notes
|
|
c.save()
|
|
if (settings.SEND_MAIL and current_status != proposal.status):
|
|
lead = User.objects.get(username=proposal.topic.lead_username)
|
|
if (lead.email and proposal.proposer.email):
|
|
message = """
|
|
This is an automated email.
|
|
If needed, you should reply directly to the topic lead (%s).
|
|
|
|
On your session proposal: %s
|
|
The topic lead (%s) changed status from %s to %s.
|
|
|
|
Reviewer's notes:
|
|
%s
|
|
|
|
You can access your proposal at: %s/cfp/details/%s""" \
|
|
% (proposal.topic.lead_username,
|
|
smart_str(proposal.title),
|
|
proposal.topic.lead_username,
|
|
status_long, proposal.get_status_display(),
|
|
smart_str(reviewer_notes),
|
|
settings.SITE_ROOT, proposalid)
|
|
email = EmailMessage(settings.EMAIL_PREFIX +
|
|
"Status change on your session proposal",
|
|
message, settings.EMAIL_FROM,
|
|
[proposal.proposer.email, ], [],
|
|
headers={'Reply-To': lead.email})
|
|
email.send()
|
|
return HttpResponseRedirect('/cfp/topic/%d' % proposal.topic.id)
|
|
else:
|
|
form = ProposalReviewForm(instance=proposal)
|
|
comments = Comment.objects.filter(proposal=proposal)
|
|
return TemplateResponse(request, 'cfpreview.html',
|
|
{'form': form,
|
|
'proposal': proposal,
|
|
'comments': comments,
|
|
'blueprints': linkify(proposal.blueprints)})
|
|
|
|
|
|
def dologout(request):
|
|
logout(request)
|
|
return HttpResponseRedirect('/')
|