Splitting views.py and models.py
Separating parts of views.py and models.py into forms.py and utils.py for cleanliness.
This commit is contained in:
parent
87483a2474
commit
f0466d87c9
49
cfp/forms.py
Normal file
49
cfp/forms.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# 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.forms import ModelForm, CharField, Textarea
|
||||||
|
|
||||||
|
from odsreg.cfp.models import Comment, Proposal
|
||||||
|
|
||||||
|
|
||||||
|
class CommentForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Comment
|
||||||
|
exclude = ('proposal', 'posted_date', 'author')
|
||||||
|
|
||||||
|
|
||||||
|
class ProposalForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Proposal
|
||||||
|
exclude = ('proposer', 'status', 'scheduled')
|
||||||
|
|
||||||
|
|
||||||
|
class ProposalEditForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Proposal
|
||||||
|
exclude = ('topic', 'proposer', 'status', 'scheduled')
|
||||||
|
|
||||||
|
|
||||||
|
class ProposalReviewForm(ModelForm):
|
||||||
|
comment = CharField(widget=Textarea)
|
||||||
|
class Meta:
|
||||||
|
model = Proposal
|
||||||
|
fields = ('status',)
|
||||||
|
|
||||||
|
|
||||||
|
class ProposalSwitchForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Proposal
|
||||||
|
fields = ('topic',)
|
@ -13,36 +13,10 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import urllib
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms import ModelForm, CharField, Textarea
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from cfp.utils import validate_bp
|
||||||
def is_valid_lp_name(value):
|
|
||||||
return value.replace('-', '').isalnum()
|
|
||||||
|
|
||||||
|
|
||||||
def validate_bp(value):
|
|
||||||
bps = value.split()
|
|
||||||
for bp in bps:
|
|
||||||
members = bp.split("/")
|
|
||||||
if len(members) != 2:
|
|
||||||
raise ValidationError(u'Blueprints should be specified under'
|
|
||||||
' the form project/blueprint-name')
|
|
||||||
(project, bpname) = list(members)
|
|
||||||
if not is_valid_lp_name(project):
|
|
||||||
raise ValidationError(u'Incorrect project name: %s' % project)
|
|
||||||
if not is_valid_lp_name(bpname):
|
|
||||||
raise ValidationError(u'Incorrect blueprint name: %s' % bpname)
|
|
||||||
f = urllib.urlopen("https://api.launchpad.net/devel/%s/+spec/%s"
|
|
||||||
% (project, bpname))
|
|
||||||
f.close()
|
|
||||||
if f.getcode() != 200:
|
|
||||||
raise ValidationError(u'No such blueprint: %s/%s'
|
|
||||||
' -- did you create it on Launchpad ?'
|
|
||||||
% (project, bpname))
|
|
||||||
|
|
||||||
|
|
||||||
class Topic(models.Model):
|
class Topic(models.Model):
|
||||||
@ -95,34 +69,3 @@ class Comment(models.Model):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['posted_date']
|
ordering = ['posted_date']
|
||||||
|
|
||||||
|
|
||||||
class CommentForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Comment
|
|
||||||
exclude = ('proposal', 'posted_date', 'author')
|
|
||||||
|
|
||||||
|
|
||||||
class ProposalForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Proposal
|
|
||||||
exclude = ('proposer', 'status', 'scheduled')
|
|
||||||
|
|
||||||
|
|
||||||
class ProposalEditForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Proposal
|
|
||||||
exclude = ('topic', 'proposer', 'status', 'scheduled')
|
|
||||||
|
|
||||||
|
|
||||||
class ProposalReviewForm(ModelForm):
|
|
||||||
comment = CharField(widget=Textarea)
|
|
||||||
class Meta:
|
|
||||||
model = Proposal
|
|
||||||
fields = ('status',)
|
|
||||||
|
|
||||||
|
|
||||||
class ProposalSwitchForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Proposal
|
|
||||||
fields = ('topic',)
|
|
||||||
|
61
cfp/utils.py
Normal file
61
cfp/utils.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
import urllib
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
def is_editable(proposal, user):
|
||||||
|
return ((not proposal.scheduled) and
|
||||||
|
((proposal.proposer == user and proposal.status != 'A') or
|
||||||
|
topiclead(user, proposal.topic)))
|
||||||
|
|
||||||
|
|
||||||
|
def linkify(blueprints):
|
||||||
|
links = {}
|
||||||
|
for bp in blueprints.split():
|
||||||
|
(project, name) = bp.split('/')
|
||||||
|
links[bp] = "https://blueprints.launchpad.net/%s/+spec/%s" \
|
||||||
|
% (project, name)
|
||||||
|
return links
|
||||||
|
|
||||||
|
|
||||||
|
def topiclead(user, topic):
|
||||||
|
return (user.username == topic.lead_username) or user.is_staff
|
||||||
|
|
||||||
|
|
||||||
|
def _is_valid_lp_name(value):
|
||||||
|
return value.replace('-', '').isalnum()
|
||||||
|
|
||||||
|
|
||||||
|
def validate_bp(value):
|
||||||
|
bps = value.split()
|
||||||
|
for bp in bps:
|
||||||
|
members = bp.split("/")
|
||||||
|
if len(members) != 2:
|
||||||
|
raise ValidationError(u'Blueprints should be specified under'
|
||||||
|
' the form project/blueprint-name')
|
||||||
|
(project, bpname) = list(members)
|
||||||
|
if not _is_valid_lp_name(project):
|
||||||
|
raise ValidationError(u'Incorrect project name: %s' % project)
|
||||||
|
if not _is_valid_lp_name(bpname):
|
||||||
|
raise ValidationError(u'Incorrect blueprint name: %s' % bpname)
|
||||||
|
f = urllib.urlopen("https://api.launchpad.net/devel/%s/+spec/%s"
|
||||||
|
% (project, bpname))
|
||||||
|
f.close()
|
||||||
|
if f.getcode() != 200:
|
||||||
|
raise ValidationError(u'No such blueprint: %s/%s'
|
||||||
|
' -- did you create it on Launchpad ?'
|
||||||
|
% (project, bpname))
|
40
cfp/views.py
40
cfp/views.py
@ -21,26 +21,11 @@ from django.contrib.auth import logout
|
|||||||
from django.core.mail import EmailMessage
|
from django.core.mail import EmailMessage
|
||||||
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
from odsreg.cfp.models import Proposal, Topic, Comment
|
from odsreg.cfp.models import Proposal, Topic, Comment
|
||||||
from odsreg.cfp.models import ProposalForm, ProposalEditForm, CommentForm
|
from odsreg.cfp.forms import ProposalForm, ProposalEditForm, CommentForm
|
||||||
from odsreg.cfp.models import ProposalReviewForm, ProposalSwitchForm
|
from odsreg.cfp.forms import ProposalReviewForm, ProposalSwitchForm
|
||||||
|
from odsreg.cfp.utils import linkify, is_editable, topiclead
|
||||||
|
|
||||||
def linkify(blueprints):
|
|
||||||
links = {}
|
|
||||||
for bp in blueprints.split():
|
|
||||||
(project, name) = bp.split('/')
|
|
||||||
links[bp] = "https://blueprints.launchpad.net/%s/+spec/%s" \
|
|
||||||
% (project, name)
|
|
||||||
return links
|
|
||||||
|
|
||||||
|
|
||||||
def topiclead(user, topic):
|
|
||||||
return (user.username == topic.lead_username) or user.is_staff
|
|
||||||
|
|
||||||
|
|
||||||
def forbidden():
|
|
||||||
return HttpResponseForbidden("Forbidden")
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -58,7 +43,7 @@ def list(request):
|
|||||||
def topiclist(request, topicid):
|
def topiclist(request, topicid):
|
||||||
topic = Topic.objects.get(id=topicid)
|
topic = Topic.objects.get(id=topicid)
|
||||||
if not topiclead(request.user, topic):
|
if not topiclead(request.user, topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
proposals = Proposal.objects.filter(topic=topicid)
|
proposals = Proposal.objects.filter(topic=topicid)
|
||||||
request.session['lastlist'] = "cfp/topic/%s" % topicid
|
request.session['lastlist'] = "cfp/topic/%s" % topicid
|
||||||
return render(request, "topiclist.html",
|
return render(request, "topiclist.html",
|
||||||
@ -89,12 +74,6 @@ def create(request):
|
|||||||
return render(request, 'cfpcreate.html', {'topics': topics, 'form': form})
|
return render(request, 'cfpcreate.html', {'topics': topics, 'form': form})
|
||||||
|
|
||||||
|
|
||||||
def is_editable(proposal, user):
|
|
||||||
return ((not proposal.scheduled) and
|
|
||||||
((proposal.proposer == user and proposal.status != 'A') or
|
|
||||||
topiclead(user, proposal.topic)))
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def details(request, proposalid):
|
def details(request, proposalid):
|
||||||
proposal = Proposal.objects.get(id=proposalid)
|
proposal = Proposal.objects.get(id=proposalid)
|
||||||
@ -120,7 +99,7 @@ def details(request, proposalid):
|
|||||||
def edit(request, proposalid):
|
def edit(request, proposalid):
|
||||||
proposal = Proposal.objects.get(id=proposalid)
|
proposal = Proposal.objects.get(id=proposalid)
|
||||||
if not is_editable(proposal, request.user):
|
if not is_editable(proposal, request.user):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ProposalEditForm(request.POST, instance=proposal)
|
form = ProposalEditForm(request.POST, instance=proposal)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -136,7 +115,7 @@ def edit(request, proposalid):
|
|||||||
def delete(request, proposalid):
|
def delete(request, proposalid):
|
||||||
proposal = Proposal.objects.get(id=proposalid)
|
proposal = Proposal.objects.get(id=proposalid)
|
||||||
if ((proposal.proposer != request.user) or proposal.status in ['A', 'S']):
|
if ((proposal.proposer != request.user) or proposal.status in ['A', 'S']):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
proposal.delete()
|
proposal.delete()
|
||||||
return HttpResponseRedirect('/%s' % request.session['lastlist'])
|
return HttpResponseRedirect('/%s' % request.session['lastlist'])
|
||||||
@ -148,7 +127,7 @@ def switch(request, proposalid):
|
|||||||
proposal = Proposal.objects.get(id=proposalid)
|
proposal = Proposal.objects.get(id=proposalid)
|
||||||
if ((proposal.proposer != request.user)
|
if ((proposal.proposer != request.user)
|
||||||
and not topiclead(request.user, proposal.topic)) or proposal.scheduled:
|
and not topiclead(request.user, proposal.topic)) or proposal.scheduled:
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ProposalSwitchForm(request.POST, instance=proposal)
|
form = ProposalSwitchForm(request.POST, instance=proposal)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -166,9 +145,8 @@ def switch(request, proposalid):
|
|||||||
@login_required
|
@login_required
|
||||||
def review(request, proposalid):
|
def review(request, proposalid):
|
||||||
proposal = Proposal.objects.get(id=proposalid)
|
proposal = Proposal.objects.get(id=proposalid)
|
||||||
#TODO Allow comment while reviewing to be included in email
|
|
||||||
if not topiclead(request.user, proposal.topic):
|
if not topiclead(request.user, proposal.topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
current_status = proposal.status
|
current_status = proposal.status
|
||||||
status_long = proposal.get_status_display()
|
status_long = proposal.get_status_display()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
24
scheduling/forms.py
Normal file
24
scheduling/forms.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# 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.forms import ModelForm
|
||||||
|
|
||||||
|
from odsreg.scheduling.models import Slot
|
||||||
|
|
||||||
|
|
||||||
|
class SlotForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Slot
|
||||||
|
fields = ('title', 'description')
|
@ -14,7 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms import ModelForm
|
|
||||||
from odsreg.cfp.models import Proposal, Topic
|
from odsreg.cfp.models import Proposal, Topic
|
||||||
|
|
||||||
|
|
||||||
@ -48,9 +48,3 @@ class Slot(models.Model):
|
|||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return "%s %s %s" % (self.topic.name, self.room.code, self.start_time)
|
return "%s %s %s" % (self.topic.name, self.room.code, self.start_time)
|
||||||
|
|
||||||
|
|
||||||
class SlotForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = Slot
|
|
||||||
fields = ('title', 'description')
|
|
||||||
|
67
scheduling/utils.py
Normal file
67
scheduling/utils.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
def combined_id(slot):
|
||||||
|
return slot.proposals.order_by('id')[0].id
|
||||||
|
|
||||||
|
|
||||||
|
def combined_title(slot):
|
||||||
|
if slot.title:
|
||||||
|
return slot.title
|
||||||
|
proposals = slot.proposals.all()
|
||||||
|
if len(proposals) > 0:
|
||||||
|
return proposals[0].title
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def combined_description(slot):
|
||||||
|
full_desc = ""
|
||||||
|
proposals = slot.proposals.all()
|
||||||
|
if len(proposals) > 1 or slot.title:
|
||||||
|
full_desc = "This session will include the following subject(s):\n\n"
|
||||||
|
for p in slot.proposals.all():
|
||||||
|
if len(proposals) > 1 or slot.title:
|
||||||
|
full_desc = full_desc + p.title + ":\n\n"
|
||||||
|
full_desc = full_desc + p.description + "\n\n"
|
||||||
|
full_desc += "(Session proposed by %s %s)\n\n" % (
|
||||||
|
p.proposer.first_name, p.proposer.last_name)
|
||||||
|
return full_desc
|
||||||
|
|
||||||
|
|
||||||
|
def full_description(slot):
|
||||||
|
desc = ""
|
||||||
|
if slot.description:
|
||||||
|
desc = slot.description + "\n\n"
|
||||||
|
desc += combined_description(slot)
|
||||||
|
return desc
|
||||||
|
|
||||||
|
|
||||||
|
def htmlize(desc):
|
||||||
|
return desc.replace('\n', '<br />')
|
||||||
|
|
||||||
|
|
||||||
|
def end_time(start_time):
|
||||||
|
"""Rough calculation of end time.
|
||||||
|
Works because we don't start at 08:00 and align on 10's of minutes"""
|
||||||
|
end_minute = int(start_time[-2:]) + 40
|
||||||
|
if end_minute >= 60:
|
||||||
|
end_hour = str(int(start_time[-5:-3]) + 1)
|
||||||
|
end_minute = end_minute - 60
|
||||||
|
if end_minute == 0:
|
||||||
|
return start_time[:-5] + end_hour + ":00"
|
||||||
|
else:
|
||||||
|
return start_time[:-5] + end_hour + ":" + str(end_minute)
|
||||||
|
else:
|
||||||
|
return start_time[:-2] + str(end_minute)
|
@ -18,56 +18,21 @@ import urllib2
|
|||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect, HttpResponseForbidden
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from odsreg.cfp.models import Proposal, Topic
|
from odsreg.cfp.models import Proposal, Topic
|
||||||
from odsreg.cfp.views import topiclead, forbidden
|
from odsreg.cfp.utils import topiclead
|
||||||
from odsreg.scheduling.models import Slot, SlotForm
|
from odsreg.scheduling.forms import SlotForm
|
||||||
|
from odsreg.scheduling.models import Slot
|
||||||
|
from odsreg.scheduling.utils import combined_id, combined_title
|
||||||
def combined_id(slot):
|
from odsreg.scheduling.utils import combined_description, full_description
|
||||||
return slot.proposals.order_by('id')[0].id
|
from odsreg.scheduling.utils import htmlize, end_time
|
||||||
|
|
||||||
|
|
||||||
def combined_title(slot):
|
|
||||||
if slot.title:
|
|
||||||
return slot.title
|
|
||||||
proposals = slot.proposals.all()
|
|
||||||
if len(proposals) > 0:
|
|
||||||
return proposals[0].title
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
|
||||||
def combined_description(slot):
|
|
||||||
full_desc = ""
|
|
||||||
proposals = slot.proposals.all()
|
|
||||||
if len(proposals) > 1 or slot.title:
|
|
||||||
full_desc = "This session will include the following subject(s):\n\n"
|
|
||||||
for p in slot.proposals.all():
|
|
||||||
if len(proposals) > 1 or slot.title:
|
|
||||||
full_desc = full_desc + p.title + ":\n\n"
|
|
||||||
full_desc = full_desc + p.description + "\n\n"
|
|
||||||
full_desc += "(Session proposed by %s %s)\n\n" % (
|
|
||||||
p.proposer.first_name, p.proposer.last_name)
|
|
||||||
return full_desc
|
|
||||||
|
|
||||||
|
|
||||||
def htmlize(desc):
|
|
||||||
return desc.replace('\n', '<br />')
|
|
||||||
|
|
||||||
|
|
||||||
def full_description(slot):
|
|
||||||
desc = ""
|
|
||||||
if slot.description:
|
|
||||||
desc = slot.description + "\n\n"
|
|
||||||
desc += combined_description(slot)
|
|
||||||
return desc
|
|
||||||
|
|
||||||
|
|
||||||
def scheduling(request, topicid):
|
def scheduling(request, topicid):
|
||||||
topic = Topic.objects.get(id=topicid)
|
topic = Topic.objects.get(id=topicid)
|
||||||
if not topiclead(request.user, topic):
|
if not topiclead(request.user, topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
action = request.POST['action']
|
action = request.POST['action']
|
||||||
proposal = Proposal.objects.get(id=request.POST['proposal'])
|
proposal = Proposal.objects.get(id=request.POST['proposal'])
|
||||||
@ -97,25 +62,10 @@ def scheduling(request, topicid):
|
|||||||
'topic': topic})
|
'topic': topic})
|
||||||
|
|
||||||
|
|
||||||
def end_time(start_time):
|
|
||||||
"""Rough calculation of end time.
|
|
||||||
Works because we don't start at 08:00 and align on 10's of minutes"""
|
|
||||||
end_minute = int(start_time[-2:]) + 40
|
|
||||||
if end_minute >= 60:
|
|
||||||
end_hour = str(int(start_time[-5:-3]) + 1)
|
|
||||||
end_minute = end_minute - 60
|
|
||||||
if end_minute == 0:
|
|
||||||
return start_time[:-5] + end_hour + ":00"
|
|
||||||
else:
|
|
||||||
return start_time[:-5] + end_hour + ":" + str(end_minute)
|
|
||||||
else:
|
|
||||||
return start_time[:-2] + str(end_minute)
|
|
||||||
|
|
||||||
|
|
||||||
def publish(request, topicid):
|
def publish(request, topicid):
|
||||||
topic = Topic.objects.get(id=topicid)
|
topic = Topic.objects.get(id=topicid)
|
||||||
if not topiclead(request.user, topic):
|
if not topiclead(request.user, topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
list_calls = ""
|
list_calls = ""
|
||||||
baseurl = "http://%s.sched.org/api/session/" % settings.SCHED_URL
|
baseurl = "http://%s.sched.org/api/session/" % settings.SCHED_URL
|
||||||
for slot in Slot.objects.filter(topic=topicid):
|
for slot in Slot.objects.filter(topic=topicid):
|
||||||
@ -147,7 +97,7 @@ def publish(request, topicid):
|
|||||||
def edit(request, slotid):
|
def edit(request, slotid):
|
||||||
slot = Slot.objects.get(id=slotid)
|
slot = Slot.objects.get(id=slotid)
|
||||||
if not topiclead(request.user, slot.topic):
|
if not topiclead(request.user, slot.topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = SlotForm(request.POST, instance=slot)
|
form = SlotForm(request.POST, instance=slot)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -165,7 +115,7 @@ def edit(request, slotid):
|
|||||||
def swap(request, slotid):
|
def swap(request, slotid):
|
||||||
oldslot = Slot.objects.get(id=slotid)
|
oldslot = Slot.objects.get(id=slotid)
|
||||||
if not topiclead(request.user, oldslot.topic):
|
if not topiclead(request.user, oldslot.topic):
|
||||||
return forbidden()
|
return HttpResponseForbidden("Forbidden")
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
newslotid = int(request.POST['newslotid'])
|
newslotid = int(request.POST['newslotid'])
|
||||||
newslot = Slot.objects.get(id=newslotid, topic=oldslot.topic)
|
newslot = Slot.objects.get(id=newslotid, topic=oldslot.topic)
|
||||||
|
Loading…
Reference in New Issue
Block a user