예제 #1
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = etalage.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            u'app_conf': conv.set_value(app_conf),
            u'app_dir': conv.set_value(app_dir),
            u'autocompleter_territories_kinds': conv.pipe(
                conv.function(lambda kinds: kinds.split()),
                conv.uniform_sequence(
                    conv.test_in(model.Territory.public_kinds),
                    constructor = lambda kinds: sorted(set(kinds)),
                    ),
                conv.default([
                    # u'AbstractCommuneOfFrance',
                    u'ArrondissementOfCommuneOfFrance',
                    u'ArrondissementOfFrance',
                    u'AssociatedCommuneOfFrance',
                    # u'CantonalFractionOfCommuneOfFrance',
                    u'CantonOfFrance',
                    u'CommuneOfFrance',
                    # u'Country',
                    u'DepartmentOfFrance',
                    u'IntercommunalityOfFrance',
                    # u'InternationalOrganization',
                    u'MetropoleOfCountry',
                    u'Mountain',
                    u'OverseasCollectivityOfFrance',
                    u'PaysOfFrance',
                    u'RegionalNatureParkOfFrance',
                    u'RegionOfFrance',
                    # u'Special',
                    u'UrbanAreaOfFrance',
                    u'UrbanTransportsPerimeterOfFrance',
                    ]),
                ),
            u'brand_name': conv.default(u'Comarquage.fr'),
            u'brand_url': conv.default(u'http://www.comarquage.fr/'),
            u'cache_dir': conv.default(os.path.join(os.path.dirname(app_dir), 'cache')),
            u'categories_collection': conv.default('categories'),
            u'cdn_url': conv.default('http://localhost:7000'),
            u'custom_static_files_dir': conv.default(None),
            u'custom_templates_dir': conv.default(None),
            u'data_updates_collection': conv.default('data_updates'),
            u'data_email': conv.pipe(
                conv.function(lambda lines: lines.split(u',')),
                conv.uniform_sequence(
                    conv.input_to_email,
                    ),
                ),
            u'database': conv.pipe(  # A space-separated list of databases
                conv.function(lambda databases: databases.split()),
                conv.uniform_sequence(
                    conv.noop,
                    # Remove empty items and remove sequence when it is empty.
                    ),
                conv.default(['souk']),
                ),
            u'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            u'default_tab': conv.pipe(
                conv.cleanup_line,
                conv.test_in(['carte', 'liste']),
                conv.default('carte'),
                ),
            u'gadget-integration.js': conv.default(urlparse.urljoin('http://localhost:7002/', 'integration.js')),
            u'global_conf': conv.set_value(global_conf),
            u'handle_competence_territories': conv.pipe(conv.guess_bool, conv.default(True)),
            u'hide_directory': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_export': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_gadget': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_list': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_map': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_minisite': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_category': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_checkboxes': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_legend': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_territory': conv.pipe(conv.guess_bool, conv.default(False)),
            u'hide_term': conv.pipe(conv.guess_bool, conv.default(False)),
            u'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            u'i18n_dir_by_plugin_name': conv.set_value(None),  # set by plugins below
            u'ignored_fields': conv.pipe(
                conv.function(lambda lines: lines.split(u'\n')),
                conv.uniform_sequence(
                    conv.pipe(
                        conv.function(lambda line: line.split(None, 1)),
                        conv.uniform_sequence(conv.input_to_slug),
                        conv.function(lambda seq: dict(zip(['id', 'name'], seq))),
                        conv.empty_to_none,
                        ),
                    drop_none_items = True,
                    ),
                conv.id_name_dict_list_to_ignored_fields,
                ),
            u'index.date.field': conv.default(None),
            u'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            u'markers.piwik.id': conv.pipe(conv.input_to_int, conv.default(None)),
            u'markers.piwik.host': conv.default('http://localhost/piwik'),
            u'markers.piwik.ssl_host': conv.default('https://localhost/piwik'),
            u'organism_types_collection': conv.default('organism_types'),
            u'package_name': conv.default('etalage'),
            u'pager.page_max_size': conv.pipe(conv.input_to_int, conv.default(20)),
            u'petitpois_url': conv.pipe(  # A space-separated list of URLs
                conv.function(lambda urls: urls.split()),
                conv.uniform_sequence(
                    conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
                        full = True),
                    # Remove empty items and remove sequence when it is empty.
                    ),
                conv.default(['http://localhost:5000/']),
                ),
            u'plugins_conf_file': conv.default(None),
            u'realm': conv.default(u'Etalage'),
            u'require_subscription': conv.pipe(conv.guess_bool, conv.default(False)),
            u'reset_on_poi_update': conv.pipe(conv.guess_bool, conv.default(False)),
            # Whether this application serves its own static files.
            u'static_files': conv.pipe(conv.guess_bool, conv.default(True)),
            u'static_files_dir': conv.default(os.path.join(app_dir, 'static')),
            u'subscribers.require_subscription': conv.pipe(conv.guess_bool, conv.default(False)),
            u'subscribers.database': conv.default('souk'),
            u'subscribers.collection': conv.default('subscribers'),
            u'subscribers.gadget_valid_domains': conv.pipe(
                conv.function(lambda hostnames: hostnames.split()),
                conv.default(['localhost', '127.0.0.1', 'comarquage.fr', 'donnees-libres.fr']),
                conv.function(lambda hostnames: tuple(hostnames)),
                ),
            u'subscribers.gadget_type': conv.default('etalage'),
            u'territories_database': conv.noop,  # Done below.
            u'territories_collection': conv.default('territories'),
            u'territories_kinds': conv.pipe(
                conv.function(lambda kinds: kinds.split()),
                conv.uniform_sequence(
                    conv.test_in(model.Territory.public_kinds),
                    constructor = lambda kinds: sorted(set(kinds)),
                    ),
                conv.default([
                    # u'AbstractCommuneOfFrance',
                    u'ArrondissementOfCommuneOfFrance',
                    u'ArrondissementOfFrance',
                    u'AssociatedCommuneOfFrance',
                    # u'CantonalFractionOfCommuneOfFrance',
                    u'CantonOfFrance',
                    u'CommuneOfFrance',
                    # u'Country',
                    u'DepartmentOfFrance',
                    u'IntercommunalityOfFrance',
                    # u'InternationalOrganization',
                    u'MetropoleOfCountry',
                    u'Mountain',
                    u'OverseasCollectivityOfFrance',
                    u'PaysOfFrance',
                    u'RegionalNatureParkOfFrance',
                    u'RegionOfFrance',
                    # u'Special',
                    u'UrbanAreaOfFrance',
                    u'UrbanTransportsPerimeterOfFrance',
                    ]),
                ),
            u'theme_field': conv.pipe(
                conv.function(lambda line: line.split(None, 1)),
                conv.uniform_sequence(conv.input_to_slug),
                conv.function(lambda seq: dict(zip(['id', 'name'], seq))),
                conv.default(dict(id = 'organism-type')),
                ),
            u'tile_layers': conv.pipe(
                conv.function(eval),
                conv.function(strings.deep_decode),
                conv.test_isinstance(list),
                conv.uniform_sequence(
                    conv.pipe(
                        conv.test_isinstance(dict),
                        conv.struct(dict(
                            attribution = conv.pipe(
                                conv.test_isinstance(basestring),
                                conv.not_none,
                                ),
                            name = conv.pipe(
                                conv.test_isinstance(basestring),
                                conv.not_none,
                                ),
                            subdomains = conv.test_isinstance(basestring),
                            url = conv.pipe(
                                conv.test_isinstance(basestring),
                                conv.make_input_to_url(),
                                conv.not_none,
                                ),
                            )),
                        ),
                    ),
                conv.not_none,
                ),
            },
        default = 'drop',
        drop_none_values = False,
        ))(conf))

    # CDN configuration
    conf.update(conv.check(conv.struct(
        {
            u'bootstrap.css': conv.default(urlparse.urljoin(conf['cdn_url'], '/bootstrap/2.2.1/css/bootstrap.min.css')),
            u'bootstrap.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/bootstrap/2.2.1/js/bootstrap.min.js')),
            u'bootstrap-responsive.css': conv.default(
                urlparse.urljoin(conf['cdn_url'], '/bootstrap/2.2.1/css/bootstrap-responsive.min.css')
                ),
            u'easyxdm.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/easyxdm/latest/easyXDM.min.js')),
            u'easyxdm.swf': conv.default(urlparse.urljoin(conf['cdn_url'], '/easyxdm/latest/easyxdm.swf')),
            u'hogan.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/hogan/3.0.0/hogan.js')),
            u'images.markers.url': conv.default(urlparse.urljoin(conf['cdn_url'], '/images/markers/')),
            u'images.misc.url': conv.default(urlparse.urljoin(conf['cdn_url'], '/images/misc/')),
            u'jquery.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/jquery/jquery-1.7.1.min.js')),
            u'jquery-ui.css': conv.default(
                urlparse.urljoin(conf['cdn_url'], '/jquery-ui/1.8.16/themes/smoothness/jquery-ui.css')
                ),
            u'jquery-ui.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/jquery-ui/1.8.16/jquery-ui.min.js')),
            u'json2.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/easyxdm/latest/json2.js')),
            u'leaflet.css': conv.default(urlparse.urljoin(conf['cdn_url'], '/leaflet/leaflet-0.5.1/leaflet.css')),
            u'leaflet.ie.css': conv.default(urlparse.urljoin(conf['cdn_url'], '/leaflet/leaflet-0.5.1/leaflet.ie.css')),
            u'leaflet.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/leaflet/leaflet-0.5.1/leaflet.js')),
            u'pie.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/css3pie/1.0beta5/PIE.js')),
            u'prettify.js': conv.default(urlparse.urljoin(conf['cdn_url'], '/google-code-prettify/187/prettify.js')),
            u'territories_database': conv.pipe(
                conv.default(conf['database'][0]),
                ),
            },
        default = conv.noop,
        ))(conf))

    if len(conf['database']) != len(conf['petitpois_url']):
        raise Exception("Number of databases and number of Petitpois URLs don't match : {0} , {1}".format(
            conf['database'], conf['petitpois_url']))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stdout)

    errorware = conf.setdefault(u'errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'Etalage Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Connect to MongoDB database.
    connection = pymongo.Connection()
    model.dbs = [
        connection[database_name]
        for database_name in conf['database']
        ]
    model.Subscriber.db = connection[conf['subscribers.database']]
    model.Subscriber.collection_name = conf['subscribers.collection']

    # Initialize plugins.
    if conf['plugins_conf_file'] is not None:
        plugins_conf = SafeConfigParser(dict(here = os.path.dirname(conf['plugins_conf_file'])))
        plugins_conf.read(conf['plugins_conf_file'])
        conf['i18n_dir_by_plugin_name'] = {}
        for section in plugins_conf.sections():
            plugin_accessor = plugins_conf.get(section, 'use')
            plugin_constructor = pkg_resources.EntryPoint.parse('constructor = {0}'.format(plugin_accessor)).load(
                require = False)
            plugin_constructor(plugins_conf, section)
            plugin_package_name = plugins_conf.get(section, 'package_name')
            if plugin_package_name is not None:
                plugin_i18n_dir = plugins_conf.get(section, 'i18n_dir')
                if plugin_i18n_dir is not None:
                    conf['i18n_dir_by_plugin_name'][plugin_package_name] = plugin_i18n_dir

    # Initialize ramdb database from MongoDB.
    ramdb.load()

    # Create the Mako TemplateLookup, with the default auto-escaping.
    templates_dirs = []
    if conf['custom_templates_dir']:
        templates_dirs.append(conf['custom_templates_dir'])
    templates_dirs.append(os.path.join(app_dir, 'templates'))
    templates.lookup = mako.lookup.TemplateLookup(
        cache_enabled = False if conf['debug'] else True,
        default_filters = ['h'],
        directories = templates_dirs,
#        error_handler = handle_mako_error,
        input_encoding = 'utf-8',
        module_directory = os.path.join(conf['cache_dir'], 'templates'),
#        strict_undefined = True,
        )
예제 #2
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = openfisca_web_ui.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'alert_on_js_error': conv.pipe(conv.guess_bool, conv.not_none),
            'api.base_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.calculate_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.entities_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.fields_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.reforms_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.repair_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'api.simulate_url': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_query = True, full = True),
                conv.not_none,
                ),
            'app_conf': conv.set_value(app_conf, handle_none_value = True),
            'app_dir': conv.set_value(app_dir, handle_none_value = True),
            'app_name': conv.pipe(conv.cleanup_line, conv.default('OpenFisca')),
            'auth.dummy_admin_email': conv.pipe(conv.cleanup_line, conv.default(u'*****@*****.**')),
            'auth.dummy_user_email': conv.pipe(conv.cleanup_line, conv.default(u'*****@*****.**')),
            'base_reforms': conv.pipe(
                conv.cleanup_line,
                conv.function(lambda value: value.split(',')),
                conv.uniform_sequence(conv.cleanup_line),
                conv.empty_to_none,
                ),
            'cache_dir': conv.default(os.path.join(os.path.dirname(app_dir), 'cache')),
            'cookie': conv.default('openfisca-web-ui'),
            'country': conv.cleanup_line,
            'customs_dir': conv.default(None),
            'database.host': conv.default('localhost'),
            'database.name': conv.default('openfisca_web_ui'),
            'database.port': conv.pipe(conv.input_to_int, conv.default(27017)),
            'debug': conv.pipe(conv.guess_bool, conv.not_none),
            'enabled.auth': conv.pipe(conv.guess_bool, conv.not_none),
            'enabled.charts.locating': conv.pipe(conv.guess_bool, conv.not_none),
            'enabled.disclaimer': conv.pipe(conv.guess_bool, conv.not_none),
            'enabled.livereload': conv.pipe(conv.guess_bool, conv.not_none),
            'global_conf': conv.set_value(global_conf, handle_none_value = True),
            # 'host_urls': conv.pipe(
            #    conv.function(lambda host_urls: host_urls.split()),
            #    conv.uniform_sequence(
            #        conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
            #            full = True, schemes = (u'ws', u'wss')),
            #        constructor = lambda host_urls: sorted(set(host_urls)),
            #        ),
            #    ),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'languages': conv.pipe(
                conv.cleanup_line,
                conv.function(lambda value: value.split(',')),
                conv.uniform_sequence(conv.input_to_slug),
                conv.not_none,
                ),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'minified_js_bundle': conv.pipe(conv.guess_bool, conv.not_none),
            'package_name': conv.default('openfisca-web-ui'),
            'piwik.site_id': conv.input_to_int,
            'piwik.url': conv.make_input_to_url(full = True, error_if_fragment = True, error_if_path = True,
                error_if_query = True),
            # Whether this application serves its own static files.
            'static_files': conv.pipe(conv.guess_bool, conv.not_none),
            'static_files_dir': conv.default(os.path.join(app_dir, 'static')),
            'ui.default_year': conv.pipe(conv.input_to_int, conv.default(2013)),
            'ui.max_year': conv.pipe(conv.input_to_int, conv.default(2099)),
            'ui.min_year': conv.pipe(conv.input_to_int, conv.default(1870)),
            'urls.legislation_explorer': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
                    full = True),
                conv.not_none,
                ),
            'urls.other_ui_by_country': conv.pipe(
                conv.cleanup_line,
                conv.function(lambda value: value.split('\n')),
                conv.uniform_sequence(
                    conv.pipe(
                        conv.function(lambda value: value.split('=')),
                        conv.uniform_sequence(conv.cleanup_line),
                        )
                    ),
                conv.function(lambda value: dict(value)),
                conv.uniform_mapping(
                    conv.noop,
                    conv.pipe(
                        conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
                            full = True),
                        conv.not_none,
                        )
                    ),
                ),
            'urls.persona': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
                    full = True),
                conv.default(u'https://login.persona.org/'),
                ),
            'urls.www': conv.pipe(
                conv.make_input_to_url(error_if_fragment = True, error_if_path = True, error_if_query = True,
                    full = True),
                conv.not_none,
                ),
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not conf['debug'] and conf.get('email_to'):
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca-Web-UI Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Load MongoDB database.
    global db
    db = pymongo.Connection(conf['database.host'], conf['database.port'])[conf['database.name']]
    model.init(db)

    # Create the Mako TemplateLookup, with the default auto-escaping.
    templates.dirs = [os.path.join(app_dir, 'templates')]
