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, )
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')]
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()
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()
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, )
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) )
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()
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')