예제 #1
0
    def test_election_public(self):
        """ Test the election_public property of Elections. """
        create_elections(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(election.election_public, True)

        election = nuancierlib.get_election(self.session, 2)
        self.assertEqual(election.election_public, False)

        election = nuancierlib.get_election(self.session, 3)
        self.assertEqual(election.election_public, False)
예제 #2
0
    def test_election_public(self):
        """ Test the election_public property of Elections. """
        create_elections(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(election.election_public, True)

        election = nuancierlib.get_election(self.session, 2)
        self.assertEqual(election.election_public, False)

        election = nuancierlib.get_election(self.session, 3)
        self.assertEqual(election.election_public, False)
예제 #3
0
파일: admin.py 프로젝트: grdryn/nuancier
def admin_cache(election_id):
    ''' Regenerate the cache for this election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    next_url = None
    if 'next' in flask.request.args:
        next_url = flask.request.args['next']

    if not next_url or next_url == flask.url_for(
            '.admin_cache', election_id=election_id):
        next_url = flask.url_for('.admin_index')

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    try:
        nuancierlib.generate_cache(
            session=SESSION,
            election=election,
            picture_folder=APP.config['PICTURE_FOLDER'],
            cache_folder=APP.config['CACHE_FOLDER'],
            size=APP.config['THUMB_SIZE'])
        flask.flash('Cache regenerated for election %s' %
                    election.election_name)
    except nuancierlib.NuancierException as err:
        SESSION.rollback()
        LOG.debug('User: "******" could not generate cache for "%s"',
                  flask.g.fas_user.username, election_id)
        LOG.exception(err)
        flask.flash(err.message, 'error')

    return flask.redirect(next_url)
예제 #4
0
    def test_toggle_public(self):
        """ Test the toggle_public function. """
        create_elections(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(True, election.election_public)

        nuancierlib.toggle_public(self.session, 1)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(False, election.election_public)

        nuancierlib.toggle_public(self.session, 1)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(True, election.election_public)
예제 #5
0
파일: admin.py 프로젝트: grdryn/nuancier
def admin_review(election_id):
    ''' Review a new election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')
        return flask.redirect(flask.url_for('admin_index'))

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')
        return flask.redirect(flask.url_for('admin_index'))

    candidates = nuancierlib.get_candidates(SESSION, election_id)

    return flask.render_template(
        'admin_review.html',
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder))
예제 #6
0
    def test_edit_election(self):
        """ Test the edit_election function. """
        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        new_election = nuancierlib.edit_election(
            self.session,
            election=election,
            election_name='elec name',
            election_folder='Test',
            election_year=2048,
            election_date_start=TODAY,
            election_date_end=TODAY + timedelta(days=2),
            submission_date_start=TODAY - timedelta(days=2),
            election_n_choice=42,
            election_badge_link='http://badges.fp.o/1234',
            user='******',
        )

        self.assertEqual(new_election.election_name, 'elec name')
        self.assertEqual(new_election.election_folder, 'Test')
        self.assertEqual(new_election.election_year, 2048)
        self.assertEqual(new_election.election_date_start, TODAY)
        self.assertEqual(
            new_election.election_date_end, TODAY + timedelta(days=2))
        self.assertEqual(
            new_election.submission_date_start, TODAY - timedelta(days=2))
        self.assertEqual(new_election.election_n_choice, 42)
        self.assertEqual(
            new_election.election_badge_link, 'http://badges.fp.o/1234')
예제 #7
0
def admin_review_status(election_id, status):
    ''' Review a new election depending on the status of the candidates. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')

    status = flask.request.args.get('status', status)
    if status == 'all':
        _status = None
    elif status in ['pending', 'denied']:
        _status = False
    else:
        _status = True

    candidates = nuancierlib.get_candidates(SESSION,
                                            election_id,
                                            approved=_status)
    if status == 'pending':
        candidates = [
            candidate for candidate in candidates
            if candidate.approved_motif in [None, '']
        ]
    elif status == 'denied':
        candidates = [
            candidate for candidate in candidates
            if candidate.approved_motif not in [None, '']
        ]

    template = 'admin_review.html'
    if election.election_public or election.election_open \
            or not nuancier.is_nuancier_admin(flask.g.fas_user):
        template = 'admin_review_ro.html'

    return flask.render_template(
        template,
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        picture_folder=os.path.join(APP.config['PICTURE_FOLDER'],
                                    election.election_folder),
        cache_folder=os.path.join(APP.config['CACHE_FOLDER'],
                                  election.election_folder),
        status=status,
    )
예제 #8
0
파일: admin.py 프로젝트: ryanlerch/nuancier
def admin_review_status(election_id, status):
    ''' Review a new election depending on the status of the candidates. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')

    status = flask.request.args.get('status', status)
    if status == 'all':
        _status = None
    elif status in ['pending', 'denied']:
        _status = False
    else:
        _status = True

    candidates = nuancierlib.get_candidates(
        SESSION, election_id, approved=_status
    )
    if status == 'pending':
        candidates = [
            candidate for candidate in candidates
            if candidate.approved_motif in [None, '']
        ]
    elif status == 'denied':
        candidates = [
            candidate for candidate in candidates
            if candidate.approved_motif not in [None, '']
        ]

    template = 'admin_review.html'
    if election.election_public or election.election_open \
            or not nuancier.is_nuancier_admin(flask.g.fas_user):
        template = 'admin_review_ro.html'

    return flask.render_template(
        template,
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder),
        status=status,
    )