예제 #3
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_str_to_list,  # Another validation is done below.
            'extensions': conv.ini_str_to_list,
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')
        errorware['show_exceptions_in_wsgi_errors'] = conf.get('show_exceptions_in_wsgi_errors', True)

    # Initialize tax-benefit system.
    country_package = importlib.import_module(conf['country_package'])
    tax_benefit_system = country_package.CountryTaxBenefitSystem()

    extensions = conf['extensions']
    if extensions is not None:
        for extension in extensions:
            tax_benefit_system.load_extension(extension)

    class Scenario(tax_benefit_system.Scenario):
        instance_and_error_couple_cache = {} if conf['debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                key = (unicode(ctx.lang), unicode(value), repair, tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    tax_benefit_system.Scenario = Scenario

    model.tax_benefit_system = tax_benefit_system

    log.debug(u'Pre-fill tax and benefit system cache.')
    tax_benefit_system.prefill_cache()

    log.debug(u'Initialize reforms.')
    reforms = conv.check(
        conv.uniform_sequence(
            conv.module_and_function_str_to_function,
            )
        )(conf['reforms'])
    model.reforms = {}
    model.reformed_tbs = {}
    if reforms is not None:
        for reform in reforms:
            reformed_tbs = reform(tax_benefit_system)
            key = reformed_tbs.key
            full_key = reformed_tbs.full_key
            model.reforms[key] = reform
            model.reformed_tbs[full_key] = reformed_tbs

    log.debug(u'Cache default decomposition.')
    if tax_benefit_system.decomposition_file_path is not None:
        # Ignore the returned value, because we just want to pre-compute the cache.
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    log.debug(u'Initialize lib2to3-based input variables extractor.')
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    global country_package_dir_path
    # Using pkg_resources.get_distribution(conf["country_package"]).location
    # returns a wrong path in virtualenvs (<venv>/lib versus <venv>/local/lib).
    country_package_dir_path = country_package.__path__[0]

    global api_package_version
    api_package_version = pkg_resources.get_distribution('openfisca_web_api').version

    global country_package_version
    country_package_version = pkg_resources.get_distribution(conf["country_package"]).version

    log.debug(u'Cache legislation JSON with references to original XML.')
    legislation_json = tax_benefit_system.get_legislation(with_source_file_infos=True)
    parameters_json = []
    walk_legislation_json(
        legislation_json,
        descriptions = [],
        parameters_json = parameters_json,
        path_fragments = [],
        )
    model.parameters_json_cache = parameters_json

    if not conf['debug']:
        # Do this after tax_benefit_system.get_legislation(with_source_file_infos=True).
        log.debug(u'Compute and cache compact legislation for each first day of month since at least 2 legal years.')
        today = periods.instant(datetime.date.today())
        first_day_of_year = today.offset('first-of', 'year')
        instant = first_day_of_year.offset(-2, 'year')
        two_years_later = first_day_of_year.offset(2, 'year')
        while instant < two_years_later:
            tax_benefit_system.get_compact_legislation(instant)
            instant = instant.offset(1, 'month')

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
예제 #4
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_str_to_list,  # Another validation is done below.
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_cache = {} if conf['debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                key = (unicode(ctx.lang), unicode(value), repair, tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass
    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Initialize reforms
    build_reform_functions = conv.check(
        conv.uniform_sequence(
            conv.module_and_function_str_to_function,
            )
        )(conf['reforms'])
    if build_reform_functions is not None:
        api_reforms = [
            build_reform(tax_benefit_system)
            for build_reform in build_reform_functions
            ]
        api_reforms = conv.check(
            conv.uniform_sequence(conv.test_isinstance(reforms.AbstractReform))
            )(api_reforms)
        model.build_reform_function_by_key = {
            reform.key: build_reform
            for build_reform, reform in zip(build_reform_functions, api_reforms)
            }
        model.reform_by_full_key = {
            reform.full_key: reform
            for reform in api_reforms
            }

    # Cache default decomposition.
    if hasattr(tax_benefit_system, 'DEFAULT_DECOMP_FILE'):
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    global country_package_dir_path
    country_package_dir_path = pkg_resources.get_distribution(conf['country_package']).location

    # Store Git last commit SHA
    global git_head_sha
    git_head_sha = get_git_head_sha()
    global country_package_git_head_sha
    country_package_git_head_sha = get_git_head_sha(cwd = country_package.__path__[0])

    # Cache legislation JSON with references to original XML
    legislation_json_with_references_to_xml = tax_benefit_system.get_legislation_json(with_source_file_infos = True)
    parameters_json = []
    walk_legislation_json(
        legislation_json_with_references_to_xml,
        descriptions = [],
        parameters_json = parameters_json,
        path_fragments = [],
        )
    model.parameters_json_cache = parameters_json

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
예제 #5
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = etalagepassim.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(
        conv.check(
            conv.struct(
                {
                    u"app_conf": conv.set_value(app_conf),
                    u"app_dir": conv.set_value(app_dir),
                    u"autocompleter_territories_kinds": conv.pipe(
                        conv.function(lambda kinds: kinds.split()),
                        conv.uniform_sequence(
                            conv.test_in(model.Territory.public_kinds), constructor=lambda kinds: sorted(set(kinds))
                        ),
                        conv.default(
                            [
                                # u'AbstractCommuneOfFrance',
                                u"ArrondissementOfCommuneOfFrance",
                                u"ArrondissementOfFrance",
                                u"AssociatedCommuneOfFrance",
                                # u'CantonalFractionOfCommuneOfFrance',
                                u"CantonOfFrance",
                                u"CommuneOfFrance",
                                # u'Country',
                                u"DepartmentOfFrance",
                                u"IntercommunalityOfFrance",
                                # u'InternationalOrganization',
                                u"MetropoleOfCountry",
                                u"Mountain",
                                u"OverseasCollectivityOfFrance",
                                u"PaysOfFrance",
                                u"RegionalNatureParkOfFrance",
                                u"RegionOfFrance",
                                # u'Special',
                                u"UrbanAreaOfFrance",
                                u"UrbanTransportsPerimeterOfFrance",
                            ]
                        ),
                    ),
                    u"brand_name": conv.default(u"Comarquage.fr"),
                    u"brand_url": conv.default(u"http://www.comarquage.fr/"),
                    u"cache_dir": conv.default(os.path.join(os.path.dirname(app_dir), "cache")),
                    u"categories_collection": conv.default("categories"),
                    u"cdn_url": conv.default("http://localhost:7000"),
                    u"custom_static_files_dir": conv.default(None),
                    u"custom_templates_dir": conv.default(None),
                    u"data_updates_collection": conv.default("data_updates"),
                    u"data_email": conv.pipe(
                        conv.function(lambda lines: lines.split(u",")), conv.uniform_sequence(conv.input_to_email)
                    ),
                    u"database": conv.pipe(  # A space-separated list of databases
                        conv.function(lambda databases: databases.split()),
                        conv.uniform_sequence(
                            conv.noop,
                            # Remove empty items and remove sequence when it is empty.
                        ),
                        conv.default(["souk"]),
                    ),
                    u"debug": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"default_tab": conv.pipe(
                        conv.cleanup_line, conv.test_in(["accueil", "carte", "liste"]), conv.default("carte")
                    ),
                    u"gadget_default_tab": conv.pipe(
                        conv.cleanup_line, conv.test_in(["accueil", "carte", "liste"]), conv.default(None)
                    ),
                    u"gadget-integration.js": conv.default(
                        urlparse.urljoin("http://localhost:7002/", "integration.js")
                    ),
                    u"global_conf": conv.set_value(global_conf),
                    u"handle_competence_territories": conv.pipe(conv.guess_bool, conv.default(True)),
                    u"hide_directory": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_export": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_gadget": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_home": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_list": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_map": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_minisite": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_category": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_checkboxes": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_legend": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_territory": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"hide_term": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"i18n_dir": conv.default(os.path.join(app_dir, "i18n")),
                    u"i18n_dir_by_plugin_name": conv.set_value(None),  # set by plugins below
                    u"ignored_fields": conv.pipe(
                        conv.function(lambda lines: lines.split(u"\n")),
                        conv.uniform_sequence(
                            conv.pipe(
                                conv.function(lambda line: line.split(None, 1)),
                                conv.uniform_sequence(conv.input_to_slug),
                                conv.function(lambda seq: dict(zip(["id", "name"], seq))),
                            )
                        ),
                        conv.id_name_dict_list_to_ignored_fields,
                    ),
                    u"index.date.field": conv.default(None),
                    u"log_level": conv.pipe(
                        conv.default("WARNING"), conv.function(lambda log_level: getattr(logging, log_level.upper()))
                    ),
                    u"markers.piwik.id": conv.pipe(conv.input_to_int, conv.default(None)),
                    u"markers.piwik.host": conv.default("http://localhost/piwik"),
                    u"markers.piwik.ssl_host": conv.default("https://localhost/piwik"),
                    u"organism_types_collection": conv.default("organism_types"),
                    u"package_name": conv.default("etalagepassim"),
                    u"package_slug": conv.default("etalage-passim"),
                    u"pager.page_max_size": conv.pipe(conv.input_to_int, conv.default(20)),
                    u"petitpois_url": conv.pipe(  # A space-separated list of URLs
                        conv.function(lambda urls: urls.split()),
                        conv.uniform_sequence(
                            conv.make_input_to_url(
                                error_if_fragment=True, error_if_path=True, error_if_query=True, full=True
                            ),
                            # Remove empty items and remove sequence when it is empty.
                        ),
                        conv.default(["http://localhost:5000/"]),
                    ),
                    u"plugins_conf_file": conv.default(None),
                    u"realm": conv.default(u"Passim"),
                    u"recaptcha.private_key": conv.pipe(conv.cleanup_line, conv.not_none),
                    u"recaptcha.public_key": conv.pipe(conv.cleanup_line, conv.not_none),
                    u"require_subscription": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"reset_on_poi_update": conv.pipe(conv.guess_bool, conv.default(False)),
                    # Whether this application serves its own static files.
                    u"static_files": conv.pipe(conv.guess_bool, conv.default(True)),
                    u"static_files_dir": conv.default(os.path.join(app_dir, "static")),
                    u"subscribers.require_subscription": conv.pipe(conv.guess_bool, conv.default(False)),
                    u"subscribers.database": conv.default("souk"),
                    u"subscribers.collection": conv.default("subscribers"),
                    u"subscribers.gadget_valid_domains": conv.pipe(
                        conv.function(lambda hostnames: hostnames.split()),
                        conv.default(["localhost", "127.0.0.1", "comarquage.fr", "donnees-libres.fr"]),
                        conv.function(lambda hostnames: tuple(hostnames)),
                    ),
                    u"territories_database": conv.noop,  # Done below.
                    u"territories_collection": conv.default("territories"),
                    u"territories_kinds": conv.pipe(
                        conv.function(lambda kinds: kinds.split()),
                        conv.uniform_sequence(
                            conv.test_in(model.Territory.public_kinds), constructor=lambda kinds: sorted(set(kinds))
                        ),
                        conv.default(
                            [
                                # u'AbstractCommuneOfFrance',
                                u"ArrondissementOfCommuneOfFrance",
                                u"ArrondissementOfFrance",
                                u"AssociatedCommuneOfFrance",
                                # u'CantonalFractionOfCommuneOfFrance',
                                u"CantonOfFrance",
                                u"CommuneOfFrance",
                                # u'Country',
                                u"DepartmentOfFrance",
                                u"IntercommunalityOfFrance",
                                # u'InternationalOrganization',
                                u"MetropoleOfCountry",
                                u"Mountain",
                                u"OverseasCollectivityOfFrance",
                                u"PaysOfFrance",
                                u"RegionalNatureParkOfFrance",
                                u"RegionOfFrance",
                                # u'Special',
                                u"UrbanAreaOfFrance",
                                u"UrbanTransportsPerimeterOfFrance",
                            ]
                        ),
                    ),
                    u"theme_field": conv.pipe(
                        conv.function(lambda line: line.split(None, 1)),
                        conv.uniform_sequence(conv.input_to_slug),
                        conv.function(lambda seq: dict(zip(["id", "name"], seq))),
                        conv.default(dict(id="organism-type")),
                    ),
                    u"tile_layers": conv.pipe(
                        conv.function(eval),
                        conv.function(strings.deep_decode),
                        conv.test_isinstance(list),
                        conv.uniform_sequence(
                            conv.pipe(
                                conv.test_isinstance(dict),
                                conv.struct(
                                    dict(
                                        attribution=conv.pipe(conv.test_isinstance(basestring), conv.not_none),
                                        name=conv.pipe(conv.test_isinstance(basestring), conv.not_none),
                                        subdomains=conv.test_isinstance(basestring),
                                        url=conv.pipe(
                                            conv.test_isinstance(basestring), conv.make_input_to_url(), conv.not_none
                                        ),
                                    )
                                ),
                            )
                        ),
                        conv.not_none,
                    ),
                    u"transport_types_order": conv.pipe(
                        conv.function(lambda transport_type_slugs: transport_type_slugs.split()),
                        conv.default(
                            [
                                u"transport-collectif-urbain",
                                u"transport-collectif-departemental",
                                u"transport-collectif-regional",
                                u"transport-longue-distance",
                                u"transport-a-la-demande",
                                u"transport-personnes-a-mobilite-reduite",
                                u"transport-scolaire",
                                u"velo-libre-service",
                                u"autopartage",
                                u"covoiturage",
                                u"taxi",
                                u"velo-taxi",
                                u"reseau-routier",
                                u"stationnement",
                                u"port",
                                u"aeroport",
                                u"circuit-touristique",
                                u"reseau-fluvial",
                            ]
                        ),
                    ),
                },
                default="drop",
                keep_none_values=True,
            )
        )(conf)
    )

    # CDN configuration
    conf.update(
        conv.check(
            conv.struct(
                {
                    u"bootstrap.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/bootstrap/2.3.1/css/bootstrap.min.css")
                    ),
                    u"bootstrap-gadget.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/bootstrap/2.3.1/css/bootstrap.min.css")
                    ),
                    u"bootstrap.js": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/bootstrap/2.3.1/js/bootstrap.min.js")
                    ),
                    u"bootstrap-responsive.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/bootstrap/2.3.1/css/bootstrap-responsive.min.css")
                    ),
                    u"easyxdm.js": conv.default(urlparse.urljoin(conf["cdn_url"], "/easyxdm/latest/easyXDM.min.js")),
                    u"easyxdm.swf": conv.default(urlparse.urljoin(conf["cdn_url"], "/easyxdm/latest/easyxdm.swf")),
                    u"images.markers.url": conv.default(urlparse.urljoin(conf["cdn_url"], "/images/markers/")),
                    u"images.misc.url": conv.default(urlparse.urljoin(conf["cdn_url"], "/images/misc/")),
                    u"jquery.js": conv.default(urlparse.urljoin(conf["cdn_url"], "/jquery/jquery-1.9.1.min.js")),
                    u"json2.js": conv.default(urlparse.urljoin(conf["cdn_url"], "/easyxdm/latest/json2.js")),
                    u"leaflet.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/leaflet/leaflet-0.5.1/leaflet.css")
                    ),
                    u"leaflet.ie.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/leaflet/leaflet-0.5.1/leaflet.ie.css")
                    ),
                    u"leaflet.js": conv.default(urlparse.urljoin(conf["cdn_url"], "/leaflet/leaflet-0.5.1/leaflet.js")),
                    u"pie.js": conv.default(urlparse.urljoin(conf["cdn_url"], "/css3pie/1.0beta5/PIE.js")),
                    u"prettify.js": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/google-code-prettify/187/prettify.js")
                    ),
                    u"territories_database": conv.pipe(conv.default(conf["database"][0])),
                    u"typeahead.css": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/twitter-typeahead/0.9.3/typeahead.css")
                    ),
                    u"typeahead.js": conv.default(
                        urlparse.urljoin(conf["cdn_url"], "/twitter-typeahead/0.9.3/typeahead.js")
                    ),
                },
                default=conv.noop,
            )
        )(conf)
    )

    if len(conf["database"]) != len(conf["petitpois_url"]):
        raise Exception(
            "Number of databases and number of Petitpois URLs don't match : {0} , {1}".format(
                conf["database"], conf["petitpois_url"]
            )
        )

    # Configure logging.
    logging.basicConfig(level=conf["log_level"], stream=sys.stdout)

    errorware = conf.setdefault(u"errorware", {})
    errorware["debug"] = conf["debug"]
    if not errorware["debug"]:
        errorware["error_email"] = conf["email_to"]
        errorware["error_log"] = conf.get("error_log", None)
        errorware["error_message"] = conf.get("error_message", "An internal server error occurred")
        errorware["error_subject_prefix"] = conf.get("error_subject_prefix", "Passim Error: ")
        errorware["from_address"] = conf["from_address"]
        errorware["smtp_server"] = conf.get("smtp_server", "localhost")

    # Connect to MongoDB database.
    connection = pymongo.Connection()
    model.dbs = [connection[database_name] for database_name in conf["database"]]
    model.Subscriber.db = connection[conf["subscribers.database"]]
    model.Subscriber.collection_name = conf["subscribers.collection"]

    # Initialize plugins.
    if conf["plugins_conf_file"] is not None:
        plugins_conf = SafeConfigParser(dict(here=os.path.dirname(conf["plugins_conf_file"])))
        plugins_conf.read(conf["plugins_conf_file"])
        conf["i18n_dir_by_plugin_name"] = {}
        for section in plugins_conf.sections():
            plugin_accessor = plugins_conf.get(section, "use")
            plugin_constructor = pkg_resources.EntryPoint.parse("constructor = {0}".format(plugin_accessor)).load(
                require=False
            )
            plugin_constructor(plugins_conf, section)
            plugin_package_name = plugins_conf.get(section, "package_name")
            if plugin_package_name is not None:
                plugin_i18n_dir = plugins_conf.get(section, "i18n_dir")
                if plugin_i18n_dir is not None:
                    conf["i18n_dir_by_plugin_name"][plugin_package_name] = plugin_i18n_dir

    # Initialize ramdb database from MongoDB.
    ramdb.load()

    # Create the Mako TemplateLookup, with the default auto-escaping.
    templates_dirs = []
    if conf["custom_templates_dir"]:
        templates_dirs.append(conf["custom_templates_dir"])
    templates_dirs.append(os.path.join(app_dir, "templates"))
    templates.lookup = mako.lookup.TemplateLookup(
        cache_enabled=False if conf["debug"] else True,
        default_filters=["h"],
        directories=templates_dirs,
        #        error_handler = handle_mako_error,
        input_encoding="utf-8",
        module_directory=os.path.join(conf["cache_dir"], "templates"),
        #        strict_undefined = True,
    )
