def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] if revote and (index+1 <= len(votes)): vote = votes[index] if value is not None: vote.candidate_id = candidate.data else: vote.value = value if value else int(candidate.data) SESSION.add(vote) else: if value is not None: cand_id = candidate.data elif cand_name: cand_id = cand_name[candidate.short_name] else: cand_id = candidate.short_name new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.utcnow(), candidate_id=cand_id, value= value if value else int(candidate.data), ) SESSION.add(new_vote) SESSION.commit()
def process_vote(candidates, election, votes, revote, cand_name=None, value=None): for index in range(len(candidates)): candidate = candidates[index] if revote and (index + 1 <= len(votes)): vote = votes[index] if value is not None: vote.candidate_id = candidate.data else: vote.value = value if value else int(candidate.data) SESSION.add(vote) else: if value is not None: cand_id = candidate.data elif cand_name: cand_id = cand_name[candidate.short_name] else: cand_id = candidate.short_name new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.utcnow(), candidate_id=cand_id, value=value if value else int(candidate.data), ) SESSION.add(new_vote) SESSION.commit()
def admin_edit_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) candidate = models.Candidate.get(SESSION, candidate_id=candidate_id) if not election or not candidate: flask.abort(404) if candidate.election != election: flask.abort(404) form = forms.CandidateForm(obj=candidate) if form.validate_on_submit(): form.populate_obj(candidate) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.edit", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Edit candidate')
def admin_delete_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) candidate = models.Candidate.get(SESSION, candidate_id=candidate_id) if not election or not candidate: flask.abort(404) if candidate.election != election: flask.abort(404) form = forms.ConfirmationForm() if form.validate_on_submit(): candidate_name = candidate.name try: SESSION.delete(candidate) SESSION.commit() flask.flash('Candidate "%s" deleted' % candidate_name) fedmsgshim.publish( topic="candidate.delete", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) except SQLAlchemyError, err: SESSION.rollback() APP.logger.debug('Could not delete candidate') APP.logger.exception(err) flask.flash( 'Could not delete this candidate. Is it already part of an ' 'election?', 'error' ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias))
def admin_delete_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) candidate = models.Candidate.get(SESSION, candidate_id=candidate_id) if not election or not candidate: flask.abort(404) if candidate.election != election: flask.abort(404) form = forms.ConfirmationForm() if form.validate_on_submit(): candidate_name = candidate.name try: SESSION.delete(candidate) SESSION.commit() flask.flash('Candidate "%s" deleted' % candidate_name) fedmsgshim.publish(topic="candidate.delete", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), )) except SQLAlchemyError, err: SESSION.rollback() APP.logger.debug('Could not delete candidate') APP.logger.exception(err) flask.flash( 'Could not delete this candidate. Is it already part of an ' 'election?', 'error') return flask.redirect( flask.url_for('admin_view_election', election_alias=election.alias))
def admin_add_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.CandidateForm() if form.validate_on_submit(): candidate = models.Candidate( election=election, name=form.name.data, url=form.url.data ) SESSION.add(candidate) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Add candidate')
def admin_add_multi_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.MultiCandidateForm() if form.validate_on_submit(): candidates_name = [] for entry in form.candidate.data.strip().split("|"): candidate = entry.split("!") fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: fas_name = FAS2.person_by_username( candidate[0])['human_name'] except (KeyError, AuthError): SESSION.rollback() flask.flash( 'User `%s` does not have a FAS account.' % candidate[0], 'error') return flask.redirect( flask.url_for('admin_add_candidate', election_alias=election_alias)) # No url if len(candidate) == 1: cand = models.Candidate(election=election, name=candidate[0], fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) # With url elif len(candidate) == 2: cand = models.Candidate(election=election, name=candidate[0], url=candidate[1], fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) else: flask.flash("There was an issue!") fedmsgshim.publish(topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=cand.election.to_json(), candidate=cand.to_json(), )) SESSION.commit() flask.flash('Added %s candidates' % len(candidates_name)) return flask.redirect( flask.url_for('admin_view_election', election_alias=election.alias)) return flask.render_template('admin/candidate_multi.html', form=form, submit_text='Add candidates')
def admin_add_multi_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.MultiCandidateForm() if form.validate_on_submit(): candidates_name = [] for entry in form.candidate.data.strip().split("|"): candidate = entry.split("!") fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: fas_name = FAS2.person_by_username( candidate[0])['human_name'] except (KeyError, AuthError), err: SESSION.rollback() flask.flash( 'User `%s` does not have a FAS account.' % candidate[0], 'error') return flask.redirect( flask.url_for( 'admin_add_candidate', election_alias=election_alias)) # No url if len(candidate) == 1: cand = models.Candidate( election=election, name=candidate[0], fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) # With url elif len(candidate) == 2: cand = models.Candidate( election=election, name=candidate[0], url=candidate[1], fas_name=fas_name) SESSION.add(cand) candidates_name.append(cand.name) else: flask.flash("There was an issue!") fedmsgshim.publish( topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=cand.election.to_json(), candidate=cand.to_json(), ) ) SESSION.commit() flask.flash('Added %s candidates' % len(candidates_name)) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias))
def admin_add_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.CandidateForm() if form.validate_on_submit(): fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: if APP.config.get('FASJSON'): user = ACCOUNTS.get_user( username=form.name.data).result fas_name = f'{user['givenname']} {user['surname']}' else: fas_name = ACCOUNTS.person_by_username( form.name.data)['human_name'] except (KeyError, AuthError, APIError): flask.flash( 'User `%s` does not have a FAS account.' % form.name.data, 'error') return flask.redirect( flask.url_for( 'admin_add_candidate', election_alias=election_alias)) candidate = models.Candidate( election=election, name=form.name.data, url=form.url.data, fas_name=fas_name, ) SESSION.add(candidate) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Add candidate')
def vote_range(election): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id, count=True) num_candidates = election.candidates.count() cand_ids = [str(cand.id) for cand in election.candidates] next_action = 'confirm' max_selection = num_candidates if election.max_votes: max_selection = election.max_votes form = forms.get_range_voting_form( candidates=election.candidates, max_range=max_selection) if form.validate_on_submit(): if form.action.data == 'submit': for candidate in form: if candidate.short_name in ['csrf_token', 'action']: continue new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.now(), candidate_id=candidate.short_name, value=candidate.data, ) SESSION.add(new_vote) SESSION.commit() flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back() if form.action.data == 'preview': flask.flash("Please confirm your vote!") next_action = 'vote' usernamemap = build_name_map(election) return flask.render_template( 'vote_range.html', election=election, form=form, num_candidates=num_candidates, max_range=max_selection, usernamemap=usernamemap, nextaction=next_action)
def admin_edit_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) candidate = models.Candidate.get(SESSION, candidate_id=candidate_id) if not election or not candidate: flask.abort(404) if candidate.election != election: flask.abort(404) form = forms.CandidateForm(obj=candidate) if form.validate_on_submit(): form.populate_obj(candidate) if election.candidates_are_fasusers: # pragma: no cover try: if APP.config.get('FASJSON'): user = ACCOUNTS.get_user( username=candidate.name).result candidate.fas_name = f'{user['givenname']} {user['surname']}' else: candidate.fas_name = ACCOUNTS.person_by_username( candidate.name)['human_name'] except (KeyError, AuthError, APIError): SESSION.rollback() flask.flash( 'User `%s` does not have a FAS account.' % candidate.name, 'error') return flask.redirect(flask.url_for( 'admin_edit_candidate', election_alias=election_alias, candidate_id=candidate_id)) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.edit", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Edit candidate')
def admin_add_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.CandidateForm() if form.validate_on_submit(): fas_name = None if election.candidates_are_fasusers: # pragma: no cover try: fas_name = FAS2.person_by_username( form.name.data)['human_name'] except (KeyError, AuthError): flask.flash( 'User `%s` does not have a FAS account.' % form.name.data, 'error') return flask.redirect( flask.url_for( 'admin_add_candidate', election_alias=election_alias)) candidate = models.Candidate( election=election, name=form.name.data, url=form.url.data, fas_name=fas_name, ) SESSION.add(candidate) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Add candidate')
def admin_add_multi_candidate(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.MultiCandidateForm() if form.validate_on_submit(): candidates_name = [] for entry in form.candidate.data.strip().split("|"): candidate = entry.split("!") # No url if len(candidate) == 1: cand = models.Candidate( election=election, name=candidate[0]) SESSION.add(cand) candidates_name.append(cand.name) # With url elif len(candidate) == 2: cand = models.Candidate( election=election, name=candidate[0], url=candidate[1]) SESSION.add(cand) candidates_name.append(cand.name) else: flask.flash("There was an issue!") fedmsgshim.publish( topic="candidate.new", msg=dict( agent=flask.g.fas_user.username, election=cand.election.to_json(), candidate=cand.to_json(), ) ) SESSION.commit() flask.flash('Added %s candidates' % len(candidates_name)) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate_multi.html', form=form, submit_text='Add candidates')
def admin_edit_candidate(election_alias, candidate_id): election = models.Election.get(SESSION, alias=election_alias) candidate = models.Candidate.get(SESSION, candidate_id=candidate_id) if not election or not candidate: flask.abort(404) if candidate.election != election: flask.abort(404) form = forms.CandidateForm(obj=candidate) if form.validate_on_submit(): form.populate_obj(candidate) if election.candidates_are_fasusers: # pragma: no cover try: candidate.fas_name = FAS2.person_by_username( candidate.name)['human_name'] except (KeyError, AuthError): SESSION.rollback() flask.flash( 'User `%s` does not have a FAS account.' % candidate.name, 'error') return flask.redirect(flask.url_for( 'admin_edit_candidate', election_alias=election_alias, candidate_id=candidate_id)) SESSION.commit() flask.flash('Candidate "%s" saved' % candidate.name) fedmsgshim.publish( topic="candidate.edit", msg=dict( agent=flask.g.fas_user.username, election=candidate.election.to_json(), candidate=candidate.to_json(), ) ) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/candidate.html', form=form, submit_text='Edit candidate')
def vote_irc(election): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id, count=True) cand_name = {} for candidate in election.candidates: cand_name[candidate.name] = candidate.id num_candidates = election.candidates.count() next_action = 'confirm' form = forms.get_irc_voting_form( candidates=election.candidates, fasusers=election.candidates_are_fasusers) if form.validate_on_submit(): if form.action.data == 'submit': for candidate in form: if candidate.short_name in ['csrf_token', 'action']: continue new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.now(), candidate_id=cand_name[candidate.short_name], value=candidate.data, ) SESSION.add(new_vote) SESSION.commit() flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back() if form.action.data == 'preview': flask.flash("Please confirm your vote!") next_action = 'vote' return flask.render_template( 'vote_simple.html', election=election, form=form, num_candidates=num_candidates, nextaction=next_action)
def admin_new_election(): form = forms.ElectionForm() if form.validate_on_submit(): if form.max_votes.data: try: form.max_votes.data = int(form.max_votes.data) except ValueError: form.max_votes.data = None else: form.max_votes.data = None election = models.Election( shortdesc=form.shortdesc.data, alias=form.alias.data, description=form.description.data, url=form.url.data, start_date=form.start_date.data, end_date=form.end_date.data, seats_elected=form.seats_elected.data, embargoed=int(form.embargoed.data), voting_type=form.voting_type.data, max_votes=form.max_votes.data, candidates_are_fasusers=int(form.candidates_are_fasusers.data), fas_user=flask.g.fas_user.username, ) # Fix start_date and end_date to use datetime election.start_date = datetime.combine(election.start_date, time()) election.end_date = datetime.combine(election.end_date, time(23, 59, 59)) SESSION.add(election) # Add admin groups if there are any for admin_grp in form.admin_grp.data.split(','): if admin_grp.strip(): admin = models.ElectionAdminGroup( election=election, group_name=admin_grp.strip(), ) SESSION.add(admin) # Add legal voters groups if there are any for voter_grp in form.lgl_voters.data.split(','): if voter_grp.strip(): lglvoters = models.LegalVoter( election=election, group_name=voter_grp.strip(), ) SESSION.add(lglvoters) SESSION.commit() fedmsgshim.publish( topic="election.new", msg=dict( agent=flask.g.fas_user.username, election=election.to_json(), ) ) flask.flash('Election "%s" added' % election.alias) fedmsgshim.publish(topic="election.new", msg=election) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) return flask.render_template( 'admin/election_form.html', form=form, submit_text='Create election')
def vote_select(election): votes = models.Vote.of_user_on_election( SESSION, flask.g.fas_user.username, election.id, count=True) num_candidates = election.candidates.count() cand_name = {} for candidate in election.candidates: cand_name[candidate.name] = candidate.id next_action = 'confirm' max_selection = num_candidates if election.max_votes: max_selection = election.max_votes form = forms.get_select_voting_form( candidates=election.candidates, max_selection=max_selection) if form.validate_on_submit(): cnt = 0 for candidate in form: if candidate.short_name in ['csrf_token', 'action']: continue if candidate.data: cnt += 1 if cnt > max_selection: flask.flash('Too many candidates submitted', 'error') else: if form.action.data == 'submit': for candidate in form: if candidate.short_name in ['csrf_token', 'action']: continue new_vote = models.Vote( election_id=election.id, voter=flask.g.fas_user.username, timestamp=datetime.now(), candidate_id=cand_name[candidate.short_name], value=int(candidate.data), ) SESSION.add(new_vote) SESSION.commit() flask.flash("Your vote has been recorded. Thank you!") return safe_redirect_back() if form.action.data == 'preview': flask.flash("Please confirm your vote!") next_action = 'vote' usernamemap = build_name_map(election) return flask.render_template( 'vote_simple.html', election=election, form=form, num_candidates=num_candidates, max_selection=max_selection, usernamemap=usernamemap, nextaction=next_action)
def admin_edit_election(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.ElectionForm(election.id, obj=election) if form.validate_on_submit(): form.embargoed.data = int(form.embargoed.data) if form.max_votes.data: try: form.max_votes.data = int(form.max_votes.data) except ValueError: form.max_votes.data = None else: form.max_votes.data = None form.candidates_are_fasusers.data = int( form.candidates_are_fasusers.data) form.populate_obj(election) admin_groups = set(election.admin_groups_list) new_groups = set( [grp.strip() for grp in form.admin_grp.data.split(',')]) # Add the new admin groups for admin_grp in new_groups.difference(admin_groups): admin = models.ElectionAdminGroup( election=election, group_name=admin_grp, ) SESSION.add(admin) # Remove the admin groups that were removed with this edition for admin_grp in admin_groups.difference(new_groups): admingrp = models.ElectionAdminGroup.by_election_id_and_name( SESSION, election.id, admin_grp) SESSION.delete(admingrp) legal_voters = set(election.legal_voters_list) new_lgl_voters_groups = set( [grp.strip() for grp in form.lgl_voters.data.split(',') if grp.strip()]) # Add the new legal voter groups for lgl_grp in new_lgl_voters_groups.difference(legal_voters): admin = models.LegalVoter( election=election, group_name=lgl_grp, ) SESSION.add(admin) # Remove the legal voter groups that were removed with this edition for lgl_grp in legal_voters.difference(new_lgl_voters_groups): admingrp = models.LegalVoter.by_election_id_and_name( SESSION, election.id, lgl_grp) SESSION.delete(admingrp) SESSION.commit() fedmsgshim.publish( topic="election.edit", msg=dict( agent=flask.g.fas_user.username, election=election.to_json(), ) ) flask.flash('Election "%s" saved' % election.alias) return flask.redirect(flask.url_for( 'admin_view_election', election_alias=election.alias)) form.admin_grp.data = ', '.join(election.admin_groups_list) form.lgl_voters.data = ', '.join(election.legal_voters_list) return flask.render_template( 'admin/election_form.html', form=form, submit_text='Edit election')
def admin_view_election(election_alias): election = models.Election.get(SESSION, alias=election_alias) if not election: flask.abort(404) form = forms.ElectionForm(election.id, obj=election) if form.validate_on_submit(): form.embargoed.data = int(form.embargoed.data) if form.max_votes.data: try: form.max_votes.data = int(form.max_votes.data) except ValueError: form.max_votes.data = None else: form.max_votes.data = None form.candidates_are_fasusers.data = int( form.candidates_are_fasusers.data) form.populate_obj(election) # Fix start_date and end_date to use datetime election.start_date = datetime.combine(election.start_date, time()) election.end_date = datetime.combine(election.end_date, time(23, 59, 59)) SESSION.add(election) admin_groups = set(election.admin_groups_list) new_groups = set( [grp.strip() for grp in form.admin_grp.data.split(',')]) # Add the new admin groups for admin_grp in new_groups.difference(admin_groups): admin = models.ElectionAdminGroup( election=election, group_name=admin_grp, ) SESSION.add(admin) # Remove the admin groups that were removed with this edition for admin_grp in admin_groups.difference(new_groups): admingrp = models.ElectionAdminGroup.by_election_id_and_name( SESSION, election.id, admin_grp) SESSION.delete(admingrp) legal_voters = set(election.legal_voters_list) new_lgl_voters_groups = set([ grp.strip() for grp in form.lgl_voters.data.split(',') if grp.strip() ]) # Add the new legal voter groups for lgl_grp in new_lgl_voters_groups.difference(legal_voters): admin = models.LegalVoter( election=election, group_name=lgl_grp, ) SESSION.add(admin) # Remove the legal voter groups that were removed with this edition for lgl_grp in legal_voters.difference(new_lgl_voters_groups): admingrp = models.LegalVoter.by_election_id_and_name( SESSION, election.id, lgl_grp) SESSION.delete(admingrp) SESSION.commit() fedmsgshim.publish(topic="election.edit", msg=dict( agent=flask.g.fas_user.username, election=election.to_json(), )) flask.flash('Election "%s" saved' % election.alias) return flask.redirect( flask.url_for('admin_view_election', election_alias=election.alias)) form.admin_grp.data = ', '.join(election.admin_groups_list) form.lgl_voters.data = ', '.join(election.legal_voters_list) return flask.render_template('admin/view_election.html', election=election, form=form, submit_text='Edit election')
def admin_new_election(): form = forms.ElectionForm() if form.validate_on_submit(): if form.max_votes.data: try: form.max_votes.data = int(form.max_votes.data) except ValueError: form.max_votes.data = None else: form.max_votes.data = None election = models.Election( shortdesc=form.shortdesc.data, alias=form.alias.data, description=form.description.data, url=form.url.data, start_date=form.start_date.data, end_date=form.end_date.data, seats_elected=form.seats_elected.data, embargoed=int(form.embargoed.data), voting_type=form.voting_type.data, max_votes=form.max_votes.data, candidates_are_fasusers=int(form.candidates_are_fasusers.data), fas_user=flask.g.fas_user.username, ) # Fix start_date and end_date to use datetime election.start_date = datetime.combine(election.start_date, time()) election.end_date = datetime.combine(election.end_date, time(23, 59, 59)) SESSION.add(election) # Add admin groups if there are any for admin_grp in form.admin_grp.data.split(','): if admin_grp.strip(): admin = models.ElectionAdminGroup( election=election, group_name=admin_grp.strip(), ) SESSION.add(admin) # Add legal voters groups if there are any for voter_grp in form.lgl_voters.data.split(','): if voter_grp.strip(): lglvoters = models.LegalVoter( election=election, group_name=voter_grp.strip(), ) SESSION.add(lglvoters) SESSION.commit() fedmsgshim.publish(topic="election.new", msg=dict( agent=flask.g.fas_user.username, election=election.to_json(), )) flask.flash('Election "%s" added' % election.alias) fedmsgshim.publish(topic="election.new", msg=election) return flask.redirect( flask.url_for('admin_view_election', election_alias=election.alias)) return flask.render_template('admin/election_form.html', form=form, submit_text='Create election')