<commit_before># -*- coding: utf-8 -*-
# -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP - Import operations model 347 engine
#    Copyright (C) 2009 Asr Oss. All Rights Reserved
#    $Id$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU 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 General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

"""
Import operations model 347 engine wizards
"""
__author__ = """Alejandro Sanchez Ramirez Asr Oss - alejandro@asr-oss.com
                Borja López Soilán (Pexego) - borjals@pexego.es"""

from tools.translate import _
import wizard
import pooler
import time
import threading
import sql_db
import re
import netsvc

class wizard_calculate(wizard.interface):
    """
    Wizard to calculates the 347 model report from the OpenERP invoices/payments.
    """

    ############################################################################
    # Forms
    ############################################################################

    _init_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculate partner records" colspan="4" width="400">
        <label string="This wizard will calculate the partner operations records of the 347 report." colspan="4"/>
        <label string="" colspan="4"/>
        <label string="It will create records for the next operations:" colspan="4"/>
        <label string="  A - Purchases of goods and services over the limit (1)." colspan="4"/>
        <label string="  B - Sales of goods and services over the limit (1)." colspan="4"/>
        <!-- <label string=" C - Received payments on behalf of third parties over the limit (3)." colspan="4"/> -->
    </form>"""

    _progress_form = '''<?xml version="1.0"?>
    <form string="Calculating partner records" colspan="4" width="400">
        <label string="The calculation may take a while." colspan="4"/>
        <label string="" colspan="4"/>
        <field name="progress" widget="progressbar"/>
    </form>'''

    _progress_fields = {
        'progress': { 'string': 'Progress', 'type':'float' },
    }

    _done_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculation done" colspan="4" width="400">
        <label string="The partner operation records have been calculated." colspan="4"/>
        <label string="" colspan="4"/>
    </form>"""

    _show_exception_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculation failed!" colspan="4" width="400">
        <label string="Error: The calculation operation has failed!" colspan="4"/>
        <label string="" colspan="4"/>
        <separator string="Details"/>
        <field name="exception_text" colspan="4" nolabel="1"/>
    </form>"""

    _show_exception_fields = {
        'exception_text': {'string': 'Exception', 'type':'text' },
    }

    ############################################################################
    # Actions
    ############################################################################

    def _calculate(self, db_name, uid, data, context=None):
        """
        Calculates the 347 model report from the OpenERP invoices/payments data.
        """
        try:
            conn = sql_db.db_connect(db_name)
            cr = conn.cursor()
            pool = pooler.get_pool(cr.dbname)

            report = pool.get('l10n.es.aeat.mod347.report').browse(cr, uid, data['id'], context=context)

            pool.get('l10n.es.aeat.mod347.report').write(cr, uid, data['id'], {
                'state': 'calc',
                'calc_date': time.strftime('%Y-%m-%d %H:%M:%S')
            })

            #
            # Delete the previous partner records
            #
            pool.get('l10n.es.aeat.mod347.partner_record').unlink(cr, uid, [r.id for r in report.partner_records])

            # Get the cash journals (moves on this journals will be considered cash)
            cash_journal_ids = pool.get('account.journal').search(cr, uid, [('cash_journal', '=', True)])

            # Get the fiscal year period ids of the non-special periods
            # (to ignore closing/opening entries)
            period_ids = [period.id for period in report.fiscalyear_id.period_ids if not period.special]

            #
            # We will check every partner with include_in_mod347
            #
            partner_ids = pool.get('res.partner').search(cr, uid, [('include_in_mod347','=',True)])
            partners_done = 0
            total_partners = len(partner_ids)
            for partner in pool.get('res.partner').browse(cr, uid, partner_ids):

                #
                # Search for invoices
                #
                # We will repeat the process for sales and purchases:
                for invoice_type, refund_type in zip(('out_invoice', 'in_invoice'), ('out_refund', 'in_refund')):
                    #
                    # CHECK THE SALE/PURCHASES INVOICE LIMIT -------------------
                    # (A and B operation keys)
                    #

                    #
                    # Search for invoices to this partner (with account moves).
                    #
                    invoice_ids = pool.get('account.invoice').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('type', '=', invoice_type),
                                ('period_id', 'in', period_ids),
                                ('move_id', '!=', None),
                            ])
                    refund_ids = pool.get('account.invoice').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('type', '=', refund_type),
                                ('period_id', 'in', period_ids),
                                ('move_id', '!=', None),
                            ])
                    invoices = pool.get('account.invoice').browse(cr, uid, invoice_ids)
                    refunds = pool.get('account.invoice').browse(cr, uid, refund_ids)

                    # Calculate the invoiced amount
                    invoice_amount = sum([invoice.amount_total for invoice in invoices])
                    refund_amount = sum([invoice.amount_total for invoice in refunds])
                    total_amount = invoice_amount - refund_amount

                    #
                    # Search for payments received in cash from this partner.
                    #
                    cash_account_move_line_ids = pool.get('account.move.line').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('account_id', '=', partner.property_account_receivable.id),
                                ('journal_id', 'in', cash_journal_ids),
                                ('period_id', 'in', period_ids),
                            ])
                    cash_account_move_lines = pool.get('account.move.line').browse(cr, uid, cash_account_move_line_ids)

                    # Calculate the cash amount
                    received_cash_amount = sum([line.credit for line in cash_account_move_lines])

                    #
                    # If the invoiced amount is greater than the limit
                    # we will add an partner record to the report.
                    #
                    if total_amount > report.operations_limit:
                        if invoice_type == 'out_invoice':
                            operation_key = 'B' # Note: B = Sale operations
                        else:
                            assert invoice_type == 'in_invoice'
                            operation_key = 'A' # Note: A = Purchase operations

                        #
                        # Get the default invoice address of the partner
                        #
                        address = None
                        address_ids = pool.get('res.partner').address_get(cr, uid, [partner.id], ['invoice', 'default'])
                        if address_ids.get('invoice'):
                            address = pool.get('res.partner.address').browse(cr, uid, address_ids.get('invoice'))
                        elif address_ids.get('default'):
                            address = pool.get('res.partner.address').browse(cr, uid, address_ids.get('default'))

                        #
                        # Get the partner data
                        #
                        partner_vat = partner.vat and re.match(r"([A-Z]{0,2})(.*)", partner.vat).groups()[1]
                        partner_state_code = address.state_id and address.state_id.code or ''
                        partner_country_code = address.country_id and address.country_id.code or ''
                        if partner.vat:
                            partner_country_code, partner_vat = re.match("(ES){0,1}(.*)", partner.vat).groups()

                        # Create the partner record
                        partner_record = pool.get('l10n.es.aeat.mod347.partner_record').create(cr, uid, {
                                'report_id': report.id ,
                                'operation_key' : operation_key,
                                'partner_id': partner.id,
                                'partner_vat': partner_vat,
                                'representative_vat': '',
                                'partner_state_code': partner_state_code,
                                'partner_country_code' : partner_country_code,
                                'amount': total_amount,
                                'cash_amount': received_cash_amount > report.received_cash_limit and received_cash_amount or 0,
                            })

                        #
                        # Add the invoices detail to the partner record
                        #
                        for invoice in invoices:
                            pool.get('l10n.es.aeat.mod347.invoice_record').create(cr, uid, {
                                'partner_record_id' : partner_record,
                                'invoice_id': invoice.id,
                                'date': invoice.date_invoice,
                                'amount': invoice.amount_total,
                            })
                        for invoice in refunds:
                            pool.get('l10n.es.aeat.mod347.invoice_record').create(cr, uid, {
                                'partner_record_id' : partner_record,
                                'invoice_id': invoice.id,
                                'date': invoice.date_invoice,
                                'amount': -invoice.amount_total,
                            })

                        #
                        # Add the cash detail to the partner record if over limit
                        #
                        if received_cash_amount > report.received_cash_limit:
                            for line in cash_account_move_lines:
                                pool.get('l10n.es.aeat.mod347.cash_record').create(cr, uid, {
                                    'partner_record_id' : partner_record,
                                    'move_line_id' : line.id,
                                    'date': line.date,
                                    'amount': line.credit,
                                })

                    #
                    # TODO: Calculate records of operation keys C-D-E-F-G !
                    #

                #
                # Update the progress:
                #
                partners_done += 1
                data['calculation_progress'] = (partners_done * 100.0) / total_partners

            #
            # Set the report as calculated
            #
            wf_service = netsvc.LocalService("workflow")
            wf_service.trg_validate(uid, 'l10n.es.aeat.mod347.report', report.id, 'calculate', cr)

            data['calculation_progress'] = 100
            cr.commit()
        except Exception, e:
            data['calculation_exception'] = e
            cr.rollback()
            raise
        finally:
            data['calculation_done'] = True
        return {}

    def _calculate_in_background_choice(self, cr, uid, data, context):
        """
        Choice-like action that runs the calculation on background,
        waiting for it to end or timeout.
        """
        if not data.get('calculation_thread'):
            # Run the calculation in background
            data['calculation_done'] = False
            data['calculation_exception'] = None
            data['calculation_thread'] = threading.Thread(target=self._calculate, args=(cr.dbname, uid, data, context))
            data['calculation_thread'].start()
        #
        # Wait up some seconds seconds for the task to end.
        #
        time_left = 20
        while not data['calculation_done'] and time_left > 0:
            time_left = time_left - 1
            time.sleep(1)
        #
        # Check if we are done
        #
        if data['calculation_done']:
            if data['calculation_exception']:
                return 'show_exception'
            else:
                return 'done'
        else:
            return 'progress'

    def _progress_action(self, cr, uid, data, context):
        """
        Action that gets the current progress
        """
        return { 'progress': data['calculation_progress'] }

    def _show_exception_action(self, cr, uid, data, context):
        """
        Action that gets the calculation exception text
        """
        try:
            exception_text = unicode(data.get('process_exception', ''))
        except UnicodeDecodeError:
            exception_text = str(data.get('process_exception', ''))
        return { 'exception_text': exception_text }

    ############################################################################
    # States
    ############################################################################

    states = {
        'init': {
            'actions': [],
            'result': {'type':'form', 'arch': _init_form, 'fields': {}, 'state':[('end', 'Cancel', 'gtk-cancel', True), ('calculate_records', 'Calculate', 'gtk-apply', True)]}
        },
        'calculate_records': {
            'actions': [],
            'result': {'type': 'choice', 'next_state': _calculate_in_background_choice}
        },
        'progress': {
            'actions': [_progress_action],
            'result': {'type': 'form', 'arch': _progress_form, 'fields': _progress_fields, 'state':[('end','Close (continues in background)', 'gtk-cancel', True),('calculate_records','Keep waiting', 'gtk-go-forward', True)]}
        },
        'done': {
            'actions': [],
            'result': {'type': 'form', 'arch': _done_form, 'fields': {}, 'state':[('end','Done', 'gtk-ok', True)]}
        },
        'show_exception': {
            'actions': [_show_exception_action],
            'result': {'type': 'form', 'arch': _show_exception_form, 'fields': _show_exception_fields, 'state':[('end','Done', 'gtk-ok', True)]}
        }
    }

wizard_calculate('l10n_es_aeat_mod347.calculate_wizard')

<commit_msg>[FIX] l10n_ES_aeat_mod347: Asegurarse de cerrar explicitamente el cursor.<commit_after># -*- coding: utf-8 -*-
# -*- encoding: utf-8 -*-
##############################################################################
#
#    OpenERP - Import operations model 347 engine
#    Copyright (C) 2009 Asr Oss. All Rights Reserved
#    $Id$
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU 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 General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

"""
Import operations model 347 engine wizards
"""
__author__ = """Alejandro Sanchez Ramirez Asr Oss - alejandro@asr-oss.com
                Borja López Soilán (Pexego) - borjals@pexego.es"""

from tools.translate import _
import wizard
import pooler
import time
import threading
import sql_db
import re
import netsvc

class wizard_calculate(wizard.interface):
    """
    Wizard to calculates the 347 model report from the OpenERP invoices/payments.
    """

    ############################################################################
    # Forms
    ############################################################################

    _init_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculate partner records" colspan="4" width="400">
        <label string="This wizard will calculate the partner operations records of the 347 report." colspan="4"/>
        <label string="" colspan="4"/>
        <label string="It will create records for the next operations:" colspan="4"/>
        <label string="  A - Purchases of goods and services over the limit (1)." colspan="4"/>
        <label string="  B - Sales of goods and services over the limit (1)." colspan="4"/>
        <!-- <label string=" C - Received payments on behalf of third parties over the limit (3)." colspan="4"/> -->
    </form>"""

    _progress_form = '''<?xml version="1.0"?>
    <form string="Calculating partner records" colspan="4" width="400">
        <label string="The calculation may take a while." colspan="4"/>
        <label string="" colspan="4"/>
        <field name="progress" widget="progressbar"/>
    </form>'''

    _progress_fields = {
        'progress': { 'string': 'Progress', 'type':'float' },
    }

    _done_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculation done" colspan="4" width="400">
        <label string="The partner operation records have been calculated." colspan="4"/>
        <label string="" colspan="4"/>
    </form>"""

    _show_exception_form = """<?xml version="1.0" encoding="utf-8"?>
    <form string="Calculation failed!" colspan="4" width="400">
        <label string="Error: The calculation operation has failed!" colspan="4"/>
        <label string="" colspan="4"/>
        <separator string="Details"/>
        <field name="exception_text" colspan="4" nolabel="1"/>
    </form>"""

    _show_exception_fields = {
        'exception_text': {'string': 'Exception', 'type':'text' },
    }

    ############################################################################
    # Actions
    ############################################################################

    def _calculate(self, db_name, uid, data, context=None):
        """
        Calculates the 347 model report from the OpenERP invoices/payments data.
        """
        try:
            conn = sql_db.db_connect(db_name)
            cr = conn.cursor()
            pool = pooler.get_pool(cr.dbname)

            report = pool.get('l10n.es.aeat.mod347.report').browse(cr, uid, data['id'], context=context)

            pool.get('l10n.es.aeat.mod347.report').write(cr, uid, data['id'], {
                'state': 'calc',
                'calc_date': time.strftime('%Y-%m-%d %H:%M:%S')
            })

            #
            # Delete the previous partner records
            #
            pool.get('l10n.es.aeat.mod347.partner_record').unlink(cr, uid, [r.id for r in report.partner_records])

            # Get the cash journals (moves on this journals will be considered cash)
            cash_journal_ids = pool.get('account.journal').search(cr, uid, [('cash_journal', '=', True)])

            # Get the fiscal year period ids of the non-special periods
            # (to ignore closing/opening entries)
            period_ids = [period.id for period in report.fiscalyear_id.period_ids if not period.special]

            #
            # We will check every partner with include_in_mod347
            #
            partner_ids = pool.get('res.partner').search(cr, uid, [('include_in_mod347','=',True)])
            partners_done = 0
            total_partners = len(partner_ids)
            for partner in pool.get('res.partner').browse(cr, uid, partner_ids):

                #
                # Search for invoices
                #
                # We will repeat the process for sales and purchases:
                for invoice_type, refund_type in zip(('out_invoice', 'in_invoice'), ('out_refund', 'in_refund')):
                    #
                    # CHECK THE SALE/PURCHASES INVOICE LIMIT -------------------
                    # (A and B operation keys)
                    #

                    #
                    # Search for invoices to this partner (with account moves).
                    #
                    invoice_ids = pool.get('account.invoice').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('type', '=', invoice_type),
                                ('period_id', 'in', period_ids),
                                ('move_id', '!=', None),
                            ])
                    refund_ids = pool.get('account.invoice').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('type', '=', refund_type),
                                ('period_id', 'in', period_ids),
                                ('move_id', '!=', None),
                            ])
                    invoices = pool.get('account.invoice').browse(cr, uid, invoice_ids)
                    refunds = pool.get('account.invoice').browse(cr, uid, refund_ids)

                    # Calculate the invoiced amount
                    invoice_amount = sum([invoice.amount_total for invoice in invoices])
                    refund_amount = sum([invoice.amount_total for invoice in refunds])
                    total_amount = invoice_amount - refund_amount

                    #
                    # Search for payments received in cash from this partner.
                    #
                    cash_account_move_line_ids = pool.get('account.move.line').search(cr, uid, [
                                ('partner_id', '=', partner.id),
                                ('account_id', '=', partner.property_account_receivable.id),
                                ('journal_id', 'in', cash_journal_ids),
                                ('period_id', 'in', period_ids),
                            ])
                    cash_account_move_lines = pool.get('account.move.line').browse(cr, uid, cash_account_move_line_ids)

                    # Calculate the cash amount
                    received_cash_amount = sum([line.credit for line in cash_account_move_lines])

                    #
                    # If the invoiced amount is greater than the limit
                    # we will add an partner record to the report.
                    #
                    if total_amount > report.operations_limit:
                        if invoice_type == 'out_invoice':
                            operation_key = 'B' # Note: B = Sale operations
                        else:
                            assert invoice_type == 'in_invoice'
                            operation_key = 'A' # Note: A = Purchase operations

                        #
                        # Get the default invoice address of the partner
                        #
                        address = None
                        address_ids = pool.get('res.partner').address_get(cr, uid, [partner.id], ['invoice', 'default'])
                        if address_ids.get('invoice'):
                            address = pool.get('res.partner.address').browse(cr, uid, address_ids.get('invoice'))
                        elif address_ids.get('default'):
                            address = pool.get('res.partner.address').browse(cr, uid, address_ids.get('default'))

                        #
                        # Get the partner data
                        #
                        partner_vat = partner.vat and re.match(r"([A-Z]{0,2})(.*)", partner.vat).groups()[1]
                        partner_state_code = address.state_id and address.state_id.code or ''
                        partner_country_code = address.country_id and address.country_id.code or ''
                        if partner.vat:
                            partner_country_code, partner_vat = re.match("(ES){0,1}(.*)", partner.vat).groups()

                        # Create the partner record
                        partner_record = pool.get('l10n.es.aeat.mod347.partner_record').create(cr, uid, {
                                'report_id': report.id ,
                                'operation_key' : operation_key,
                                'partner_id': partner.id,
                                'partner_vat': partner_vat,
                                'representative_vat': '',
                                'partner_state_code': partner_state_code,
                                'partner_country_code' : partner_country_code,
                                'amount': total_amount,
                                'cash_amount': received_cash_amount > report.received_cash_limit and received_cash_amount or 0,
                            })

                        #
                        # Add the invoices detail to the partner record
                        #
                        for invoice in invoices:
                            pool.get('l10n.es.aeat.mod347.invoice_record').create(cr, uid, {
                                'partner_record_id' : partner_record,
                                'invoice_id': invoice.id,
                                'date': invoice.date_invoice,
                                'amount': invoice.amount_total,
                            })
                        for invoice in refunds:
                            pool.get('l10n.es.aeat.mod347.invoice_record').create(cr, uid, {
                                'partner_record_id' : partner_record,
                                'invoice_id': invoice.id,
                                'date': invoice.date_invoice,
                                'amount': -invoice.amount_total,
                            })

                        #
                        # Add the cash detail to the partner record if over limit
                        #
                        if received_cash_amount > report.received_cash_limit:
                            for line in cash_account_move_lines:
                                pool.get('l10n.es.aeat.mod347.cash_record').create(cr, uid, {
                                    'partner_record_id' : partner_record,
                                    'move_line_id' : line.id,
                                    'date': line.date,
                                    'amount': line.credit,
                                })

                    #
                    # TODO: Calculate records of operation keys C-D-E-F-G !
                    #

                #
                # Update the progress:
                #
                partners_done += 1
                data['calculation_progress'] = (partners_done * 100.0) / total_partners

            #
            # Set the report as calculated
            #
            wf_service = netsvc.LocalService("workflow")
            wf_service.trg_validate(uid, 'l10n.es.aeat.mod347.report', report.id, 'calculate', cr)

            data['calculation_progress'] = 100
            cr.commit()
        except Exception, e:
            data['calculation_exception'] = e
            cr.rollback()
            raise
        finally:
            cr.close()
            data['calculation_done'] = True
        return {}

    def _calculate_in_background_choice(self, cr, uid, data, context):
        """
        Choice-like action that runs the calculation on background,
        waiting for it to end or timeout.
        """
        if not data.get('calculation_thread'):
            # Run the calculation in background
            data['calculation_done'] = False
            data['calculation_exception'] = None
            data['calculation_thread'] = threading.Thread(target=self._calculate, args=(cr.dbname, uid, data, context))
            data['calculation_thread'].start()
        #
        # Wait up some seconds seconds for the task to end.
        #
        time_left = 20
        while not data['calculation_done'] and time_left > 0:
            time_left = time_left - 1
            time.sleep(1)
        #
        # Check if we are done
        #
        if data['calculation_done']:
            if data['calculation_exception']:
                return 'show_exception'
            else:
                return 'done'
        else:
            return 'progress'

    def _progress_action(self, cr, uid, data, context):
        """
        Action that gets the current progress
        """
        return { 'progress': data['calculation_progress'] }

    def _show_exception_action(self, cr, uid, data, context):
        """
        Action that gets the calculation exception text
        """
        try:
            exception_text = unicode(data.get('process_exception', ''))
        except UnicodeDecodeError:
            exception_text = str(data.get('process_exception', ''))
        return { 'exception_text': exception_text }

    ############################################################################
    # States
    ############################################################################

    states = {
        'init': {
            'actions': [],
            'result': {'type':'form', 'arch': _init_form, 'fields': {}, 'state':[('end', 'Cancel', 'gtk-cancel', True), ('calculate_records', 'Calculate', 'gtk-apply', True)]}
        },
        'calculate_records': {
            'actions': [],
            'result': {'type': 'choice', 'next_state': _calculate_in_background_choice}
        },
        'progress': {
            'actions': [_progress_action],
            'result': {'type': 'form', 'arch': _progress_form, 'fields': _progress_fields, 'state':[('end','Close (continues in background)', 'gtk-cancel', True),('calculate_records','Keep waiting', 'gtk-go-forward', True)]}
        },
        'done': {
            'actions': [],
            'result': {'type': 'form', 'arch': _done_form, 'fields': {}, 'state':[('end','Done', 'gtk-ok', True)]}
        },
        'show_exception': {
            'actions': [_show_exception_action],
            'result': {'type': 'form', 'arch': _show_exception_form, 'fields': _show_exception_fields, 'state':[('end','Done', 'gtk-ok', True)]}
        }
    }

wizard_calculate('l10n_es_aeat_mod347.calculate_wizard')

<|endoftext|>


<commit_before>from flask import Flask, request, Response
from flask.ext.pymongo import PyMongo
from crypto import *
from api_helpers import *
from storage import *

app = Flask(__name__)
app.config.from_object('settings')
mongo = PyMongo(app)

@app.route('/')
def hello():
    return 'Hello World!'

@app.route('/pubkey/add', methods=['POST'])
def add_pubkey():
    db = mongo.db
    username = request.form['username']
    pubkey = request.form['pubkey']
    shibboleth = request.form['shibboleth']
    signature = request.form['signature']

    key = db.keys.find_one({'username': username})
    if key:
        return json_error("username already exists", 400)

    if check_signature(pubkey, shibboleth, signature):
        if db.keys.insert({'username': username, 'pubkey': pubkey}):
            return json_success()
        return json_error('database insertion failure', 500)
    return json_error('invalid signature', 400)

@app.route('/pubkey/server')
def server_pub():
    return app.config['PUB_KEY'], 200, {'Content-Type': 'text/plain'}

@app.route('/pubkey/<username>')
def get_pubkey(username):
    db = mongo.db
    entry = db.keys.find_one({'username': username})

    if entry:
        return entry['pubkey'], 200, {'Content-Type': 'text/plain'}
    else:
        return '', 404, {}

@app.route('/authenticate', methods=['POST'])
def authenticate():
    username = request.form['username']
    signature = authenticate_user(mongo.db, app, request.form)

    resp = Response(*json_success())
    resp.set_cookie('username', username)
    resp.set_cookie('signature', signature)

    return resp

@app.route('/file/upload', methods=['POST'])
def file_upload():
    username = current_user(app, request.cookies)
    if username:
        f = request.files['file']
        aes_key = request.headers['X-Symmetric-Key']

        if store_file(f, username, aes_key, mongo.db):
            return json_success()
        return json_error('database error', 500)

    return json_error('not authenticated', 401)

@app.route('/file/download/<filename>')
def file_download(filename):
    username = current_user(app, request.cookies)
    if username:
        finfo = get_fileinfo(mongo.db, username, filename)
        f = find_file(mongo.db, finfo)

        headers = {'Content-Type': f.content_type,
                   'Content-Length': f.length,
                   'Content-Disposition': 'attachment; filename='+f.filename,
                   'X-Symmetric-Key': finfo['aes_key']}

        return f.read(), 200, headers

    return json_error('not authenticated', 401)

@app.route('/file/list')
def file_list():
    username = current_user(app, request.cookies)
    if username:
        files = [finfo['filename'] for finfo in list_files(mongo.db, username)]
        return json_result({'result': 'success', 'files': files})

    return json_error('not authenticated', 401)

@app.route('/file/info/<filename>')
def file_info(filename):
    username = current_user(app, request.cookies)
    if username:
        finfo = get_fileinfo(mongo.db, username, filename)
        f = find_file(mongo.db, finfo)
        del finfo['file_id']
        del finfo['_id']
        finfo['date'] = finfo['date'].strftime('%Y-%m-%d %H:%M:%S')
        finfo['type'] = f.content_type
        finfo['length'] = f.length

        resp = {'result':'success', 'fileinfo':finfo}
        return json_result(resp)

    return json_error('not authenticated', 401)

@app.route('/file/share', methods=['POST'])
def file_share():
    username = current_user(app, request.cookies)
    if username:
        aes_key = request.headers['X-Symmetric-Key']
        recipient = request.form['recipient']
        filename = requests.form['filename']
        if copy_file(db, username, recipient, filename, aes_key):
            return json_success()

    return json_error('not authenticated', 401)

<commit_msg>another accidental plural<commit_after>from flask import Flask, request, Response
from flask.ext.pymongo import PyMongo
from crypto import *
from api_helpers import *
from storage import *

app = Flask(__name__)
app.config.from_object('settings')
mongo = PyMongo(app)

@app.route('/')
def hello():
    return 'Hello World!'

@app.route('/pubkey/add', methods=['POST'])
def add_pubkey():
    db = mongo.db
    username = request.form['username']
    pubkey = request.form['pubkey']
    shibboleth = request.form['shibboleth']
    signature = request.form['signature']

    key = db.keys.find_one({'username': username})
    if key:
        return json_error("username already exists", 400)

    if check_signature(pubkey, shibboleth, signature):
        if db.keys.insert({'username': username, 'pubkey': pubkey}):
            return json_success()
        return json_error('database insertion failure', 500)
    return json_error('invalid signature', 400)

@app.route('/pubkey/server')
def server_pub():
    return app.config['PUB_KEY'], 200, {'Content-Type': 'text/plain'}

@app.route('/pubkey/<username>')
def get_pubkey(username):
    db = mongo.db
    entry = db.keys.find_one({'username': username})

    if entry:
        return entry['pubkey'], 200, {'Content-Type': 'text/plain'}
    else:
        return '', 404, {}

@app.route('/authenticate', methods=['POST'])
def authenticate():
    username = request.form['username']
    signature = authenticate_user(mongo.db, app, request.form)

    resp = Response(*json_success())
    resp.set_cookie('username', username)
    resp.set_cookie('signature', signature)

    return resp

@app.route('/file/upload', methods=['POST'])
def file_upload():
    username = current_user(app, request.cookies)
    if username:
        f = request.files['file']
        aes_key = request.headers['X-Symmetric-Key']

        if store_file(f, username, aes_key, mongo.db):
            return json_success()
        return json_error('database error', 500)

    return json_error('not authenticated', 401)

@app.route('/file/download/<filename>')
def file_download(filename):
    username = current_user(app, request.cookies)
    if username:
        finfo = get_fileinfo(mongo.db, username, filename)
        f = find_file(mongo.db, finfo)

        headers = {'Content-Type': f.content_type,
                   'Content-Length': f.length,
                   'Content-Disposition': 'attachment; filename='+f.filename,
                   'X-Symmetric-Key': finfo['aes_key']}

        return f.read(), 200, headers

    return json_error('not authenticated', 401)

@app.route('/file/list')
def file_list():
    username = current_user(app, request.cookies)
    if username:
        files = [finfo['filename'] for finfo in list_files(mongo.db, username)]
        return json_result({'result': 'success', 'files': files})

    return json_error('not authenticated', 401)

@app.route('/file/info/<filename>')
def file_info(filename):
    username = current_user(app, request.cookies)
    if username:
        finfo = get_fileinfo(mongo.db, username, filename)
        f = find_file(mongo.db, finfo)
        del finfo['file_id']
        del finfo['_id']
        finfo['date'] = finfo['date'].strftime('%Y-%m-%d %H:%M:%S')
        finfo['type'] = f.content_type
        finfo['length'] = f.length

        resp = {'result':'success', 'fileinfo':finfo}
        return json_result(resp)

    return json_error('not authenticated', 401)

@app.route('/file/share', methods=['POST'])
def file_share():
    username = current_user(app, request.cookies)
    if username:
        aes_key = request.headers['X-Symmetric-Key']
        recipient = request.form['recipient']
        filename = request.form['filename']
        if copy_file(db, username, recipient, filename, aes_key):
            return json_success()

    return json_error('not authenticated', 401)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

__all__ = ['FETCHERS', 'FETCHERS_DATASETS']

FETCHERS = {}
FETCHERS_DATASETS = {}

try:
    from dlstats.fetchers.bis import BIS, DATASETS as DATASETS_BIS
    FETCHERS['BIS'] = BIS
    FETCHERS_DATASETS['BIS'] = DATASETS_BIS.copy()
    __all__.append('BIS')
except ImportError:
    pass

try:
    from dlstats.fetchers.oecd import OECD, DATASETS as DATASETS_OECD
    FETCHERS['OECD'] = OECD
    FETCHERS_DATASETS['OECD'] = DATASETS_OECD.copy()
    __all__.append('OECD')
except ImportError:
    pass

try:
    from dlstats.fetchers.eurostat import Eurostat
    FETCHERS['EUROSTAT'] = Eurostat
    #TODO: FETCHERS_DATASETS['EUROSTAT'] = None
    __all__.append('Eurostat')
except ImportError:
    pass

try:
    from dlstats.fetchers.world_bank import WorldBank
    FETCHERS['WORLDBANK'] = WorldBank
    #TODO: FETCHERS_DATASETS['WB'] = None
    __all__.append('WorldBank')
except ImportError:
    pass

try:
    from dlstats.fetchers.IMF import IMF, DATASETS as DATASETS_IMF
    FETCHERS['IMF'] = IMF
    FETCHERS_DATASETS['IMF'] = DATASETS_IMF
    __all__.append('IMF')
except ImportError:
    pass

try:
    from dlstats.fetchers.BEA import BEA
    FETCHERS['BEA'] = BEA
    #TODO: FETCHERS_DATASETS['BEA'] = None
    __all__.append('BEA')
except ImportError:
    pass

try:
    from dlstats.fetchers.ecb import ECB
    FETCHERS['ECB'] = ECB
    #TODO: FETCHERS_DATASETS['ECB'] = None
    __all__.append('ECB')
except ImportError:
    pass

try:
    from dlstats.fetchers.esri import Esri
    FETCHERS['ESRI'] = Esri
    #TODO: FETCHERS_DATASETS['ESRI'] = None
    __all__.append('Esri')
except ImportError:
    pass

try:
    from dlstats.fetchers.insee import INSEE
    FETCHERS['INSEE'] = INSEE
    __all__.append('INSEE')
except ImportError:
    pass

#try:
#    from dlstats.fetchers.destatis import DESTATIS
#    FETCHERS['DESTATIS'] = DESTATIS
#    __all__.append('DESTATIS')
#except ImportError:
#    pass

try:
    from dlstats.fetchers.fed import FED
    FETCHERS['FED'] = FED
    __all__.append('FED')
except ImportError:
    pass
<commit_msg>comments WorldBank/OECD/BEA Fetcher - attempt updates<commit_after># -*- coding: utf-8 -*-

__all__ = ['FETCHERS', 'FETCHERS_DATASETS']

FETCHERS = {}
FETCHERS_DATASETS = {}

try:
    from dlstats.fetchers.bis import BIS, DATASETS as DATASETS_BIS
    FETCHERS['BIS'] = BIS
    FETCHERS_DATASETS['BIS'] = DATASETS_BIS.copy()
    __all__.append('BIS')
except ImportError:
    pass

#try:
#    from dlstats.fetchers.oecd import OECD, DATASETS as DATASETS_OECD
#    FETCHERS['OECD'] = OECD
#    FETCHERS_DATASETS['OECD'] = DATASETS_OECD.copy()
#    __all__.append('OECD')
#except ImportError:
#    pass

try:
    from dlstats.fetchers.eurostat import Eurostat
    FETCHERS['EUROSTAT'] = Eurostat
    #TODO: FETCHERS_DATASETS['EUROSTAT'] = None
    __all__.append('Eurostat')
except ImportError:
    pass

#try:
#    from dlstats.fetchers.world_bank import WorldBank
#    FETCHERS['WORLDBANK'] = WorldBank
#    #TODO: FETCHERS_DATASETS['WB'] = None
#    __all__.append('WorldBank')
#except ImportError:
#    pass

try:
    from dlstats.fetchers.imf import IMF
    FETCHERS['IMF'] = IMF
    __all__.append('IMF')
except ImportError:
    pass

#try:
#    from dlstats.fetchers.bea import BEA
#    FETCHERS['BEA'] = BEA
#    #TODO: FETCHERS_DATASETS['BEA'] = None
#    __all__.append('BEA')
#except ImportError:
#    pass

try:
    from dlstats.fetchers.ecb import ECB
    FETCHERS['ECB'] = ECB
    #TODO: FETCHERS_DATASETS['ECB'] = None
    __all__.append('ECB')
except ImportError:
    pass

try:
    from dlstats.fetchers.esri import Esri
    FETCHERS['ESRI'] = Esri
    #TODO: FETCHERS_DATASETS['ESRI'] = None
    __all__.append('Esri')
except ImportError:
    pass

try:
    from dlstats.fetchers.insee import INSEE
    FETCHERS['INSEE'] = INSEE
    __all__.append('INSEE')
except ImportError:
    pass

#try:
#    from dlstats.fetchers.destatis import DESTATIS
#    FETCHERS['DESTATIS'] = DESTATIS
#    __all__.append('DESTATIS')
#except ImportError:
#    pass

try:
    from dlstats.fetchers.fed import FED
    FETCHERS['FED'] = FED
    __all__.append('FED')
except ImportError:
    pass
<|endoftext|>


<commit_before>import re

from twilio import twiml
from flask import g, request, redirect, url_for
from calloncongress import settings, data
from calloncongress.helpers import digitless_url, read_context, write_context, flush_context, get_lang, get_zip

def language_selection():
    if not get_lang():
        errors = []
        r = twiml.Response()

        # Handle twimlet-style params
        if 'language' in g.request_params.keys():
            sel = g.request_params['language']
            try:
                sel = int(sel)
                write_context('language', settings.LANGUAGES[sel - 1][0])
            except ValueError:
                if sel in [lang[0] for lang in settings.LANGUAGES]:
                    write_context('language', sel)

        # Collect and wipe digits if named params are not set
        if 'Digits' in g.request_params.keys():
            sel = int(g.request_params.get('Digits', 1))
            try:
                write_context('language', settings.LANGUAGES[sel - 1][0])
            except:
                errors.append('%d is not a valid selection, please try again.')

            del g.request_params['Digits']

        # Prompt and gather if language is not valid
        if not get_lang():
            with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT, action=request.path) as rg:
                if not len(errors):
                    rg.say("""Welcome to Call on Congress, the Sunlight Foundation's
                              free service that helps you keep our lawmakers accountable
                              with important information about our government.
                           """)
                else:
                    rg.say(' '.join(errors))
                rg.say('Press 1 to continue in English.', language='en')
                rg.say('Presione 2 para continuar en espanol.', language='es')

            return r

    return True

def zipcode_selection():
    if not get_zip():
        errors = []
        r = twiml.Response()

        if 'Digits' in g.request_params.keys():
            sel = g.request_params.get('Digits')
            if len(sel) == 5:
                write_context('zipcode', int(sel))
            else:
                errors.append('%s is not a valid zipcode, please try again.' % sel)

            del g.request_params['Digits']

        if not get_zip():
            if request.path.startswith == '/member':
                reason = 'To help us identify your representatives,'
            elif request.path.startswith == '/voting':
                reason = 'To help us find your election office,'
            else:
                reason = None

            with r.gather(numDigits=5, timeout=settings.INPUT_TIMEOUT, action=request.path) as rg:
                if len(errors):
                    rg.say(' '.join(errors))
                if reason:
                    rg.say(reason)
                rg.say("""please use the telephone keypad to enter
                          your five-digit zip code now.""")

            return r

    return True

def bioguide_selection():
    errors = []
    r = twiml.Response()

    # Handle twimlet-style params
    if 'bioguide_id' in g.request_params.keys():
        return True

    # Make sure there's a legislators list in the call context.
    # If not, short-circuit to zip collection and repost to get legislator list
    # before prompting for a selection.
    if 'Digits' in g.request_params.keys():
        if not len(read_context('legislators', [])):
            del g.request_params['Digits']
            return bioguide_selection()

        sel = g.request_params['Digits']
        del g.request_params['Digits']
        try:
            legislator = read_context('legislators')[sel - 1]
            g.request_params['bioguide_id'] = legislator['bioguide_id']
            return True
        except:
            errors.append('%d is not a valid selection, please try again.')

    if 'bioguide_id' not in g.request_params.keys():
        if not len(read_context('legislators', [])):
            if not get_zip():
                return zipcode_selection()
            load_members_for(get_zip())

        legislators = read_context('legislators', [])
        if len(legislators):
            if len(legislators) > 3:
                r.say("""Since your zip code covers more than one congressional district,
                         you will be provided with a list of all possible legislators that
                         may represent you. Please select from the following names:""")
            else:
                r.say("""We identified your representatives in Congress. Please select from
                         the following names:""")

            with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg:
                options = [(l['fullname'], l['bioguide_id']) for l in legislators]
                script = " ".join("Press %i for %s." % (index + 1, o[0]) for index, o in enumerate(options))
                script += " Press 0 to enter a new zipcode."
                rg.say(script)
        else:
            if not get_lang() and g.request_params.get('lanugae'):
                write_context('language', g.request_params.get('language'))

            r.say("I'm sorry, we weren't able to locate any representatives for %s." % get_zip())
            flush_context('zipcode')
            with r.gather(numDigits=5, timeout=settings.INPUT_TIMEOUT, action=url_for('.members', next_url=request.path)) as rg:
                rg.say("Please enter a new zip code.")

        return r

    return True

def bill_selection():
    if 'bill_id' in g.request_params.keys():
        return True

    r = twiml.Response()
    r.redirect(url_for('.bill_search'))
    return r

def bill_type(abbr):
    abbr = re.split(r'([a-zA-Z.\-]*)', abbr)[1].lower().replace('.', '')
    return {
        'hr': 'House Bill',
        'hres': 'House Resolution',
        'hjres': 'House Joint Resolution',
        'hcres': 'House Concurrent Resolution',
        's': 'Senate Bill',
        'sres': 'Senate Resolution',
        'sjres': 'Senate Joint Resolution',
        'scres': 'Senate Concurrent Resolution',
    }.get(abbr)

def load_members_for(zipcode):
    legislators = data.legislators_for_zip(zipcode)
    write_context('legislators', legislators)
    return legislators

def load_member_for(bioguide):
    legislator = data.legislator_by_bioguide(bioguide)
    write_context('legislator', legislator)
    return legislator

# def parent_url_for(current):
#     from calloncongress.voice.menu import MENU
#     parent = MENU.get(current).get('parent', 'main')
#     try:
#         if parent.func_name == 'referrer':
#             try:
#                 parent = parent_url_for(g.referrer)
#             except AttributeError:
#                 parent = 'main'
#     except AttributeError:
#         pass

#     return url_for(MENU.get(parent).get('route'))

def handle_selection(response, **kwargs):
    from calloncongress.voice.menu import MENU
    params = kwargs.get('params', {})
    try:
        sel = int(kwargs['selection'])
        menu = MENU[kwargs['menu']]

        if sel == 9:
            parent_menu = MENU[menu['parent']]
            response.redirect(url_for(parent_menu['route']))
            return response

        choice = [choice['action'] for choice in menu['choices'] if choice['key'] == sel][0]
        response.redirect(url_for(choice, **params))
        return response
    except:
        response.say('Sorry, an error occurred.')
        try:
            response.redirect(url_for(MENU[kwargs['menu']]['route']))
            return response
        except:
            pass

    response.redirect(url_for('.index'))
    return response

def next_action(response, **kwargs):
    if 'next_url' in g.request_params.keys():
        response.redirect(g.request_params['next_url'])
    elif 'default' in kwargs:
        response.redirect(kwargs['default'])
    else:
        response.redirect(url_for('.index'))

    return response
<commit_msg>logical rethink of bioguide validator<commit_after>import re

from twilio import twiml
from flask import g, request, redirect, url_for
from calloncongress import settings, data
from calloncongress.helpers import digitless_url, read_context, write_context, flush_context, get_lang, get_zip

def language_selection():
    """Ensures a language has been selected before proceeding with call flow, by:
        - If a get param is sent, store it and return.
        - If the context already has a language, return.
        - If a language choice was passed back, pull it out of settings, store it and return.
        - If nothing was sent, prompt the user with available choices.
       This only needs to be set once during the life of a call.
    """

    # Twimlet-style params always override language settings
    if 'language' in g.request_params.keys():
        sel = g.request_params['language']
        try:
            sel = int(sel)
            write_context('language', settings.LANGUAGES[sel - 1][0])
        except ValueError:
            if sel in [lang[0] for lang in settings.LANGUAGES]:
                write_context('language', sel)

    # Internal app use
    if not get_lang():
        errors = []
        r = twiml.Response()

        # Collect and wipe digits if a choice was submitted
        if 'Digits' in g.request_params.keys():
            sel = int(g.request_params.get('Digits', 1))
            try:
                write_context('language', settings.LANGUAGES[sel - 1][0])
            except:
                errors.append('%d is not a valid selection, please try again.')

            del g.request_params['Digits']

        # Prompt and gather if language is not valid or no choice was submitted
        if not get_lang():
            with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT, action=request.path) as rg:
                if not len(errors):
                    rg.say("""Welcome to Call on Congress, the Sunlight Foundation's
                              free service that helps you keep our lawmakers accountable
                              with important information about our government.
                           """)
                else:
                    rg.say(' '.join(errors))
                rg.say('Press 1 to continue in English.', language='en')
                rg.say('Presione 2 para continuar en espanol.', language='es')

            return r

    return True

def zipcode_selection():
    """Ensures a zipcode has been selected before proceeding with call flow, by:
        - If a get param is sent, store it and return.
        - If the context already has a zipcode, return.
        - If a language choice was passed back, pull it out of settings, store it and return.
        - If nothing was sent, prompt the user with available choices.
       This only needs to be set once during the life of a call.
    """

    # Twimlet use
    if 'zipcode' in g.request_params.keys():
        write_context('zipcode', int(sel))

    # Internal app use
    if not get_zip():
        errors = []
        r = twiml.Response()

        # Collect and wipe digits if a choice was submitted
        if 'Digits' in g.request_params.keys():
            sel = g.request_params.get('Digits')
            if len(sel) == 5:
                write_context('zipcode', int(sel))
            else:
                errors.append('%s is not a valid zipcode, please try again.' % sel)

            del g.request_params['Digits']

        # Prompt and gather if zip is not valid or no choice was submitted
        if not get_zip():
            if request.path.startswith == '/member':
                reason = 'To help us identify your representatives,'
            elif request.path.startswith == '/voting':
                reason = 'To help us find your election office,'
            else:
                reason = None

            with r.gather(numDigits=5, timeout=settings.INPUT_TIMEOUT, action=request.path) as rg:
                if len(errors):
                    rg.say(' '.join(errors))
                if reason:
                    rg.say(reason)
                rg.say("""please use the telephone keypad to enter
                          your five-digit zip code now.""")

            return r

    return True

def bioguide_selection():
    """Ensures a Bioguide ID is present in request params before proceeding with call flow.
       This is not stored in the context, only passed in params. Logic as follows:
        - If a get param is sent, return.
        - If a list of possible legislators is stored in context, and a choice was passed,
            append the choice's Bioguide ID to params and return.
        - If no list of legislators is present in context, prompt for zipcode and load legislators,
            then prompt for a selection.
    """
    r = twiml.Response()

    # Handle twimlet-style params
    if 'bioguide_id' in g.request_params.keys():
        return True

    # Make sure there's a legislators list in the call context.
    # If not, short-circuit to zip collection and repost to get legislator list
    # before prompting for a selection.
    legislators = read_context('legislators', [])
    if 'Digits' in g.request_params.keys() and len(legislators):
        sel = g.request_params['Digits']
        del g.request_params['Digits']
        try:
            legislator = read_context('legislators')[sel - 1]
            g.request_params['bioguide_id'] = legislator['bioguide_id']

            return True
        except:
            r.say('%d is not a valid selection, please try again.' % sel)

    # If we don't have a bioguide, or legislators, or a zip selection,
    # skip this and get a zip code first.
    if not len(legislators) and not get_zip() and not 'Digits' in g.request_params.keys():
        return zipcode_selection()

    # If we do have a zip code selection, store it before trying to get legislators.
    if not len(legislators) and not get_zip():
        zipcode_selection()

    # If we have a zip and no legislators, load them.
    if not len(legislators):
        load_members_for(get_zip())
        legislators = read_context('legislators', [])

    # If there are legislators, prompt for a choice. If still nothing, fail and get a new zip.
    if len(legislators):
        if len(legislators) > 3:
            r.say("""Since your zip code covers more than one congressional district,
                     you will be provided with a list of all possible legislators that
                     may represent you. Please select from the following names:""")
        else:
            r.say("""We identified your representatives in Congress. Please select from
                     the following names:""")

        with r.gather(numDigits=1, timeout=settings.INPUT_TIMEOUT) as rg:
            options = [(l['fullname'], l['bioguide_id']) for l in legislators]
            script = " ".join("Press %i for %s." % (index + 1, o[0]) for index, o in enumerate(options))
            script += " Press 0 to enter a new zipcode."
            rg.say(script)
    else:
        r.say("I'm sorry, we weren't able to locate any representatives for %s." % get_zip())
        flush_context('zipcode')
        try:
            del g.request_params['Digits']
        except:
            pass

    return r

def bill_selection():
    if 'bill_id' in g.request_params.keys():
        return True

    r = twiml.Response()
    r.redirect(url_for('.bill_search'))
    return r

def bill_type(abbr):
    abbr = re.split(r'([a-zA-Z.\-]*)', abbr)[1].lower().replace('.', '')
    return {
        'hr': 'House Bill',
        'hres': 'House Resolution',
        'hjres': 'House Joint Resolution',
        'hcres': 'House Concurrent Resolution',
        's': 'Senate Bill',
        'sres': 'Senate Resolution',
        'sjres': 'Senate Joint Resolution',
        'scres': 'Senate Concurrent Resolution',
    }.get(abbr)

def load_members_for(zipcode):
    legislators = data.legislators_for_zip(zipcode)
    write_context('legislators', legislators)
    return legislators

def load_member_for(bioguide):
    legislator = data.legislator_by_bioguide(bioguide)
    write_context('legislator', legislator)
    return legislator

# def parent_url_for(current):
#     from calloncongress.voice.menu import MENU
#     parent = MENU.get(current).get('parent', 'main')
#     try:
#         if parent.func_name == 'referrer':
#             try:
#                 parent = parent_url_for(g.referrer)
#             except AttributeError:
#                 parent = 'main'
#     except AttributeError:
#         pass

#     return url_for(MENU.get(parent).get('route'))

def handle_selection(response, **kwargs):
    from calloncongress.voice.menu import MENU
    params = kwargs.get('params', {})
    try:
        sel = int(kwargs['selection'])
        menu = MENU[kwargs['menu']]

        if sel == 9:
            parent_menu = MENU[menu['parent']]
            response.redirect(url_for(parent_menu['route']))
            return response

        choice = [choice['action'] for choice in menu['choices'] if choice['key'] == sel][0]
        response.redirect(url_for(choice, **params))
        return response
    except:
        response.say('Sorry, an error occurred.')
        try:
            response.redirect(url_for(MENU[kwargs['menu']]['route']))
            return response
        except:
            pass

    response.redirect(url_for('.index'))
    return response

def next_action(response, **kwargs):
    if 'next_url' in g.request_params.keys():
        response.redirect(g.request_params['next_url'])
    elif 'default' in kwargs:
        response.redirect(kwargs['default'])
    else:
        response.redirect(url_for('.index'))

    return response
<|endoftext|>


<commit_before>__author__ = 'Victor Rajewski'

from django.conf.urls import patterns, include, url
from django.contrib.auth.decorators import login_required

from django.conf import settings

from . import views

urlpatterns = patterns('',
    url(r'^$', login_required(views.BadgeIndex.as_view()), name='mome_rath.index'),
    url(r'^badge/(?P<slug>[^/]+)/?$', login_required(views.BadgeDetail.as_view()), name='mome_rath.badge_detail'),
    url(r'^badge/(?P<slug>[^/]+)/edit?$', login_required(views.BadgeEdit.as_view()), name='mome_rath.badge_edit'),
    url(r'^create$', login_required(views.BadgeCreate.as_view()), name='mome_rath.badge_create'),
#    url(r'^badge/(?P<slug>[^/]+)/award', login_required(views.AwardBadge.as_view()), name='mome_rath.award_badge'),
#    url(r'^user/(?P<username>[^/]+)/?$', 'awards_by_user', name='mome_rath.awards_by_user'),
    )

'''
    url(r'^$', 'badges_list', name='badger.badges_list'),
    url(r'^staff_tools$', 'staff_tools',
        name='badger.staff_tools'),
    url(r'^tag/(?P<tag_name>.+)/?$', 'badges_list',
        name='badger.badges_list'),
    url(r'^awards/?', 'awards_list',
        name='badger.awards_list'),
    url(r'^badge/(?P<slug>[^/]+)/awards/?$', 'awards_list',
        name='badger.awards_list_for_badge'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)\.json$', 'award_detail',
        kwargs=dict(format="json"),
        name='badger.award_detail_json'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)/?$', 'award_detail',
        name='badger.award_detail'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)/delete$', 'award_delete',
        name='badger.award_delete'),
    url(r'^badge/(?P<slug>[^/]+)/claims/(?P<claim_group>.+)\.pdf$', 'claims_list',
        kwargs=dict(format='pdf'),
        name='badger.claims_list_pdf'),
    url(r'^badge/(?P<slug>[^/]+)/claims/(?P<claim_group>[^/]+)/?$', 'claims_list',
        name='badger.claims_list'),
    url(r'^claim/(?P<claim_code>[^/]+)/?$', 'claim_deferred_award',
        name='badger.claim_deferred_award'),
    url(r'^claim/?$', 'claim_deferred_award',
        name='badger.claim_deferred_award_form'),
    url(r'^badge/(?P<slug>.+)\.json$', 'detail',
        kwargs=dict(format="json"),
        name='badger.detail_json'),
    url(r'^badge/(?P<slug>[^/]+)/?$', 'detail',
        name='badger.detail'),
    url(r'^badge/(?P<slug>[^/]+)/awards/?$', 'awards_by_badge',
        name='badger.awards_by_badge'),

    url(r'^badge/(?P<slug>[^/]+)/nominate$', 'nominate_for',
        name='badger.nominate_for'),
    url(r'^badge/(?P<slug>[^/]+)/edit$', 'edit',
        name='badger.badge_edit'),
    url(r'^badge/(?P<slug>[^/]+)/delete$', 'delete',
        name='badger.badge_delete'),
    url(r'^badge/(?P<slug>[^/]+)/nominations/(?P<id>\d+)/?$', 'nomination_detail',
        name='badger.nomination_detail'),
    url(r'^users/(?P<username>[^/]+)/badges/?$', 'badges_by_user',
        name='badger.badges_by_user'),
'''<commit_msg>changed create badge url to /new-badge<commit_after>__author__ = 'Victor Rajewski'

from django.conf.urls import patterns, include, url
from django.contrib.auth.decorators import login_required

from django.conf import settings

from . import views

urlpatterns = patterns('',
    url(r'^$', login_required(views.BadgeIndex.as_view()), name='mome_rath.index'),
    url(r'^badge/(?P<slug>[^/]+)/?$', login_required(views.BadgeDetail.as_view()), name='mome_rath.badge_detail'),
    url(r'^badge/(?P<slug>[^/]+)/edit?$', login_required(views.BadgeEdit.as_view()), name='mome_rath.badge_edit'),
    url(r'^new-badge$', login_required(views.BadgeCreate.as_view()), name='mome_rath.badge_create'),
#    url(r'^badge/(?P<slug>[^/]+)/award', login_required(views.AwardBadge.as_view()), name='mome_rath.award_badge'),
#    url(r'^user/(?P<username>[^/]+)/?$', 'awards_by_user', name='mome_rath.awards_by_user'),
    )

'''
    url(r'^$', 'badges_list', name='badger.badges_list'),
    url(r'^staff_tools$', 'staff_tools',
        name='badger.staff_tools'),
    url(r'^tag/(?P<tag_name>.+)/?$', 'badges_list',
        name='badger.badges_list'),
    url(r'^awards/?', 'awards_list',
        name='badger.awards_list'),
    url(r'^badge/(?P<slug>[^/]+)/awards/?$', 'awards_list',
        name='badger.awards_list_for_badge'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)\.json$', 'award_detail',
        kwargs=dict(format="json"),
        name='badger.award_detail_json'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)/?$', 'award_detail',
        name='badger.award_detail'),
    url(r'^badge/(?P<slug>[^/]+)/awards/(?P<id>\d+)/delete$', 'award_delete',
        name='badger.award_delete'),
    url(r'^badge/(?P<slug>[^/]+)/claims/(?P<claim_group>.+)\.pdf$', 'claims_list',
        kwargs=dict(format='pdf'),
        name='badger.claims_list_pdf'),
    url(r'^badge/(?P<slug>[^/]+)/claims/(?P<claim_group>[^/]+)/?$', 'claims_list',
        name='badger.claims_list'),
    url(r'^claim/(?P<claim_code>[^/]+)/?$', 'claim_deferred_award',
        name='badger.claim_deferred_award'),
    url(r'^claim/?$', 'claim_deferred_award',
        name='badger.claim_deferred_award_form'),
    url(r'^badge/(?P<slug>.+)\.json$', 'detail',
        kwargs=dict(format="json"),
        name='badger.detail_json'),
    url(r'^badge/(?P<slug>[^/]+)/?$', 'detail',
        name='badger.detail'),
    url(r'^badge/(?P<slug>[^/]+)/awards/?$', 'awards_by_badge',
        name='badger.awards_by_badge'),

    url(r'^badge/(?P<slug>[^/]+)/nominate$', 'nominate_for',
        name='badger.nominate_for'),
    url(r'^badge/(?P<slug>[^/]+)/edit$', 'edit',
        name='badger.badge_edit'),
    url(r'^badge/(?P<slug>[^/]+)/delete$', 'delete',
        name='badger.badge_delete'),
    url(r'^badge/(?P<slug>[^/]+)/nominations/(?P<id>\d+)/?$', 'nomination_detail',
        name='badger.nomination_detail'),
    url(r'^users/(?P<username>[^/]+)/badges/?$', 'badges_by_user',
        name='badger.badges_by_user'),
'''<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

__author__ = """Chris Tabor (dxdstudio@gmail.com)"""

from pyquery import PyQuery as Pq
from reflector import Reflector
from pprint import pprint as ppr

DEBUG = __name__ == '__main__'

class CSSReflector(Reflector):

    invalid_tags = ['body', 'head', 'title', 'meta']

    def __init__(self, nested=True, newlines_and_spaces=False):
        self.newlines_and_spaces = newlines_and_spaces
        self.nested = nested
        if nested:
            self.selectors = set()
        else:
            self.selectors = {'classes': set(), 'ids': set()}

    def __str__(self):
        ppr(self.selectors)
        return ''

    def _is_root_body_node(self, element):
        """Determine if element is a direct child of <html> or <body>,
        and thus a 'root' element (outside of html)"""
        parent = Pq(element).parent()[0].tag
        return parent in ['body', 'html']

    def _add_nested(self, k, el):
        """Parse nested element by its children."""
        el = Pq(el)
        tagname = Pq(el)[0].tag
        if tagname in self.invalid_tags:
            return
        selector = ''
        id, classes = el.attr('id'), el.attr('class')
        id = '#{}'.format(id) if id is not None else ''
        classes = '.{}'.format(classes) if classes is not None else ''
        if not id and not classes:
            selector = el[0].tag
        selector += '{}{}'.format(id, classes)
        children = Pq(el).children()
        if self._is_root_body_node(el):
            # Add for single nodes only
            if not children:
                self.selectors.add(selector)
            # Build nested css by traversing all child nodes and getting
            # their attributes.
            while children:
                for child in children:
                    child = Pq(child)
                    id, classes = child.attr('id'), child.attr('class')
                    # Order is important here. Id comes first, then classes,
                    # and classes must not have a space at the beginning,
                    # but must have one at the end, so that nested elements
                    # are properly represented, as well as selector chains.
                    if id is not None:
                        selector += ' #{}'.format(id)
                    if classes is not None:
                        classes = '.'.join(classes.split(' '))
                        selector += '.{} '.format(classes)
                    # Update child
                    children = Pq(child).children()
                    # Add selector on each loop, to show
                    # all variations of nesting in the css.
                    self.selectors.add(selector)
                    # Break on the first loop, since we replace children
                    # in the while loop above,
                    # thus preventing duplicate selectors.
                    break

    def _add(self, k, el):
        """Parse element, without considering children."""
        el = Pq(el)
        id, classes = el.attr('id'), el.attr('class')
        if id is not None:
            self.selectors['ids'].add(id)
        if classes is not None:
            for _class in classes.split(' '):
                self.selectors['classes'].add(_class.strip())

    def make_stylesheet(self, output=None, save_as_string=False):
        """Generate stylesheet string."""
        out = ''
        if self.nested:
            for sel in self.selectors:
                out += '{} '.format(sel) + '{}'
                if self.newlines_and_spaces:
                    out += '\n'
        else:
            for id in self.selectors['ids']:
                out += '#{} '.format(id.strip()) + '{}'
                if self.newlines_and_spaces:
                    out += '\n'
            for _class in self.selectors['classes']:
                out += '.{} '.format(_class.strip()) + '{}'
                if self.newlines_and_spaces:
                    out += '\n'
        if save_as_string:
            return out
        self._write(output, out)

    def _write(self, output, out):
        if not output.endswith('.css'):
            raise ValueError('{} if is not a valid css file.'.format(output))
        with open(output, 'wb+') as newfile:
            newfile.write(out)

    def _process(self):
        if self.nested:
            self.doc.find('*').each(self._add_nested)
        else:
            self.doc.find('*').each(self._add)

    def process_string(self, html_string):
        """Parse html with pyquery."""
        self.doc = Pq(html_string)
        self._process()
        return self

    def process(self, filename):
        with open(filename) as _file:
            self.doc = Pq(_file.read())
        self._process()
        return self

if DEBUG:
    hreflector = CSSReflector(newlines_and_spaces=True)
    hreflector.process('test.html').make_stylesheet('output-test.css')
<commit_msg>Refactor css reflector: - Generate selectors for all levels of nesting - Break functions apart and cleanup - Fix some edge cases with more complicated spacing and chained selectors<commit_after># -*- coding: utf-8 -*-

__author__ = """Chris Tabor (dxdstudio@gmail.com)"""

from pyquery import PyQuery as Pq
from reflector import Reflector
from pprint import pprint as ppr

DEBUG = __name__ == '__main__'

class CSSReflector(Reflector):

    invalid_tags = ['body', 'head', 'title', 'meta']

    def __init__(self, nested=True, newlines_and_spaces=False):
        self.newlines_and_spaces = newlines_and_spaces
        self.nested = nested
        if nested:
            self.selectors = set()
        else:
            self.selectors = {'classes': set(), 'ids': set()}

    def __str__(self):
        ppr(self.selectors)
        return ''

    def _is_root_body_node(self, element):
        """Determine if element is a direct child of <html> or <body>,
        and thus a 'root' element (outside of html)"""
        parent = Pq(element).parent()[0].tag
        return parent in ['body', 'html']

    def _format_classes(self, classes, spaces=''):
        if classes is None:
            return ''
        _classes = ''
        for _class in classes.split(' '):
            _classes += '{spaces}.{}'.format(_class.strip(), spaces=spaces)
        return '{}'.format(_classes)

    def _format_id(self, id):
        return '#{}'.format(id) if id is not None else ''

    def _format_selector(self, el, id, classes):
        selector = ''
        if not id and not classes:
            selector = el[0].tag
        selector += '{}{}'.format(id, classes)
        return selector

    def _add_nested(self, k, el):
        """Parse nested element by its children."""
        el = Pq(el)
        tagname = Pq(el)[0].tag
        if tagname in self.invalid_tags:
            return
        id = self._format_id(el.attr('id'))
        classes = self._format_classes(el.attr('class'))
        selector = self._format_selector(el, id, classes)
        children = Pq(el).children()
        if not self._is_root_body_node(el):
            return
        # Add for single nodes only
        if not children:
            self.selectors.add(selector)
        # Build nested css by traversing all child nodes and getting
        # their attributes.
        while children:
            for child in children:
                # Add first root selector, before appending child selectors.
                self.selectors.add(selector)
                # Build out child selectors to add to this one.
                child = Pq(child)
                id, classes = child.attr('id'), child.attr('class')
                # Order is important here. Id comes first, then classes,
                # and classes must not have a space at the beginning,
                # but must have one at the end, so that nested elements
                # are properly represented, as well as selector chains.
                if id is not None:
                    selector += ' #{}'.format(id)
                if classes is not None:
                    selector += self._format_classes(classes, spaces=' ')
                # Update child
                children = Pq(child).children()
                # Add selector on each loop, to show
                # all levels of nesting in the CSS.
                # e.g. .foo {}, .foo.bar {}. .foo.bar #baz
                self.selectors.add(selector)

    def _add(self, k, el):
        """Parse element, without considering children."""
        el = Pq(el)
        id, classes = el.attr('id'), el.attr('class')
        if id is not None:
            self.selectors['ids'].add(id)
        if classes is not None:
            for _class in classes.split(' '):
                self.selectors['classes'].add(_class.strip())

    def _format_selectors(self, selectors):
        out = ''
        for sel in selectors:
            out += '{} '.format(sel) + '{}'
            if self.newlines_and_spaces:
                out += '\n'
        return out

    def _format_stylesheet(self):
        """Format the output for writing to file or string.
        Styles can be divided as shallow, separate lists of ids and classes,
        or compound, nested CSS (typical)."""
        out = ''
        if self.nested:
            out += self._format_selectors(self.selectors)
        else:
            out += self._format_selectors(self.selectors['ids'])
            out += self._format_selectors(self.selectors['classes'])
        return out

    def make_stylesheet(self, output=None, save_as_string=False):
        """Generate stylesheet string."""
        out = self._format_stylesheet()
        if save_as_string:
            return out
        self._write(output, out)

    def _write(self, output, out):
        if not output.endswith('.css'):
            raise ValueError('{} if is not a valid css file.'.format(output))
        with open(output, 'wb+') as newfile:
            newfile.write(out)

    def _process(self):
        if self.nested:
            self.doc.find('*').each(self._add_nested)
        else:
            self.doc.find('*').each(self._add)

    def process_string(self, html_string):
        """Parse html with pyquery."""
        self.doc = Pq(html_string)
        self._process()
        return self

    def process(self, filename):
        with open(filename) as _file:
            self.doc = Pq(_file.read())
        self._process()
        return self

if DEBUG:
    hreflector = CSSReflector(newlines_and_spaces=True)
    hreflector.process('test.html').make_stylesheet('output-test.css')
<|endoftext|>