summaryrefslogtreecommitdiff
path: root/postgresqleu/elections/views.py
blob: 87ea042e62f0190afe42e8f10259c7c4fd1c2e21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.db import connection

from models import Election, Member, Candidate, Vote
from forms import VoteForm
from datetime import date, timedelta

def home(request):
	elections = Election.objects.filter(isopen=True).order_by('startdate')
	open_elections = [e for e in elections if e.startdate<=date.today() and e.enddate>=date.today()]
	past_elections = [e for e in elections if e.startdate<date.today() and e.enddate<date.today()]
	upcoming_elections = [e for e in elections if e.startdate>date.today()]

	return render_to_response('elections/home.html', {
			'open': open_elections,
			'past': past_elections,
			'upcoming': upcoming_elections,
	}, context_instance=RequestContext(request))

def election(request, electionid):
	election = get_object_or_404(Election, pk=electionid)
	if not election.isopen:
		raise Http404("This election is not open (yet)")

	if election.startdate > date.today():
		raise Http404("This election has not started yet")

	if election.enddate < date.today():
		# Election is closed, consider publishing the results
		if not election.resultspublic:
			# If user is an admin, show anyway, otherwise throw an error
			if not request.user.is_superuser:
				raise Http404("The results for this election aren't published yet.")

		# Ok, so we do have the results. Use a custom query to make sure we get decently formatted data
		# and no client-side ORM aggregation
		curs = connection.cursor()
		curs.execute("SELECT c.name, sum(v.score) AS score FROM elections_candidate c INNER JOIN elections_vote v ON c.id=v.candidate_id WHERE v.election_id=%(election)s AND c.election_id=%(election)s GROUP BY c.name ORDER BY 2 DESC", {
				'election': election.pk,
				})
		res = curs.fetchall()
		if len(res) == 0:
			raise Http404('No results found for this election')

		return render_to_response('elections/results.html', {
				'election': election,
				'topscore': res[0][1],
				'scores': [{'name': r[0], 'score': r[1], 'width': 300*r[1]/res[0][1]} for r in res],
				}, context_instance=RequestContext(request))

	if len(election.candidate_set.all()) <= 0:
		raise Http404("This election has no candidates!")

	# Otherwise, we show up the form. This part requires login
	if not request.user.is_authenticated():
		return HttpResponseRedirect("/login/?next=%s" % request.path)

	try:
		member = Member.objects.get(user=request.user)

		# Make sure member has paid
		if not member.paiduntil:
			return render_to_response('elections/mustbemember.html', {},
									  context_instance=RequestContext(request))

		# Make sure that the membership hasn't expired
		if member.paiduntil < date.today():
			return render_to_response('elections/mustbemember.html', {},
									  context_instance=RequestContext(request))

		# Verify that the user has been a member for at least 28 days.
		if member.membersince > election.startdate - timedelta(days=28):
			return render_to_response('elections/memberfourweeks.html', {
					'registered_at': member.paiduntil - timedelta(days=365),
					'mustregbefore': election.startdate - timedelta(days=28),
					'election': election,
					}, context_instance=RequestContext(request))

	except Member.DoesNotExist:
		return render_to_response('elections/mustbemember.html', {},
								  context_instance=RequestContext(request))

	if request.method == "POST":
		form = VoteForm(election, member, data=request.POST)
		if form.is_valid():
			# Save the form
			form.save()
	else:
		# Not a POST, so generate an empty form
		form = VoteForm(election, member)


	return render_to_response('elections/form.html', {
			'form': form,
			'election': election,
	}, context_instance=RequestContext(request))

def candidate(request, election, candidate):
	candidate = get_object_or_404(Candidate, election=election, pk=candidate)

	return render_to_response('elections/candidate.html', {
			'candidate': candidate,
	}, context_instance=RequestContext(request))

@login_required
def ownvotes(request, electionid):
	election = get_object_or_404(Election, pk=electionid)
	if not election.isopen:
		raise Http404("This election is not open (yet)")

	if election.enddate >= date.today():
		raise Http404("This election has not ended yet")

	member = get_object_or_404(Member, user=request.user)

	votes = Vote.objects.select_related().filter(voter=member, election=election).order_by('-score')

	return render_to_response('elections/ownvotes.html', {
			'election': election,
			'votes': votes,
	}, context_instance=RequestContext(request))