예제 #6
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = openfisca_web_api.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(conv.check(conv.struct(
        {
            'app_conf': conv.set_value(app_conf),
            'app_dir': conv.set_value(app_dir),
            'country_package': conv.pipe(
                conv.make_input_to_slug(separator = u'_'),
                conv.test_in((
                    u'openfisca_france',
                    u'openfisca_tunisia',
                    u'openfisca_tunisia_pension',
                    )),
                conv.not_none,
                ),
            'debug': conv.pipe(conv.guess_bool, conv.default(False)),
            'global_conf': conv.set_value(global_conf),
            'i18n_dir': conv.default(os.path.join(app_dir, 'i18n')),
            'load_alert': conv.pipe(conv.guess_bool, conv.default(False)),
            'log_level': conv.pipe(
                conv.default('WARNING'),
                conv.function(lambda log_level: getattr(logging, log_level.upper())),
                ),
            'package_name': conv.default('openfisca-web-api'),
            'realm': conv.default(u'OpenFisca Web API'),
            'reforms': conv.ini_items_list_to_ordered_dict,  # Another validation is done below.
            },
        default = 'drop',
        ))(conf))

    # Configure logging.
    logging.basicConfig(level = conf['log_level'], stream = sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get('error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get('error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_by_json_str_cache = weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def cached_or_new(cls):
            return conv.check(cls.json_to_cached_or_new_instance)(None)

        @classmethod
        def make_json_to_cached_or_new_instance(cls, repair, tax_benefit_system):
            def json_to_cached_or_new_instance(value, state = None):
                json_str = json.dumps(value, separators = (',', ':')) if value is not None else None
                instance_and_error_couple = cls.instance_and_error_couple_by_json_str_cache.get(json_str)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(repair, tax_benefit_system)(
                        value, state = state or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_by_json_str_cache[json_str] = ValueAndError(
                        instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass
    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Cache default decomposition.
    model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(tax_benefit_system)

    # Store Git last commit SHA
    global last_commit_sha
    last_commit_sha = get_git_last_commit_sha()

    # Load reform modules and store build_reform functions.
    model.build_reform_function_by_key = build_reform_function_by_key = conv.check(
        conv.uniform_mapping(
            conv.noop,
            conv.module_function_str_to_function,
            )(conf['reforms'])
        )
    # Check that each reform builds and cache instances. Must not be used with composed reforms.
    model.reform_by_key = conv.check(
        conv.uniform_mapping(
            conv.noop,
            conv.pipe(
                conv.function(lambda build_reform: build_reform(tax_benefit_system)),
                conv.test_isinstance(reforms.AbstractReform),
                ),
            )(build_reform_function_by_key)
        )
예제 #7
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(
        conv.check(
            conv.struct(
                {
                    'app_conf':
                    conv.set_value(app_conf),
                    'app_dir':
                    conv.set_value(app_dir),
                    'country_package':
                    conv.pipe(
                        conv.make_input_to_slug(separator=u'_'),
                        conv.test_in((
                            u'openfisca_france',
                            u'openfisca_tunisia',
                            u'openfisca_tunisia_pension',
                        )),
                        conv.not_none,
                    ),
                    'debug':
                    conv.pipe(conv.guess_bool, conv.default(False)),
                    'global_conf':
                    conv.set_value(global_conf),
                    'i18n_dir':
                    conv.default(os.path.join(app_dir, 'i18n')),
                    'load_alert':
                    conv.pipe(conv.guess_bool, conv.default(False)),
                    'log_level':
                    conv.pipe(
                        conv.default('WARNING'),
                        conv.function(lambda log_level: getattr(
                            logging, log_level.upper())),
                    ),
                    'package_name':
                    conv.default('openfisca-web-api'),
                    'realm':
                    conv.default(u'OpenFisca Web API'),
                    'reforms':
                    conv.ini_str_to_list,  # Another validation is done below.
                },
                default='drop',
            ))(conf))

    # Configure logging.
    logging.basicConfig(level=conf['log_level'], stream=sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get(
            'error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get(
            'error_subject_prefix', 'OpenFisca Web API Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Initialize tax-benefit system.

    country_package = importlib.import_module(conf['country_package'])
    CountryTaxBenefitSystem = country_package.init_country()

    class Scenario(CountryTaxBenefitSystem.Scenario):
        instance_and_error_couple_cache = {} if conf[
            'debug'] else weakref.WeakValueDictionary()  # class attribute

        @classmethod
        def make_json_to_cached_or_new_instance(cls, ctx, repair,
                                                tax_benefit_system):
            def json_to_cached_or_new_instance(value, state=None):
                key = (unicode(ctx.lang), unicode(value), repair,
                       tax_benefit_system)
                instance_and_error_couple = cls.instance_and_error_couple_cache.get(
                    key)
                if instance_and_error_couple is None:
                    instance_and_error_couple = cls.make_json_to_instance(
                        repair, tax_benefit_system)(value,
                                                    state=state
                                                    or conv.default_state)
                    # Note: Call to ValueAndError() is needed below, otherwise it raises TypeError: cannot create
                    # weak reference to 'tuple' object.
                    cls.instance_and_error_couple_cache[key] = ValueAndError(
                        instance_and_error_couple)
                return instance_and_error_couple

            return json_to_cached_or_new_instance

    class TaxBenefitSystem(CountryTaxBenefitSystem):
        pass

    TaxBenefitSystem.Scenario = Scenario

    model.TaxBenefitSystem = TaxBenefitSystem
    model.tax_benefit_system = tax_benefit_system = TaxBenefitSystem()

    tax_benefit_system.prefill_cache()

    # Initialize reforms
    build_reform_functions = conv.check(
        conv.uniform_sequence(conv.module_and_function_str_to_function, ))(
            conf['reforms'])
    if build_reform_functions is not None:
        api_reforms = [
            build_reform(tax_benefit_system)
            for build_reform in build_reform_functions
        ]
        api_reforms = conv.check(
            conv.uniform_sequence(conv.test_isinstance(
                reforms.AbstractReform)))(api_reforms)
        model.build_reform_function_by_key = {
            reform.key: build_reform
            for build_reform, reform in zip(build_reform_functions,
                                            api_reforms)
        }
        model.reform_by_full_key = {
            reform.full_key: reform
            for reform in api_reforms
        }

    # Cache default decomposition.
    if hasattr(tax_benefit_system, 'DEFAULT_DECOMP_FILE'):
        model.get_cached_or_new_decomposition_json(tax_benefit_system)

    # Compute and cache compact legislation for each first day of month since at least 2 legal years.
    today = periods.instant(datetime.date.today())
    first_day_of_year = today.offset('first-of', 'year')
    instant = first_day_of_year.offset(-2, 'year')
    two_years_later = first_day_of_year.offset(2, 'year')
    while instant < two_years_later:
        tax_benefit_system.get_compact_legislation(instant)
        instant = instant.offset(1, 'month')

    # Initialize lib2to3-based input variables extractor.
    if input_variables_extractors is not None:
        model.input_variables_extractor = input_variables_extractors.setup(
            tax_benefit_system)

    global country_package_dir_path
    country_package_dir_path = pkg_resources.get_distribution(
        conf['country_package']).location

    # Store Git last commit SHA
    global git_head_sha
    git_head_sha = get_git_head_sha()
    global country_package_git_head_sha
    country_package_git_head_sha = get_git_head_sha(
        cwd=country_package.__path__[0])

    # Cache legislation JSON with references to original XML
    legislation_json_with_references_to_xml = tax_benefit_system.get_legislation_json(
        with_source_file_infos=True)
    parameters_json = []
    walk_legislation_json(
        legislation_json_with_references_to_xml,
        descriptions=[],
        parameters_json=parameters_json,
        path_fragments=[],
    )
    model.parameters_json_cache = parameters_json

    # Initialize multiprocessing and load_alert
    if conf['load_alert']:
        global cpu_count
        cpu_count = multiprocessing.cpu_count()
예제 #8
0
def load_environment(global_conf, app_conf):
    """Configure the application environment."""
    conf = openfisca_web_site.conf  # Empty dictionary
    conf.update(strings.deep_decode(global_conf))
    conf.update(strings.deep_decode(app_conf))
    conf.update(
        conv.check(
            conv.struct(
                {
                    'app_conf':
                    conv.set_value(app_conf, handle_none_value=True),
                    'app_dir':
                    conv.set_value(app_dir, handle_none_value=True),
                    'cache_dir':
                    conv.default(
                        os.path.join(os.path.dirname(app_dir), 'cache')),
                    'cookie':
                    conv.default('openfisca_web_site'),
                    'custom_templates_dir':
                    conv.pipe(
                        conv.empty_to_none,
                        conv.test(os.path.exists),
                    ),
                    'customs_dir':
                    conv.default(None),
                    'debug':
                    conv.pipe(conv.guess_bool, conv.default(False)),
                    'global_conf':
                    conv.set_value(global_conf, handle_none_value=True),
                    'google_analytics.key':
                    conv.empty_to_none,
                    'host_urls':
                    conv.pipe(
                        conv.function(lambda host_urls: host_urls.split()),
                        conv.uniform_sequence(
                            conv.make_input_to_url(error_if_fragment=True,
                                                   error_if_path=True,
                                                   error_if_query=True,
                                                   full=True,
                                                   schemes=(u'ws', u'wss')),
                            constructor=lambda host_urls: sorted(set(host_urls)
                                                                 ),
                        ),
                    ),
                    'i18n_dir':
                    conv.default(os.path.join(app_dir, 'i18n')),
                    'languages':
                    conv.pipe(
                        conv.cleanup_line,
                        conv.function(lambda value: value.split(',')),
                        conv.uniform_sequence(conv.input_to_slug),
                    ),
                    'log_level':
                    conv.pipe(
                        conv.default('WARNING'),
                        conv.function(lambda log_level: getattr(
                            logging, log_level.upper())),
                    ),
                    'package_name':
                    conv.default('openfisca-web-site'),
                    'piwik.key':
                    conv.input_to_int,
                    'piwik.url':
                    conv.make_input_to_url(error_if_fragment=True,
                                           error_if_path=True,
                                           error_if_query=True,
                                           full=True),
                    'realm':
                    conv.default(u'OpenFisca-Web-Site'),
                    # Whether this application serves its own static files.
                    'static_files':
                    conv.pipe(conv.guess_bool, conv.default(True)),
                    'static_files_dir':
                    conv.default(os.path.join(app_dir, 'static')),
                    'twitter.access_token_key':
                    conv.cleanup_line,
                    'twitter.access_token_secret':
                    conv.cleanup_line,
                    'twitter.consumer_key':
                    conv.cleanup_line,
                    'twitter.consumer_secret':
                    conv.cleanup_line,
                    'urls.api':
                    conv.pipe(
                        conv.make_input_to_url(error_if_fragment=True,
                                               error_if_path=True,
                                               error_if_query=True,
                                               full=True),
                        conv.not_none,
                    ),
                    'urls.legislation':
                    conv.pipe(
                        conv.make_input_to_url(error_if_fragment=True,
                                               error_if_path=True,
                                               error_if_query=True,
                                               full=True),
                        conv.not_none,
                    ),
                    'urls.other_www_by_country':
                    conv.pipe(
                        conv.cleanup_line,
                        conv.function(lambda value: value.split('\n')),
                        conv.uniform_sequence(
                            conv.pipe(
                                conv.function(lambda value: value.split('=')),
                                conv.uniform_sequence(conv.cleanup_line),
                            )),
                        conv.function(lambda value: dict(value)),
                        conv.uniform_mapping(
                            conv.noop,
                            conv.pipe(
                                conv.make_input_to_url(error_if_fragment=True,
                                                       error_if_path=True,
                                                       error_if_query=True,
                                                       full=True),
                                conv.not_none,
                            )),
                    ),
                    'urls.ui':
                    conv.pipe(
                        conv.make_input_to_url(error_if_fragment=True,
                                               error_if_path=True,
                                               error_if_query=True,
                                               full=True),
                        conv.not_none,
                    ),
                },
                default='drop',
            ))(conf))

    # Configure logging.
    logging.basicConfig(level=conf['log_level'], stream=sys.stderr)

    errorware = conf.setdefault('errorware', {})
    errorware['debug'] = conf['debug']
    if not errorware['debug']:
        errorware['error_email'] = conf['email_to']
        errorware['error_log'] = conf.get('error_log', None)
        errorware['error_message'] = conf.get(
            'error_message', 'An internal server error occurred')
        errorware['error_subject_prefix'] = conf.get(
            'error_subject_prefix', 'OpenFisca-Web-Site Error: ')
        errorware['from_address'] = conf['from_address']
        errorware['smtp_server'] = conf.get('smtp_server', 'localhost')

    # Create the Mako TemplateLookup, with the default auto-escaping.
    templates.dir = os.path.join(app_dir, 'templates')