[lang: es it en ] Login

source code for: cc2.subcontrollers.candidate

# cc2 <http://cc2.berlios.de/> is a web application to drive
# grassroot initiatives.
#
# Copyright (C) 2009 Alberto Granzotto <agranzot@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import turbogears as tg
from turbogears import controllers, expose, flash, config, util
from turbogears import identity, redirect, validate, error_handler, exception_handler
from turbogears.database import session
from cherrypy import request, response, session as cp_session
from cc2.utils import *
from cc2.model import *
from forms import *
from data_grids import *
from cc2.widgets import *
from cc2.other_validators import *
import turbomail
import turbowiki
from sqlalchemy.orm import eagerload
import cStringIO as StringIO
from datetime import date
import os


class CandidateController(controllers.Controller):
    @expose()
    def index(self, *args, **kw):
        raise redirect('/candidate/subscribe')

    @expose('cc2.templates.error')
    def error(self, tg_errors=None, tg_exceptions=None):
        return dict(error_message=tg_errors, exception_messages=tg_exceptions)

    @expose('cc2.templates.manage.genericform')
    @error_handler(error)
    @validate(validators={'id': CheckExistance(query=District.query().get)})
    @identity.require(identity.has_permission('create_candidate'))
    def create(self, id):
        return dict(
                title=_('Create a Candidate'), form=candidate_form,
                submit_text=_('save'), action='../do_create/%s'%id, values=None)

    @expose()
    @error_handler(create)
    @validate(form=candidate_form,
        validators={'id': CheckExistance(query=District.query.get)})
    @identity.require(identity.has_permission('create_candidate'))
    def do_create(self, id, **kw):
        politician = kw['politician']
        district = District.query.get(id)
        election = district.election
        candidate = politician.candidate
        if not candidate or not candidate.election == election:
            candidate = Candidate()
            candidate.politician = politician
            candidate.party = politician.party
            candidate.election = election
            session.save(candidate)

        candidate.agrees = kw['agrees']
        candidate.elected = kw['elected']
        candidate.info = kw['info']

        # we need the ID before saving the document
        session.flush()

        candidate.save_signed_document(kw['signed_document'])

        roll = ElectoralRoll()
        roll.position = kw['position']
        roll.candidate = candidate
        roll.district = district
        session.save(roll)

        session.flush()
        session.save(Actionlog(
            user_id=identity.current.user_id,
            action='C',
            description='candidate create',
            model_name=Candidate.__name__,
            object_id=candidate.id)
        )
        session.flush()
        flash(_('You have created candidate %s') % (politician.full_name))
        raise redirect('/election/details/%s' % election.id)

    @expose('cc2.templates.candidate.update')
    @error_handler(error)
    @identity.require(identity.has_permission('update_candidate'))
    @validate(validators={'id': CheckExistance(query=ElectoralRoll.query.get)})
    def update(self, id):
        er = ElectoralRoll.query.get(id)
        candidate = er.candidate
        foo = Foo(candidate)
        foo.position = er.position
        foo.back_to = request.headers.get('Referer', '/')
        return dict(
                title=_('Update Candidate %s') % candidate.politician.full_name,
                form=update_candidate_form, submit_text=_('update'),
                action='../do_update/%s' % id, values=foo,
                signed_documents=candidate.signed_documents)

    @expose()
    @error_handler(update)
    @identity.require(identity.has_permission('update_candidate'))
    @validate(form=update_candidate_form,
        validators={'id': CheckExistance(query=ElectoralRoll.query.get)})
    def do_update(self, id, **kw):
        er = ElectoralRoll.query.get(id)
        candidate = er.candidate
        elected = not candidate.elected and kw['elected']
        er.position = kw['position']
        candidate.agrees = kw['agrees']
        candidate.elected = kw['elected']
        candidate.info = kw['info']
        politician = candidate.politician
        election = candidate.election

        candidate.save_signed_document(kw['signed_document'])

        session.flush()
        session.save(Actionlog(
            user_id=identity.current.user_id,
            action='U',
            description='candidate update',
            model_name=Candidate.__name__,
            object_id=candidate.id)
        )
        if elected:
            session.save(Actionlog(
                user_id=identity.current.user_id,
                action='U',
                description='candidate elected',
                model_name=Candidate.__name__,
                object_id=candidate.id)
            )
        session.flush()
        flash(_('You have updated %s') % (politician.full_name))
        raise redirect(kw.get('back_to','/'))

    @expose('cc2.templates.candidate.select_election')
    def subscribe(self):
        page = Page.failsafe_by_name('internal.candidate_subscribe')
        data = []
        query = Election.query().filter(date.today()<=Election.end)
        for election in query:
            f=Foo()
            f.id = election.id
            f.type = election.election_type.name
            f.pretty_date= election.pretty_date
            f.where = election.place.name
            data.append(f)
        #if len(data) == 0:
        #    flash(_('there are no active elections'))
        #    raise redirect('/')
        return dict(elections=data, name=page.name, title=_('Select an Election'), page=page)

    @expose('cc2.templates.candidate.subscribe')
    @error_handler(error)
    @validate(validators={'election_id': CheckExistance(query=Election.query.get)})
    def sign(self, election_id, tg_errors=None, **kw):
        page = Page.failsafe_by_name('internal.candidate_sign')
        election = Election.query().get(election_id)
        f=Foo(election)
        f.type = election.election_type.name
        f.interval = '%s-%s' % (election.start.day,
            election.end.strftime('%d %B %Y'))
        f.where = election.place.name
        tg.errors = tg_errors
        kw['workgroup_id']=1
        if not cp_session.has_key('candidate_subscribe_election_id') or\
            cp_session['candidate_subscribe_election_id'] != election_id:
            cp_session['candidate_subscribe_election_id'] = election_id
            cp_session['candidate_subscribe_form'] =\
                candidate_subscribe_form_generator(election_id)

        return dict(
                title=_('Subscribe the Petition'),
                form=cp_session['candidate_subscribe_form'],
                page=page, election=f,
                submit_text=_('sign'),
                action='/candidate/thank_you/%s'%election_id, values=kw)

    def get_form(self):
        if not cp_session.has_key('candidate_subscribe_election_id'):
            flash(_('Session expired, please start again'))
            raise redirect('/candidate/subscribe')
        return cp_session.get('candidate_subscribe_form', None)

    #@expose()
    @expose('cc2.templates.candidate.thank_you')
    @error_handler(sign)
    @validate(form=get_form,
              validators={'election_id': CheckExistance(
                  query=Election.query.get)})
    def thank_you(self, election_id, **kw):
        del cp_session['candidate_subscribe_form']
        del cp_session['candidate_subscribe_election_id']
        election = Election.query().get(election_id)
        desc = u'''
name         = %(name)s
surname      = %(surname)s
birthdate    = %(pretty_birthdate)s
phone_number = %(phone_number)s
email        = %(email)s
site         = %(site)s
party        = %(party)s
election     = %(election)s
association  = %(association)s
fax number   = %(association_fax)s
email        = %(association_email)s
---------------------------
districts positions

'''
        if not election.multiple:
            for district in election.districts:
                key = 'district_%s' % district.id
                if kw.has_key(key) and kw[key] and kw[key].strip():
                    desc += u'%s - %s\n' % (district.name, kw[key])
        else:
            desc += u'%s - %s\n' % (kw['location'], kw['district'])

        kw['election'] = election.name
        if kw['birthdate']:
            kw['pretty_birthdate'] = kw['birthdate'].strftime('%d/%m/%Y')
        else:
            kw['pretty_birthdate'] = '???'
        wg = Workgroup.query().get(kw['workgroup_id'])
        kw['association'] = wg.display_name
        kw['association_fax'] = wg.fax
        kw['association_email'] = wg.email
        key = random_key()
        ticket = Ticket(
            reporter='%s %s' % (kw['name'],kw['surname']),
            reporter_email=kw['email'],
            reporter_ip=get_ip_addr(),
            type='candidate request',
            status='new',
            description=desc % kw,
            resp_workgroup_id=wg.id,
            confidential=True,
            model_name='Election',
            object_id=election_id,
            key=key
        )

        session.save(ticket)
        session.flush()
        session.save(Actionlog(
            user_id=identity.current.user_id,
            action='C',
            description='candidate request',
            model_name=Ticket.__name__,
            object_id=ticket.id)
        )
        session.flush()
        data = dict(
            name = kw['name'],
            document_url = config.get('siteurl'),
            pdf_url = '%scandidate/pdf/%s/subscription.pdf' %\
                (config.get('siteurl'), key),
            ticket_url = '%sticket/group/new' % config.get('siteurl'),
        )

        message = turbomail.Message(config.get('mail.sender'), kw['email'],
            _('Dear Candidate thanks you for your subscribe'))
        message.plain = _(u'''Dear %(name)s,
you have just subscribed our initiative:
 * %(document_url)s

To download your PDF again please visit:
 * %(pdf_url)s''') % data
        turbomail.enqueue(message)

        for user in wg.active_users:
            message = turbomail.Message(
                config.get('mail.sender'),
                user.email_address,
                _('[cc2] new Candidate subscription'))
            message.plain = _(u'''New subscription from %(name)s.
    You can see the ticket here:
     * %(ticket_url)s''') % data
            turbomail.enqueue(message)

        page = Page.failsafe_by_name('internal.candidate_thank_you')
        flash(_('Your request well be processed as soon as possible'))
        pdf_url = '%scandidate/pdf/%s/subscription.pdf' %\
            (config.get('siteurl'), key)
        formatted_text = turbowiki.wiki_parser(page.text % kw).decode('utf8')
        return dict(title=_('Thank you'), pdf_url=pdf_url, page=page,
                formatted_text=formatted_text)

    @expose(content_type="application/pdf")
    @error_handler(error)
    @exception_handler(error)
    @validate(validators={'key': CheckExistance(query=Ticket.by_key)})
    def pdf(self, key, name):
        #LOL: name is only for the file name
        ticket = Ticket.by_key(key)
        election = Election.query.get(ticket.object_id)
        document = election.document
        template = election.template
        #ok, I know, this is awful but I have no time
        d = ticket.description.split('\n')
        f=Foo()
        f.name = d[1][15:]
        f.surname = d[2][15:]
        f.birthdate = d[3][15:]
        f.phone_number = d[4][15:]
        f.email = d[5][15:]
        f.site = d[6][15:]
        f.party = d[7][15:]
        f.election = d[8][15:]
        f.association = d[9][15:]
        f.association_fax = d[10][15:]
        f.association_email = d[11][15:]
        f.districts = ', '.join(d[15:])
        f.document = document.text

        text = template.text % f
        #FIXME: uhm, wikiparse return a string, we need a unicode object...
        text = turbowiki.wiki_parser(text).decode('utf8')
        try:
            file = pdfize(text)
        except:
            send_pdf_exception_email()
            raise redirect('/error')
        if not file:
            send_pdf_exception_email()
            raise redirect('/error')
        return file.getvalue()

    @expose(content_type="application/pdf")
    @error_handler(error)
    @exception_handler(error)
    @identity.require(identity.in_group('editor'))
    def test_pdf(self, template_name, name):
        #LOL: name is only for the file name
        template = Page.by_name(template_name)
        #ok, I know, this is awful but I have no time
        f=Foo()
        f.name = 'Name-Test'
        f.surname = 'Surname-Test'
        f.birthdate = '01/01/1990'
        f.phone_number = '+(0)12phone-number345'
        f.email = 'email@example.com'
        f.site = 'http://www.example.com/'
        f.party = 'Party-test'
        f.election = 'Election-name-test'
        f.association = 'Trusted-association-test'
        f.association_fax = '012association-fax34'
        f.association_email = 'association-email@example.com'
        f.districts = ', '.join(['district-1', 'district-2'])

        text = template.text % f
        #FIXME: uhm, wikiparse returns a string, we need a unicode object...
        text = turbowiki.wiki_parser(text).decode('utf8')
        try:
            file = pdfize(text)
        except:
            send_pdf_exception_email()
            raise redirect('/error')
        if not file:
            send_pdf_exception_email()
            raise redirect('/error')
        return file.getvalue()

    @expose('cc2.templates.manage.genericdelete')
    @error_handler(error)
    @validate(validators={'id': CheckExistance(query=Candidate.query.get)})
    @identity.require(is_mine_or_group(Candidate, 'id'))
    def delete(self, id, **kw):
        o = Candidate.query().get(id)
        what = []
        what.append( (
            _('positions:'),
            [e.position for e in o.electoral_rolls])
        )
        return dict(title=_('Delete Candidancy'),
            what=what,
            go_back='/politician/details/%s'%o.politician_id,
            go_on='/candidate/do_delete/%s'%id)

    @expose()
    @error_handler(error)
    @validate(validators={'id': CheckExistance(query=Candidate.query.get)})
    @identity.require(is_mine_or_group(Candidate, 'id'))
    def do_delete(self, id, **kw):
        o = Candidate.query().get(id)

        session.delete(o)
        session.save(Actionlog(
            user_id=identity.current.user_id,
            action='D',
            description='candidate delete',
            model_name=Candidate.__name__,
            object_id=o.id)
        )
        session.flush()
        flash(_('You have deleted %s %s') %
            (o.politician.name, o.politician.surname))
        raise redirect("/")

    @expose('cc2.templates.manage.genericdelete')
    @error_handler(error)
    @identity.require(identity.has_permission('delete_candidate'))
    @validate(validators={'id': CheckExistance(query=ElectoralRoll.query.get)})
    def delete_position(self, id, **kw):
        o = ElectoralRoll.query().get(id)
        what = []
        return dict(title=_('Delete Position'),
            what=what,
            go_back='/politician/details/%s'%o.candidate.politician_id,
            go_on='/candidate/do_delete_position/%s'%id)

    @expose()
    @error_handler(error)
    @identity.require(identity.has_permission('delete_candidate'))
    @validate(validators={'id': CheckExistance(query=ElectoralRoll.query.get)})
    def do_delete_position(self, id, **kw):
        o = ElectoralRoll.query().get(id)

        session.delete(o)
        session.save(Actionlog(
            user_id=identity.current.user_id,
            action='D',
            description='position delete',
            model_name=ElectoralRoll.__name__,
            object_id=o.id)
        )
        session.flush()
        flash(_('You have deleted %s') % o.position)
        raise redirect('/politician/details/%s'%o.candidate.politician_id)