def voter_exclude(request, election, voter_uuid): user = get_user(request) admin_p = security.user_can_admin_election(user, election) if not election.frozen_at or datetime.datetime.now() <= election.voting_starts_at: raise PermissionDenied('20') # admin requested mixing to start if election.mixing_started: raise PermissionDenied('21') voter = Voter.get_by_election_and_uuid(election, voter_uuid) if not voter: raise PermissionDenied('22') if voter.excluded_at: raise PermissionDenied('23') if request.method == 'POST' and request.POST.get('confirm') == '1': election.zeus_election.exclude_voter(voter.uuid, request.POST.get('reason', '')) return HttpResponseRedirect(reverse(voters_list_pretty, args=[election.uuid])) return render_template(request, 'voter_exclude', { 'election': election, 'voter_o': voter, 'menu_active': 'voters', 'admin_p': admin_p })
def one_election_view(request, election): user = get_user(request) admin_p = security.user_can_admin_election(user, election) can_feature_p = security.user_can_feature_election(user, election) notregistered = False eligible_p = True election_url = get_election_url(election) status_update_message = None vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({ 'token': request.session.get('csrf_token'), 'election_url' : reverse(one_election, args=[election.uuid])})) test_cookie_url = "%s?%s" % (reverse(test_cookie), urllib.urlencode({'continue_url' : vote_url})) voter = get_voter(request, user, election) if voter: # cast any votes? votes = CastVote.get_by_voter(voter) if election.frozen_at: voter.last_visit = datetime.datetime.now() voter.save() else: votes = None trustee = None if request.session.get('helios_trustee_uuid', None): try: trustee = Trustee.objects.get(election=election, uuid=request.session.get('helios_trustee_uuid', None)) except: raise PermissionDenied('15') if not voter and not user and not trustee: raise PermissionDenied('16') # status update message? if election.openreg: if election.voting_has_started: status_update_message = u"Vote in %s" % election.name else: status_update_message = u"Register to vote in %s" % election.name # result! if election.result: status_update_message = u"Results are in for %s" % election.name trustees = Trustee.get_by_election(election) return render_template(request, 'election_view', {'election' : election, 'trustees': trustees, 'admin_p': admin_p, 'user': user, 'voter': voter, 'votes': votes, 'notregistered': notregistered, 'eligible_p': eligible_p, 'can_feature_p': can_feature_p, 'election_url' : election_url, 'vote_url': vote_url, 'menu_active': 'overview', 'trustee': trustee, 'test_cookie_url': test_cookie_url})
def one_election_stats(request, election): user = get_user(request) admin_p = security.user_can_admin_election(user, election) or user.superadmin_p stats_data = {'stats': {'election': list(reports.election_report([election]))[0], 'votes': list(reports.election_votes_report([election], False))}} if request.GET.get('json', None): def handler(obj): if hasattr(obj, 'isoformat'): return obj.isoformat() raise TypeError return HttpResponse(jsonlib.dumps(stats_data, default=handler), mimetype="application/json") return render_template(request, "election_stats", { 'election': election, 'admin_p': admin_p, 'user': user, 'menu_active': 'stats', 'STATS_UPDATE_INTERVAL': getattr(settings, 'HELIOS_STATS_UPDATE_INTERVAL', 2000) })
def list_trustees_view(request, election): trustees = Trustee.get_by_election(election) user = get_user(request) admin_p = security.user_can_admin_election(user, election) return render_template(request, 'list_trustees', { 'election': election, 'trustees': trustees, 'menu_active': 'trustees', 'admin_p':admin_p})
def one_election_set_completed(request, election): user = get_user(request) admin_p = security.user_can_admin_election(user, election) or user.superadmin_p if not user.superadmin_p: raise PermissionDenied('11') election.is_completed = not election.is_completed election.save() return HttpResponseRedirect('/admin/')
def one_election_audited_ballots(request, election): """ UI to show election audited ballots """ user = get_user(request) admin_p = security.user_can_admin_election(user, election) voter = get_voter(request, user, election) if request.GET.has_key('vote_hash'): b = AuditedBallot.get(election, request.GET['vote_hash']) return HttpResponse(b.raw_vote, mimetype="text/plain") after = request.GET.get('after', None) offset= int(request.GET.get('offset', 0)) limit = int(request.GET.get('limit', 100)) audited_ballots = AuditedBallot.get_by_election(election, after=after, limit=limit+1) voter_audited_ballots = AuditedBallot.get_by_election(election, extra={'voter':voter}) more_p = len(audited_ballots) > limit if more_p: audited_ballots = audited_ballots[0:limit] next_after = audited_ballots[limit-1].vote_hash else: next_after = None return render_template(request, 'election_audited_ballots', { 'menu_active': 'audits', 'election': election, 'audited_ballots': audited_ballots, 'voter_audited_ballots': voter_audited_ballots, 'admin_p': admin_p, 'next_after': next_after, 'offset': offset, 'limit': limit, 'offset_plus_one': offset+1, 'offset_plus_limit': offset+limit})
def one_election_candidates(request, election): questions_json = utils.to_json(election.questions) user = get_user(request) admin_p = security.user_can_admin_election(user, election) candidates = [] if not election.questions or len(election.questions) == 0 else\ election.questions[0]['answers'] if admin_p and request.method == "POST": if not election.can_change_candidates(): raise PermissionDenied('26') questions = [] fields = ['surname', 'name', 'father_name', 'department'] surnames = request.POST.getlist('candidates_lastname') names = request.POST.getlist('candidates_name') fathernames = request.POST.getlist('candidates_fathers_name') departments = request.POST.getlist('candidates_department') def filled(c): return c['name'] or c['surname'] or c['father_name'] candidates_data = zip(surnames, names, fathernames, departments) candidates = filter(filled, [dict(zip(fields, d)) for d in candidates_data]) error = None errors = [] for cand in candidates: for key in cand.keys(): if not cand[key]: error = "Invalid entry" errors.append(cand) empty_inputs = range(5) if len(candidates) else range(15) if error: return render_template(request, 'election_candidates', { 'election': election, 'questions_json' : questions_json, 'candidates': candidates, 'error': error, 'departments': election.departments, 'empty_inputs': empty_inputs, 'menu_active': 'candidates', 'admin_p': admin_p}) candidates = sorted(candidates, key=lambda c: c['surname']) question = {} question['answer_urls'] = [None for x in range(len(candidates))] question['choice_type'] = 'stv' question['question'] = 'Candidates choice' question['answers'] = [] question['result_type'] = 'absolute' question['tally_type'] = 'stv' questions.append(question) election.questions = questions election.candidates = candidates election.sort_candidates() election.save() election.update_answers() if election.voter_set.count() == 0: return HttpResponseRedirect(reverse(voters_upload, args=[election.uuid])) return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid])) empty_inputs = range(5) if len(candidates) else range(15) return render_template(request, 'election_candidates', { 'election': election, 'questions_json' : questions_json, 'candidates': election.candidates, 'departments': election.departments, 'empty_inputs': empty_inputs, 'menu_active': 'candidates', 'admin_p': admin_p})
def one_election_questions(request, election): from zeus.forms import QuestionForm, DEFAULT_ANSWERS_COUNT, MAX_QUESTIONS_LIMIT if election.election_type == 'election_parties': from zeus.forms import PartyForm as QuestionForm extra = 1 if election.questions_data: extra = 0 questions_formset = formset_factory(QuestionForm, extra=extra, can_delete=True, can_order=True) user = get_user(request) admin_p = security.user_can_admin_election(user, election) if request.method == "POST": if not election.can_change_questions(): raise PermissionDenied('26') formset = questions_formset(request.POST) if formset.is_valid(): questions_data = [] for question in formset.cleaned_data: if not question: continue # force sort of answers by extracting index from answer key. # cast answer index to integer, otherwise answer_10 would be placed # before answer_2 answer_index = lambda a: int(a[0].replace('answer_', '')) isanswer = lambda a: a[0].startswith('answer_') answer_values = filter(isanswer, question.iteritems()) sorted_answers = sorted(answer_values, key=answer_index) answers = [x[1] for x in sorted_answers] question['answers'] = answers for k in question.keys(): if k in ['DELETE', 'ORDER']: del question[k] questions_data.append(question) election.questions_data = questions_data election.update_answers() election.save() if election.voter_set.count() == 0: return HttpResponseRedirect(reverse(voters_upload, args=[election.uuid])) return HttpResponseRedirect(reverse(one_election_questions, args=[election.uuid])+"#q1") else: data = election.questions_data or None formset = questions_formset(initial=election.questions_data) return render_template(request, 'election_questions', { 'menu_active': 'candidates', 'default_answers_count': DEFAULT_ANSWERS_COUNT, 'formset': formset, 'max_questions_limit': MAX_QUESTIONS_LIMIT, 'election': election, 'admin_p': admin_p})
def voters_email(request, election): user = get_user(request) admin_p = security.user_can_admin_election(user, election) if not helios.VOTERS_EMAIL: return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid])) TEMPLATES = [ ('vote', _('Time to Vote')), ('info', _('Additional Info')) ] default_template = 'vote' if not election.frozen_at: TEMPLATES.pop(0) default_template = 'info' template = request.REQUEST.get('template', default_template) if not template in [t[0] for t in TEMPLATES]: raise Exception("bad template") voter_id = request.REQUEST.get('voter_id', None) if voter_id: voter = Voter.get_by_election_and_voter_id(election, voter_id) if not voter: return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid])) else: voter = None election_url = get_election_url(election) default_subject = render_template_raw(None, 'email/%s_subject.txt' % template, { 'custom_subject': "<SUBJECT>" }) default_body = render_template_raw(None, 'email/%s_body.txt' % template, { 'election' : election, 'election_url' : election_url, 'custom_subject' : default_subject, 'custom_message': '<BODY>', 'voter': {'vote_hash' : '<SMART_TRACKER>', 'name': '<VOTER_NAME>', 'voter_name': '<VOTER_NAME>', 'voter_surname': '<VOTER_SURNAME>', 'voter_login_id': '<VOTER_LOGIN_ID>', 'voter_password': '******', 'audit_passwords': '1', 'get_audit_passwords': ['pass1', 'pass2', '...'], 'get_quick_login_url': '<VOTER_LOGIN_URL>', 'voter_type' : election.voter_set.all()[0].voter_type, 'election' : election} }) if request.method == "GET": email_form = forms.EmailVotersForm() email_form.fields['subject'].initial = dict(TEMPLATES)[template] if voter: email_form.fields['send_to'].widget = email_form.fields['send_to'].hidden_widget() else: email_form = forms.EmailVotersForm(request.POST) if email_form.is_valid(): # the client knows to submit only once with a specific voter_id subject_template = 'email/%s_subject.txt' % template body_template = 'email/%s_body.txt' % template extra_vars = { 'custom_subject' : email_form.cleaned_data['subject'], 'custom_message' : email_form.cleaned_data['body'], 'election_url' : election_url, 'election' : election, } voter_constraints_include = None voter_constraints_exclude = None if voter: tasks.single_voter_email.delay(voter_uuid=voter.uuid, subject_template=subject_template, body_template=body_template, extra_vars=extra_vars) else: # exclude those who have not voted if email_form.cleaned_data['send_to'] == 'voted': voter_constraints_exclude = {'vote_hash' : None} # include only those who have not voted if email_form.cleaned_data['send_to'] == 'not-voted': voter_constraints_include = {'vote_hash': None} tasks.voters_email.delay(election_id=election.id, subject_template=subject_template, body_template=body_template, extra_vars=extra_vars, voter_constraints_include=voter_constraints_include, voter_constraints_exclude=voter_constraints_exclude) # this batch process is all async, so we can return a nice note messages.info(request, "Η αποστολή των email έχει ξεκινήσει.") return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid])) return render_template(request, "voters_email", { 'email_form': email_form, 'election': election, 'voter_o': voter, 'admin_p': admin_p, 'default_subject': default_subject, 'default_body' : default_body, 'template' : template, 'menu_active': 'voters', 'templates' : TEMPLATES})
def voters_list_pretty(request, election): """ Show the list of voters now using Django pagination """ # for django pagination support page = int(request.GET.get('page', 1)) limit = int(request.GET.get('limit', 50)) q = request.GET.get('q','') validate_hash = request.GET.get('vote_hash', "").strip() hash_invalid = None hash_valid = None if validate_hash: try: cast = CastVote.objects.get(verified_at__isnull=False, voter__election=election, vote_hash=validate_hash) hash_valid = "1" except CastVote.DoesNotExist: hash_invalid = "1" order_by = 'user__user_id' # unless it's by alias, in which case we better go by UUID if election.use_voter_aliases: order_by = 'alias' user = get_user(request) admin_p = security.user_can_admin_election(user, election) categories = None eligibility_category_id = None try: if admin_p and can_list_categories(user.user_type): categories = AUTH_SYSTEMS[user.user_type].list_categories(user) eligibility_category_id = election.eligibility_category_id(user.user_type) except AuthenticationExpired: return user_reauth(request, user) # files being processed voter_files = election.voterfile_set.all() # load a bunch of voters # voters = Voter.get_by_election(election, order_by=order_by) voters = Voter.objects.filter(election = election).order_by('voter_surname') if q != '': if election.use_voter_aliases: voters = voters.filter(alias__icontains = q) else: voters = voters.filter(voter_name__icontains = q) total_voters = voters.count() voters_voted = election.voted_count() return render_template(request, 'voters_list', {'election': election, 'voters': voters, 'admin_p': admin_p, 'request': request, 'email_voters': helios.VOTERS_EMAIL, 'limit': limit, 'total_voters': total_voters, 'upload_p': helios.VOTERS_UPLOAD, 'q' : q, 'menu_active': 'voters', 'voter_files': voter_files, 'voted_count': voters_voted, 'hash_valid': hash_valid, 'validate_hash': validate_hash, 'hash_invalid': hash_invalid, 'categories': categories, 'eligibility_category_id' : eligibility_category_id})