예제 #9
0
    def test_elections_repr(self):
        """ Test the __repr__ function of Elections. """
        create_elections(self.session)
        create_candidates(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(
            election.__repr__(),
            "Elections(id:1, name:u'Wallpaper F19', year:2013)"
        )
예제 #10
0
    def test_elections_api_repr(self):
        """ Test the api_repr function of Elections. """
        create_elections(self.session)
        create_candidates(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(
            election.api_repr(1),
            {'name': 'Wallpaper F19', 'year': 2013}
        )
예제 #11
0
def admin_edit(election_id):
    ''' Edit an election. '''
    if not nuancier.is_nuancier_admin(flask.g.fas_user):
        flask.flash('You are not an administrator of nuancier',
                        'error')
        return flask.redirect(flask.url_for('msg'))

    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    form = nuancier.forms.AddElectionForm()
    if flask.request.method == 'GET':
        form = nuancier.forms.AddElectionForm(election=election)

    if form.validate_on_submit():
        try:
            election = nuancierlib.edit_election(
                SESSION,
                election=election,
                election_name=form.election_name.data,
                election_folder=form.election_folder.data,
                election_year=form.election_year.data,
                election_date_start=form.election_date_start.data,
                election_date_end=form.election_date_end.data,
                submission_date_start=form.submission_date_start.data,
                submission_date_end=form.submission_date_end.data,
                election_n_choice=form.election_n_choice.data,
                user_n_candidates=form.user_n_candidates.data,
                election_badge_link=form.election_badge_link.data,
                user=flask.g.fas_user.username,
            )
            SESSION.commit()
            flask.flash('Election updated')
        except SQLAlchemyError as err:
            SESSION.rollback()
            LOG.debug("User: %s could not edit election: %s ",
                      flask.g.fas_user.username, election_id)
            LOG.exception(err)
            flask.flash('Could not edit this election, is this name or '
                        'folder already used?', 'error')
            return flask.render_template(
                'admin_edit.html',
                election=election,
                form=form)

        return flask.redirect(flask.url_for('admin_index'))
    return flask.render_template(
        'admin_edit.html',
        election=election,
        form=form)
예제 #12
0
    def test_generate_cache_no_picture_folder(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        self.assertRaises(nuancierlib.NuancierException,
                          nuancierlib.generate_cache,
                          session=self.session,
                          election=election,
                          picture_folder='none',
                          cache_folder=CACHE_FOLDER,
                          size=(128, 128))
예제 #13
0
def admin_edit(election_id):
    ''' Edit an election. '''
    if not nuancier.is_nuancier_admin(flask.g.fas_user):
        flask.flash('You are not an administrator of nuancier', 'error')
        return flask.redirect(flask.url_for('msg'))

    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    form = nuancier.forms.AddElectionForm()
    if flask.request.method == 'GET':
        form = nuancier.forms.AddElectionForm(election=election)

    if form.validate_on_submit():
        try:
            election = nuancierlib.edit_election(
                SESSION,
                election=election,
                election_name=form.election_name.data,
                election_folder=form.election_folder.data,
                election_year=form.election_year.data,
                election_date_start=form.election_date_start.data,
                election_date_end=form.election_date_end.data,
                submission_date_start=form.submission_date_start.data,
                submission_date_end=form.submission_date_end.data,
                election_n_choice=form.election_n_choice.data,
                user_n_candidates=form.user_n_candidates.data,
                election_badge_link=form.election_badge_link.data,
                user=flask.g.fas_user.username,
            )
            SESSION.commit()
            flask.flash('Election updated')
        except SQLAlchemyError as err:
            SESSION.rollback()
            LOG.debug("User: %s could not edit election: %s ",
                      flask.g.fas_user.username, election_id)
            LOG.exception(err)
            flask.flash(
                'Could not edit this election, is this name or '
                'folder already used?', 'error')
            return flask.render_template('admin_edit.html',
                                         election=election,
                                         form=form)

        return flask.redirect(flask.url_for('admin_index'))
    return flask.render_template('admin_edit.html',
                                 election=election,
                                 form=form)
예제 #14
0
    def test_edit_election(self):
        """ Test the edit_election function. """
        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        self.assertRaises(
            nuancierlib.NuancierException,
            nuancierlib.edit_election,
            session=self.session,
            election=election,
            election_name='elec name',
            election_folder='Test',
            election_year=2048,
            election_date_start=TODAY,
            election_date_end=TODAY + timedelta(days=2),
            submission_date_start=TODAY - timedelta(days=2),
            submission_date_end=TODAY - timedelta(days=1),
            election_n_choice=42,
            user_n_candidates=5,
            election_badge_link='http://badges.fp.o/1234',
        )

        new_election = nuancierlib.edit_election(
            self.session,
            election=election,
            election_name='elec name',
            election_folder='Test',
            election_year=2048,
            election_date_start=TODAY,
            election_date_end=TODAY + timedelta(days=2),
            submission_date_start=TODAY - timedelta(days=2),
            submission_date_end=TODAY - timedelta(days=1),
            election_n_choice=42,
            user_n_candidates=5,
            election_badge_link='http://badges.fp.o/1234',
            user='******',
        )

        self.assertEqual(new_election.election_name, 'elec name')
        self.assertEqual(new_election.election_folder, 'Test')
        self.assertEqual(new_election.election_year, 2048)
        self.assertEqual(new_election.election_date_start, TODAY)
        self.assertEqual(new_election.election_date_end,
                         TODAY + timedelta(days=2))
        self.assertEqual(new_election.submission_date_start,
                         TODAY - timedelta(days=2))
        self.assertEqual(new_election.submission_date_end,
                         TODAY - timedelta(days=1))
        self.assertEqual(new_election.election_n_choice, 42)
        self.assertEqual(new_election.election_badge_link,
                         'http://badges.fp.o/1234')
예제 #15
0
    def test_elections_repr(self):
        """ Test the __repr__ function of Elections. """
        create_elections(self.session)
        create_candidates(self.session)

        election = nuancierlib.get_election(self.session, 1)
        if six.PY2:
            self.assertEqual(
                election.__repr__(),
                "Elections(id:1, name:u'Wallpaper F19', year:2013)")
        else:
            self.assertEqual(
                election.__repr__(),
                "Elections(id:1, name:'Wallpaper F19', year:2013)")
예제 #16
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def vote(election_id):
    ''' Give the possibility to the user to vote for an election. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')
    candidates = nuancierlib.get_candidates(SESSION,
                                            election_id,
                                            approved=True)

    if not election.election_open:
        flask.flash('This election is not open', 'error')
        return flask.redirect(flask.url_for('index'))

    if flask.g.fas_user:
        username = flask.g.fas_user.username
        if not isinstance(username, six.binary_type):
            username = username.encode('utf-8')
        random.seed(int(hashlib.sha1(username).hexdigest(), 16) % 100000)
    random.shuffle(candidates)

    # How many votes the user made:
    votes = nuancierlib.get_votes_user(SESSION, election_id,
                                       flask.g.fas_user.username)

    if len(votes) >= election.election_n_choice:
        flask.flash(
            'You have cast the maximal number of votes '
            'allowed for this election.', 'error')
        return flask.redirect(
            flask.url_for('election', election_id=election_id))

    if len(votes) > 0:
        candidate_done = [cdt.candidate_id for cdt in votes]
        candidates = [
            candidate for candidate in candidates
            if candidate.id not in candidate_done
        ]

    return flask.render_template(
        'vote.html',
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        n_votes_done=len(votes),
        picture_folder=os.path.join(APP.config['PICTURE_FOLDER'],
                                    election.election_folder),
        cache_folder=os.path.join(APP.config['CACHE_FOLDER'],
                                  election.election_folder))
예제 #17
0
    def test_generate_cache_no_picture_folder(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        self.assertRaises(
            nuancierlib.NuancierException,
            nuancierlib.generate_cache,
            session=self.session,
            election=election,
            picture_folder='none',
            cache_folder=CACHE_FOLDER,
            size=(128, 128)
        )
예제 #18
0
    def test_elections_api_repr(self):
        """ Test the api_repr function of Elections. """
        create_elections(self.session)
        create_candidates(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(
            election.api_repr(1), {
                'date_end': TODAY - timedelta(days=8),
                'date_start': TODAY - timedelta(days=10),
                'id': 1,
                'name': u'Wallpaper F19',
                'submission_date_start': TODAY - timedelta(days=15),
                'submission_date_end': TODAY - timedelta(days=13),
                'year': 2013
            })
예제 #19
0
    def test_generate_cache(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        create_candidates(self.session)
        election = nuancierlib.get_election(self.session, 2)

        self.assertFalse(os.path.exists(CACHE_FOLDER))

        nuancierlib.generate_cache(session=self.session,
                                   election=election,
                                   picture_folder=PICTURE_FOLDER,
                                   cache_folder=CACHE_FOLDER,
                                   size=(128, 128))

        self.assertTrue(os.path.exists(CACHE_FOLDER))
예제 #20
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def vote(election_id):
    ''' Give the possibility to the user to vote for an election. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')
    candidates = nuancierlib.get_candidates(
        SESSION, election_id, approved=True)

    if not election.election_open:
        flask.flash('This election is not open', 'error')
        return flask.redirect(flask.url_for('index'))

    if flask.g.fas_user:
        random.seed(
            int(
                hashlib.sha1(flask.g.fas_user.username).hexdigest(), 16
            ) % 100000)
    random.shuffle(candidates)

    # How many votes the user made:
    votes = nuancierlib.get_votes_user(SESSION, election_id,
                                       flask.g.fas_user.username)

    if len(votes) >= election.election_n_choice:
        flask.flash('You have cast the maximal number of votes '
                    'allowed for this election.', 'error')
        return flask.redirect(
            flask.url_for('election', election_id=election_id))

    if len(votes) > 0:
        candidate_done = [cdt.candidate_id for cdt in votes]
        candidates = [candidate
                      for candidate in candidates
                      if candidate.id not in candidate_done]

    return flask.render_template(
        'vote.html',
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        n_votes_done=len(votes),
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder)
    )
예제 #21
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def stats(election_id):
    ''' Return some stats about this election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_public:
        flask.flash('The results this election are not public yet', 'error')
        return flask.redirect(flask.url_for('results_list'))

    statsinfo = nuancierlib.get_stats(SESSION, election_id)

    return flask.render_template('stats.html',
                                 stats=statsinfo,
                                 election=election)
예제 #22
0
    def test_elections_api_repr(self):
        """ Test the api_repr function of Elections. """
        create_elections(self.session)
        create_candidates(self.session)

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(
            election.api_repr(1),
            {
                'date_end': TODAY - timedelta(days=8),
                'date_start': TODAY - timedelta(days=10),
                'id': 1,
                'name': u'Wallpaper F19',
                'submission_date_start': TODAY - timedelta(days=15),
                'year': 2013
            }
        )
예제 #23
0
    def test_generate_cache_cache_folder_is_file(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        stream = open(CACHE_FOLDER, 'w')
        stream.write('test')
        stream.close()

        self.assertRaises(nuancierlib.NuancierException,
                          nuancierlib.generate_cache,
                          session=self.session,
                          election=election,
                          picture_folder=PICTURE_FOLDER,
                          cache_folder=CACHE_FOLDER,
                          size=(128, 128))
예제 #24
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def election(election_id):
    ''' Display the index page of the election will all the candidates
    submitted. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    # How many votes the user made:
    votes = []
    can_vote = True
    if hasattr(flask.g, 'fas_user') and flask.g.fas_user:
        votes = nuancierlib.get_votes_user(SESSION, election_id,
                                           flask.g.fas_user.username)

    if election.election_open and len(votes) < election.election_n_choice:
        if len(votes) > 0:
            flask.flash('You have already voted, but you can still vote '
                        'on more candidates.')
        return flask.redirect(flask.url_for('vote', election_id=election_id))
    elif election.election_open and len(votes) >= election.election_n_choice:
        can_vote = False
    elif not election.election_public:
        flask.flash('This election is not open', 'error')
        return flask.redirect(flask.url_for('elections_list'))

    candidates = nuancierlib.get_candidates(
        SESSION, election_id, approved=True)

    if hasattr(flask.g, 'fas_user') and flask.g.fas_user:
        random.seed(
            int(
                hashlib.sha1(flask.g.fas_user.username).hexdigest(), 16
            ) % 100000)
    random.shuffle(candidates)

    return flask.render_template(
        'election.html',
        candidates=candidates,
        election=election,
        can_vote=can_vote,
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder)
    )
예제 #25
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def election(election_id):
    ''' Display the index page of the election will all the candidates
    submitted. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    # How many votes the user made:
    votes = []
    can_vote = True
    if hasattr(flask.g, 'fas_user') and flask.g.fas_user:
        votes = nuancierlib.get_votes_user(SESSION, election_id,
                                           flask.g.fas_user.username)

    if election.election_open and len(votes) < election.election_n_choice:
        if len(votes) > 0:
            flask.flash('You have already voted, but you can still vote '
                        'on more candidates.')
        return flask.redirect(flask.url_for('vote', election_id=election_id))
    elif election.election_open and len(votes) >= election.election_n_choice:
        can_vote = False
    elif not election.election_public:
        flask.flash('This election is not open', 'error')
        return flask.redirect(flask.url_for('elections_list'))

    candidates = nuancierlib.get_candidates(SESSION,
                                            election_id,
                                            approved=True)

    if hasattr(flask.g, 'fas_user') and flask.g.fas_user:
        username = flask.g.fas_user.username
        if not isinstance(username, six.binary_type):
            username = username.encode('utf-8')
        random.seed(int(hashlib.sha1(username).hexdigest(), 16) % 100000)
    random.shuffle(candidates)

    return flask.render_template(
        'election.html',
        candidates=candidates,
        election=election,
        can_vote=can_vote,
        picture_folder=os.path.join(APP.config['PICTURE_FOLDER'],
                                    election.election_folder),
        cache_folder=os.path.join(APP.config['CACHE_FOLDER'],
                                  election.election_folder))
예제 #26
0
    def test_generate_cache(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        self.assertFalse(os.path.exists(CACHE_FOLDER))

        nuancierlib.generate_cache(
            session=self.session,
            election=election,
            picture_folder=PICTURE_FOLDER,
            cache_folder=CACHE_FOLDER,
            size=(128, 128)
        )

        self.assertTrue(os.path.exists(CACHE_FOLDER))
예제 #27
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def stats(election_id):
    ''' Return some stats about this election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_public:
        flask.flash('The results this election are not public yet', 'error')
        return flask.redirect(flask.url_for('results_list'))

    statsinfo = nuancierlib.get_stats(SESSION, election_id)

    return flask.render_template(
        'stats.html',
        stats=statsinfo,
        election=election)
예제 #28
0
    def test_election_public_today(self):
        """ Test the election_public property for today. """
        today = datetime.utcnow().date()
        election = model.Elections(
            election_name='Wallpaper F19',
            election_folder='F19',
            election_year='2013',
            election_n_choice=2,
            submission_date_start=today - timedelta(days=4),
            election_date_start=today - timedelta(days=2),
            election_date_end=today,
        )
        self.session.add(election)
        self.session.commit()

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(election.submission_open, False)
        self.assertEqual(election.election_open, False)
        self.assertEqual(election.election_public, True)
예제 #29
0
    def test_generate_cache_cache_folder_is_file(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 2)

        stream = open(CACHE_FOLDER, 'w')
        stream.write('test')
        stream.close()

        self.assertRaises(
            nuancierlib.NuancierException,
            nuancierlib.generate_cache,
            session=self.session,
            election=election,
            picture_folder=PICTURE_FOLDER,
            cache_folder=CACHE_FOLDER,
            size=(128, 128)
        )
예제 #30
0
    def test_election_public_today(self):
        """ Test the election_public property for today. """
        today = datetime.utcnow().date()
        election = model.Elections(
            election_name='Wallpaper F19',
            election_folder='F19',
            election_year='2013',
            election_n_choice=2,
            submission_date_start=today - timedelta(days=4),
            submission_date_end=today - timedelta(days=3),
            election_date_start=today - timedelta(days=2),
            election_date_end=today,
        )
        self.session.add(election)
        self.session.commit()

        election = nuancierlib.get_election(self.session, 1)
        self.assertEqual(election.submission_open, False)
        self.assertEqual(election.election_open, False)
        self.assertEqual(election.election_public, True)
예제 #31
0
def admin_review(election_id):
    ''' Review a new election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')

    status = flask.request.args.get('status', 'all')
    if status == 'all':
        status = None

    candidates = nuancierlib.get_candidates(
        SESSION, election_id, approved=status
    )

    template = 'admin_review.html'
    if election.election_public or election.election_open \
            or not nuancier.is_nuancier_admin(flask.g.fas_user):
        template = 'admin_review_ro.html'

    return flask.render_template(
        template,
        election=election,
        form=nuancier.forms.ConfirmationForm(),
        candidates=candidates,
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder))
예제 #32
0
def admin_cache(election_id):
    ''' Regenerate the cache for this election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    next_url = None
    if 'next' in flask.request.args:
        next_url = flask.request.args['next']

    if not next_url or next_url == flask.url_for('.admin_cache',
                                                 election_id=election_id):
        next_url = flask.url_for('.admin_index')

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    try:
        nuancierlib.generate_cache(session=SESSION,
                                   election=election,
                                   picture_folder=APP.config['PICTURE_FOLDER'],
                                   cache_folder=APP.config['CACHE_FOLDER'],
                                   size=APP.config['THUMB_SIZE'])
        flask.flash('Cache regenerated for election %s' %
                    election.election_name)
    except nuancierlib.NuancierMultiExceptions as multierr:  # pragma: no cover
        SESSION.rollback()
        LOG.debug('User: "******" could not generate cache for "%s"',
                  flask.g.fas_user.username, election_id)
        LOG.exception(multierr.messages)
        for msg in multierr.messages:
            flask.flash(msg, 'error')
    except nuancierlib.NuancierException as err:
        SESSION.rollback()
        LOG.debug('User: "******" could not generate cache for "%s"',
                  flask.g.fas_user.username, election_id)
        LOG.exception(err)
        flask.flash(str(err), 'error')

    return flask.redirect(next_url)
예제 #33
0
파일: admin.py 프로젝트: ryanlerch/nuancier
def admin_review(election_id, status='all'):
    ''' Review a new election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')

    status = flask.request.args.get('status', status)

    return flask.redirect(flask.url_for(
        'admin_review_status', election_id=election_id, status=status))
예제 #34
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def results(election_id):
    ''' Displays the results of an election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_public:
        flask.flash('The results this election are not public yet', 'error')
        return flask.redirect(flask.url_for('results_list'))

    election_results = nuancierlib.get_results(SESSION, election_id)

    return flask.render_template(
        'results.html',
        election=election,
        results=election_results,
        picture_folder=os.path.join(APP.config['PICTURE_FOLDER'],
                                    election.election_folder),
        cache_folder=os.path.join(APP.config['CACHE_FOLDER'],
                                  election.election_folder))
예제 #35
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def results(election_id):
    ''' Displays the results of an election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_public:
        flask.flash('The results this election are not public yet', 'error')
        return flask.redirect(flask.url_for('results_list'))

    election_results = nuancierlib.get_results(SESSION, election_id)

    return flask.render_template(
        'results.html',
        election=election,
        results=election_results,
        picture_folder=os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder),
        cache_folder=os.path.join(
            APP.config['CACHE_FOLDER'], election.election_folder))
예제 #36
0
    def test_generate_cache_wrong_info_file(self):
        """ Test the generate_cache function. """

        create_elections(self.session)
        election = nuancierlib.get_election(self.session, 3)

        info_file = os.path.join(PICTURE_FOLDER, election.election_folder,
                                 'infos.txt')
        stream = open(info_file, 'w')
        stream.write('test')
        stream.close()

        self.assertRaises(
            nuancierlib.NuancierException,
            nuancierlib.generate_cache,
            session=self.session,
            election=election,
            picture_folder=PICTURE_FOLDER,
            cache_folder=CACHE_FOLDER,
            size=(128, 128)
        )

        os.unlink(info_file)
예제 #37
0
def admin_review(election_id, status='all'):
    ''' Review a new election. '''
    election = nuancierlib.get_election(SESSION, election_id)

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')

    status = flask.request.args.get('status', status)

    return flask.redirect(
        flask.url_for('admin_review_status',
                      election_id=election_id,
                      status=status))
예제 #38
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def process_vote(election_id):
    ''' Actually register the vote, after checking if the user is actually
    allowed to vote.
    '''

    form = nuancier.forms.ConfirmationForm()
    if not form.validate_on_submit():
        flask.flash('Wrong input submitted', 'error')
        return flask.render_template('msg.html')

    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_open:
        flask.flash('This election is not open', 'error')
        return flask.render_template('msg.html')

    candidates = nuancierlib.get_candidates(SESSION,
                                            election_id,
                                            approved=True)
    candidate_ids = set([candidate.id for candidate in candidates])

    entries = set(
        [int(entry) for entry in flask.request.form.getlist('selection')])

    # If not enough candidates selected
    if not entries:
        flask.flash('You did not select any candidate to vote for.', 'error')
        return flask.redirect(flask.url_for('vote', election_id=election_id))

    # If vote on candidates from other elections
    if not set(entries).issubset(candidate_ids):
        flask.flash(
            'The selection you have made contains element which are '
            'not part of this election, please be careful.', 'error')
        return flask.redirect(flask.url_for('vote', election_id=election_id))

    # How many votes the user made:
    votes = nuancierlib.get_votes_user(SESSION, election_id,
                                       flask.g.fas_user.username)

    # Too many votes -> redirect
    if len(votes) >= election.election_n_choice:
        flask.flash(
            'You have cast the maximal number of votes '
            'allowed for this election.', 'error')
        return flask.redirect(
            flask.url_for('election', election_id=election_id))

    # Selected more candidates than allowed -> redirect
    if len(votes) + len(entries) > election.election_n_choice:
        flask.flash(
            'You selected %s wallpapers while you are only allowed '
            'to select %s' % (len(entries),
                              (election.election_n_choice - len(votes))),
            'error')
        return flask.render_template(
            'vote.html',
            form=nuancier.forms.ConfirmationForm(),
            election=election,
            candidates=[
                nuancierlib.get_candidate(SESSION, candidate_id)
                for candidate_id in entries
            ],
            n_votes_done=len(votes),
            picture_folder=os.path.join(APP.config['PICTURE_FOLDER'],
                                        election.election_folder),
            cache_folder=os.path.join(APP.config['CACHE_FOLDER'],
                                      election.election_folder))

    # Allowed to vote, selection sufficient, choice confirmed: process
    for selection in entries:
        value = 1
        if nuancier.has_weigthed_vote(flask.g.fas_user):
            value = 2
        nuancierlib.add_vote(SESSION,
                             selection,
                             flask.g.fas_user.username,
                             value=value)

    try:
        SESSION.commit()
    except SQLAlchemyError as err:  # pragma: no cover
        SESSION.rollback()
        LOG.debug(
            'ERROR: could not process the vote - user: "******" '
            'election: "%s"', flask.g.fas_user.username, election_id)
        LOG.exception(err)
        flask.flash(
            'An error occured while processing your votes, please '
            'report this to your lovely admin or see logs for '
            'more details', 'error')

    flask.flash('Your vote has been recorded, thank you for voting on '
                '%s %s' % (election.election_name, election.election_year))

    if election.election_badge_link:
        flask.flash('Do not forget to <a href="%s" target="_blank">claim your '
                    'badge!</a>' % election.election_badge_link)
    return flask.redirect(flask.url_for('elections_list'))
예제 #39
0
def admin_process_review(election_id):
    ''' Process the reviewing of a new election. '''
    if not nuancier.is_nuancier_admin(flask.g.fas_user):
        flask.flash('You are not an administrator of nuancier', 'error')
        return flask.redirect(flask.url_for('msg'))

    status = flask.request.args.get('status', None)
    endpoint = 'admin_review'
    if status:
        endpoint = 'admin_review_status'

    election = nuancierlib.get_election(SESSION, election_id)

    form = nuancier.forms.ConfirmationForm()
    if not form.validate_on_submit():
        flask.flash('Wrong input submitted', 'error')
        return flask.render_template('msg.html')

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')
        return flask.redirect(flask.url_for('results_list'))

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')
        return flask.redirect(flask.url_for('results_list'))

    candidates = nuancierlib.get_candidates(SESSION, election_id)
    candidates_id = [str(candidate.id) for candidate in candidates]

    candidates_selected = flask.request.form.getlist('candidates_id')
    motifs = flask.request.form.getlist('motifs')
    action = flask.request.form.get('action')

    if action:
        action = action.strip()

    if action not in ['Approved', 'Denied']:
        flask.flash('Only the actions "Approved" or "Denied" are accepted',
                    'error')
        return flask.redirect(
            flask.url_for(endpoint, election_id=election_id, status=status))

    selections = []
    for cand in candidates_id:
        if cand not in candidates_selected:
            selections.append(None)
        else:
            selections.append(cand)

    if action == 'Denied':
        req_motif = False
        if not motifs:
            req_motif = True
        for cnt in range(len(motifs)):
            motif = motifs[cnt]
            if selections[cnt] and not motif.strip():
                req_motif = True
                break
        if req_motif:
            flask.flash('You must provide a reason to deny a candidate',
                        'error')
            return flask.redirect(
                flask.url_for(endpoint, election_id=election_id,
                              status=status))

    cnt = 0
    for candidate in candidates_selected:
        if candidate not in candidates_id:
            flask.flash(
                'One of the candidate submitted was not candidate in this '
                'election', 'error')
            return flask.redirect(
                flask.url_for(endpoint, election_id=election_id,
                              status=status))

    msgs = []

    for candidate in selections:
        if candidate:
            candidate = nuancierlib.get_candidate(SESSION, candidate)
            motif = None
            if len(motifs) > cnt:
                motif = motifs[cnt].strip()
            if action == 'Approved':
                candidate.approved = True
                candidate.approved_motif = motif
            else:
                candidate.approved = False
                candidate.approved_motif = motif
                if APP.config.get('NUANCIER_EMAIL_NOTIFICATIONS',
                                  False):  # pragma: no cover
                    nuancierlib.notifications.email_publish(
                        to_email=candidate.submitter_email,
                        img_title=candidate.candidate_name,
                        motif=motif)
                else:
                    LOG.warning(
                        'Should have sent an email to "%s" about "%s" that has'
                        ' been rejected because of "%s"',
                        candidate.submitter_email, candidate.candidate_name,
                        motif)

            SESSION.add(candidate)
            msgs.append({
                'topic':
                'candidate.%s' % (action.lower()),
                'msg':
                dict(
                    agent=flask.g.fas_user.username,
                    election=election.api_repr(version=1),
                    candidate=candidate.api_repr(version=1),
                )
            })
        cnt += 1

    try:
        SESSION.commit()
    except SQLAlchemyError as err:  # pragma: no cover
        SESSION.rollback()
        LOG.debug(
            'User: "******" could not approve/deny candidate(s) for '
            'election "%s"', flask.g.fas_user.username, election_id)
        LOG.exception(err)
        flask.flash('Could not approve/deny candidate', 'error')

    flask.flash('Candidate(s) updated')

    for msg in msgs:
        nuancierlib.notifications.publish(
            topic=msg['topic'],
            msg=msg['msg'],
        )

    return flask.redirect(
        flask.url_for(endpoint, election_id=election_id, status=status))
예제 #40
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def contribute(election_id):
    ''' Display the index page for interested contributor. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')
    elif not election.submission_open:
        flask.flash('This election is not open for submission', 'error')
        return flask.redirect(flask.url_for('elections_list'))

    candidates = nuancier.lib.model.Candidates.get_by_submitter(
        SESSION, flask.g.fas_user.username, election_id)
    if election.user_n_candidates and \
        len(candidates) >= election.user_n_candidates:
        flask.flash(
            'You have uploaded the maximum number of candidates (%s) you '
            'can upload for this election' % election.user_n_candidates,
            'error')
        return flask.redirect(flask.url_for('elections_list'))

    form = nuancier.forms.AddCandidateForm()
    if form.validate_on_submit():
        candidate_file = flask.request.files['candidate_file']

        try:
            validate_input_file(candidate_file)
        except nuancierlib.NuancierException as err:
            LOG.debug('ERROR: Uploaded file is invalid - user: "******" '
                      'election: "%s"', flask.g.fas_user.username,
                      election_id)
            LOG.exception(err)
            flask.flash(err.message, 'error')
            return flask.render_template(
                'contribute.html',
                election=election,
                form=form)

        filename = secure_filename('%s-%s' % (flask.g.fas_user.username,
                                   candidate_file.filename))

        # Only save the file once everything has been safely saved in the DB
        upload_folder = os.path.join(
            APP.config['PICTURE_FOLDER'], election.election_folder)
        if not os.path.exists(upload_folder):  # pragma: no cover
            try:
                os.mkdir(upload_folder)
            except OSError, err:
                LOG.debug('ERROR: cannot add candidate file')
                LOG.exception(err)
                flask.flash(
                    'An error occured while writing the file, please '
                    'contact an administrator', 'error')
                return flask.render_template(
                    'contribute.html',
                    election=election,
                    form=form)

        # Save candidate to the database
        try:
            nuancierlib.add_candidate(
                SESSION,
                candidate_file=filename,
                candidate_name=form.candidate_name.data,
                candidate_author=form.candidate_author.data,
                candidate_original_url=form.candidate_original_url.data,
                candidate_license=form.candidate_license.data,
                candidate_submitter=flask.g.fas_user.username,
                submitter_email=flask.g.fas_user.email,
                election_id=election.id,
                user=flask.g.fas_user.username,
            )
        except nuancierlib.NuancierException as err:
            flask.flash(err.message, 'error')
            return flask.render_template(
                'contribute.html',
                election=election,
                form=form)

        # The PIL module has already read the stream so we need to back up
        candidate_file.seek(0)

        candidate_file.save(
            os.path.join(upload_folder, filename))

        try:
            SESSION.commit()
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            # Remove file from the system if the db commit failed
            os.unlink(os.path.join(upload_folder, filename))
            LOG.debug('ERROR: cannot add candidate - user: "******" '
                      'election: "%s"', flask.g.fas_user.username,
                      election_id)
            LOG.exception(err)
            flask.flash(
                'Someone has already upload a file with the same file name'
                ' for this election', 'error')
            return flask.render_template(
                'contribute.html',
                election=election,
                form=form)

        flask.flash('Thanks for your submission')
        return flask.redirect(flask.url_for('index'))
예제 #41
0
    def test_get_election(self):
        """ Test the get_election function. """
        create_elections(self.session)

        election = nuancierlib.get_election(self.session, 3)
        self.assertEqual('Wallpaper F21', election.election_name)
예제 #42
0
파일: ui.py 프로젝트: ryanlerch/nuancier
def process_vote(election_id):
    ''' Actually register the vote, after checking if the user is actually
    allowed to vote.
    '''

    form = nuancier.forms.ConfirmationForm()
    if not form.validate_on_submit():
        flask.flash('Wrong input submitted', 'error')
        return flask.render_template('msg.html')

    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if not election.election_open:
        flask.flash('This election is not open', 'error')
        return flask.render_template('msg.html')

    candidates = nuancierlib.get_candidates(
        SESSION, election_id, approved=True)
    candidate_ids = set([candidate.id for candidate in candidates])

    entries = set([int(entry)
                   for entry in flask.request.form.getlist('selection')])

    # If not enough candidates selected
    if not entries:
        flask.flash('You did not select any candidate to vote for.', 'error')
        return flask.redirect(flask.url_for('vote', election_id=election_id))

    # If vote on candidates from other elections
    if not set(entries).issubset(candidate_ids):
        flask.flash('The selection you have made contains element which are '
                    'not part of this election, please be careful.', 'error')
        return flask.redirect(flask.url_for('vote', election_id=election_id))

    # How many votes the user made:
    votes = nuancierlib.get_votes_user(SESSION, election_id,
                                       flask.g.fas_user.username)

    # Too many votes -> redirect
    if len(votes) >= election.election_n_choice:
        flask.flash('You have cast the maximal number of votes '
                    'allowed for this election.', 'error')
        return flask.redirect(
            flask.url_for('election', election_id=election_id))

    # Selected more candidates than allowed -> redirect
    if len(votes) + len(entries) > election.election_n_choice:
        flask.flash('You selected %s wallpapers while you are only allowed '
                    'to select %s' % (
                        len(entries),
                        (election.election_n_choice - len(votes))),
                    'error')
        return flask.render_template(
            'vote.html',
            form=nuancier.forms.ConfirmationForm(),
            election=election,
            candidates=[nuancierlib.get_candidate(SESSION, candidate_id)
                        for candidate_id in entries],
            n_votes_done=len(votes),
            picture_folder=os.path.join(
                APP.config['PICTURE_FOLDER'], election.election_folder),
            cache_folder=os.path.join(
                APP.config['CACHE_FOLDER'], election.election_folder)
        )

    # Allowed to vote, selection sufficient, choice confirmed: process
    for selection in entries:
        value = 1
        if nuancier.has_weigthed_vote(flask.g.fas_user):
            value = 2
        nuancierlib.add_vote(
            SESSION, selection, flask.g.fas_user.username, value=value)

    try:
        SESSION.commit()
    except SQLAlchemyError as err:  # pragma: no cover
        SESSION.rollback()
        LOG.debug('ERROR: could not process the vote - user: "******" '
                  'election: "%s"', flask.g.fas_user.username,
                  election_id)
        LOG.exception(err)
        flask.flash('An error occured while processing your votes, please '
                    'report this to your lovely admin or see logs for '
                    'more details', 'error')

    flask.flash('Your vote has been recorded, thank you for voting on '
                '%s %s' % (election.election_name, election.election_year))

    if election.election_badge_link:
        flask.flash('Do not forget to <a href="%s" target="_blank">claim your '
                    'badge!</a>' % election.election_badge_link)
    return flask.redirect(flask.url_for('elections_list'))
예제 #43
0
파일: admin.py 프로젝트: ryanlerch/nuancier
def admin_process_review(election_id):
    ''' Process the reviewing of a new election. '''
    if not nuancier.is_nuancier_admin(flask.g.fas_user):
        flask.flash('You are not an administrator of nuancier',
                        'error')
        return flask.redirect(flask.url_for('msg'))

    status = flask.request.args.get('status', None)
    endpoint = 'admin_review'
    if status:
        endpoint = 'admin_review_status'

    election = nuancierlib.get_election(SESSION, election_id)

    form = nuancier.forms.ConfirmationForm()
    if not form.validate_on_submit():
        flask.flash('Wrong input submitted', 'error')
        return flask.render_template('msg.html')

    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')

    if election.election_open:
        flask.flash(
            'This election is already open to public votes and can no '
            'longer be changed', 'error')
        return flask.redirect(flask.url_for('results_list'))

    if election.election_public:
        flask.flash(
            'The results of this election are already public, this election'
            ' can no longer be changed', 'error')
        return flask.redirect(flask.url_for('results_list'))

    candidates = nuancierlib.get_candidates(SESSION, election_id)
    candidates_id = [str(candidate.id) for candidate in candidates]

    candidates_selected = flask.request.form.getlist('candidates_id')
    motifs = flask.request.form.getlist('motifs')
    action = flask.request.form.get('action')

    if action:
        action = action.strip()

    if action not in ['Approved', 'Denied']:
        flask.flash(
            'Only the actions "Approved" or "Denied" are accepted',
            'error')
        return flask.redirect(flask.url_for(
                endpoint, election_id=election_id, status=status))

    selections = []
    for cand in candidates_id:
        if cand not in candidates_selected:
            selections.append(None)
        else:
            selections.append(cand)

    if action == 'Denied':
        req_motif = False
        if not motifs:
            req_motif = True
        for cnt in range(len(motifs)):
            motif = motifs[cnt]
            if selections[cnt] and not motif.strip():
                req_motif = True
                break
        if req_motif:
            flask.flash(
                'You must provide a motif to deny a candidate',
                'error')
            return flask.redirect(flask.url_for(
                endpoint, election_id=election_id, status=status))

    cnt = 0
    for candidate in candidates_selected:
        if candidate not in candidates_id:
            flask.flash(
                'One of the candidate submitted was not candidate in this '
                'election', 'error')
            return flask.redirect(flask.url_for(
                endpoint, election_id=election_id, status=status))

    msgs = []

    for candidate in selections:
        if candidate:
            candidate = nuancierlib.get_candidate(SESSION, candidate)
            motif = None
            if len(motifs) > cnt:
                motif = motifs[cnt].strip()
            if action == 'Approved':
                candidate.approved = True
                candidate.approved_motif = motif
            else:
                candidate.approved = False
                candidate.approved_motif = motif
                if APP.config.get(
                        'NUANCIER_EMAIL_NOTIFICATIONS',
                        False):  # pragma: no cover
                    nuancierlib.notifications.email_publish(
                        to_email=candidate.submitter_email,
                        img_title=candidate.candidate_name,
                        motif=motif)
                else:
                    LOG.warning(
                        'Should have sent an email to "%s" about "%s" that has'
                        ' been rejected because of "%s"',
                        candidate.submitter_email,
                        candidate.candidate_name,
                        motif)

            SESSION.add(candidate)
            msgs.append({
                'topic': 'candidate.%s' % (action.lower()),
                'msg': dict(
                    agent=flask.g.fas_user.username,
                    election=election.api_repr(version=1),
                    candidate=candidate.api_repr(version=1),
                )
            })
        cnt += 1

    try:
        SESSION.commit()
    except SQLAlchemyError as err:  # pragma: no cover
        SESSION.rollback()
        LOG.debug('User: "******" could not approve/deny candidate(s) for '
                  'election "%s"', flask.g.fas_user.username,
                  election_id)
        LOG.exception(err)
        flask.flash('Could not approve/deny candidate', 'error')

    flask.flash('Candidate(s) updated')

    for msg in msgs:
        nuancierlib.notifications.publish(
            topic=msg['topic'],
            msg=msg['msg'],
        )

    return flask.redirect(flask.url_for(
        endpoint, election_id=election_id, status=status))
예제 #44
0
    def test_get_election(self):
        """ Test the get_election function. """
        create_elections(self.session)

        election = nuancierlib.get_election(self.session, 3)
        self.assertEqual('Wallpaper F21', election.election_name)
예제 #45
0
파일: ui.py 프로젝트: jontrossbach/nuancier
def contribute(election_id):
    ''' Display the index page for interested contributor. '''
    election = nuancierlib.get_election(SESSION, election_id)
    if not election:
        flask.flash('No election found', 'error')
        return flask.render_template('msg.html')
    elif not election.submission_open:
        flask.flash('This election is not open for submission', 'error')
        return flask.redirect(flask.url_for('elections_list'))

    candidates = nuancier.lib.model.Candidates.get_by_submitter(
        SESSION, flask.g.fas_user.username, election_id)
    if election.user_n_candidates and \
        len(candidates) >= election.user_n_candidates:
        flask.flash(
            'You have uploaded the maximum number of candidates (%s) you '
            'can upload for this election' % election.user_n_candidates,
            'error')
        return flask.redirect(flask.url_for('elections_list'))

    form = nuancier.forms.AddCandidateForm()
    if form.validate_on_submit():
        candidate_file = flask.request.files['candidate_file']

        try:
            validate_input_file(candidate_file)
        except nuancierlib.NuancierException as err:
            LOG.debug(
                'ERROR: Uploaded file is invalid - user: "******" '
                'election: "%s"', flask.g.fas_user.username, election_id)
            LOG.exception(err)
            flask.flash('%s' % err, 'error')
            return flask.render_template('contribute.html',
                                         election=election,
                                         form=form)

        filename = secure_filename(
            '%s-%s' % (flask.g.fas_user.username, candidate_file.filename))

        # Only save the file once everything has been safely saved in the DB
        upload_folder = os.path.join(APP.config['PICTURE_FOLDER'],
                                     election.election_folder)
        if not os.path.exists(upload_folder):  # pragma: no cover
            try:
                os.mkdir(upload_folder)
            except OSError as err:
                LOG.debug('ERROR: cannot add candidate file')
                LOG.exception(err)
                flask.flash(
                    'An error occured while writing the file, please '
                    'contact an administrator', 'error')
                return flask.render_template('contribute.html',
                                             election=election,
                                             form=form)

        # Save candidate to the database
        try:
            nuancierlib.add_candidate(
                SESSION,
                candidate_file=filename,
                candidate_name=form.candidate_name.data,
                candidate_author=form.candidate_author.data,
                candidate_original_url=form.candidate_original_url.data,
                candidate_license=form.candidate_license.data,
                candidate_submitter=flask.g.fas_user.username,
                submitter_email=flask.g.fas_user.email,
                election_id=election.id,
                user=flask.g.fas_user.username,
            )
        except nuancierlib.NuancierException as err:
            flask.flash('%s' % err, 'error')
            return flask.render_template('contribute.html',
                                         election=election,
                                         form=form)

        # The PIL module has already read the stream so we need to back up
        candidate_file.seek(0)

        candidate_file.save(os.path.join(upload_folder, filename))

        try:
            SESSION.commit()
        except SQLAlchemyError as err:  # pragma: no cover
            SESSION.rollback()
            # Remove file from the system if the db commit failed
            os.unlink(os.path.join(upload_folder, filename))
            LOG.debug(
                'ERROR: cannot add candidate - user: "******" '
                'election: "%s"', flask.g.fas_user.username, election_id)
            LOG.exception(err)
            flask.flash(
                'Someone has already upload a file with the same file name'
                ' for this election', 'error')
            return flask.render_template('contribute.html',
                                         election=election,
                                         form=form)

        flask.flash('Thanks for your submission')
        return flask.redirect(flask.url_for('index'))
    elif flask.request.method == 'GET':
        form.candidate_author.data = flask.g.fas_user.username

    return flask.render_template('contribute.html',
                                 election=election,
                                 form=form)
예제 #46
0
# -*- coding: utf-8 -*-

__requires__ = ['SQLAlchemy >= 0.7', 'jinja2 >= 2.4']
import pkg_resources
import os

os.environ['NUANCIER_CONFIG'] = '/etc/nuancier/nuancier.cfg'

from nuancier import APP, SESSION, lib

election = lib.get_election(SESSION, 1)
lib.generate_cache(
    SESSION,
    election,
    APP.config['PICTURE_FOLDER'],
    APP.config['CACHE_FOLDER'],
    APP.config['THUMB_SIZE'],
)