Exemplo n.º 1
0
def config():
    Config._config = None
    Config.init(pyramid_oereb_test_yml, 'pyramid_oereb')
    return Config
Exemplo n.º 2
0
def includeme(config):
    """
    By including this in your pyramid web app you can easily provide a running OEREB Server

    Args:
        config (Configurator): The pyramid apps config object
    """

    global route_prefix, app_schema_name, srid

    # Set route prefix
    route_prefix = config.route_prefix

    # Get settings
    settings = config.get_settings()

    # Load configuration file
    cfg_file = settings.get('pyramid_oereb.cfg.file', None)
    cfg_c2ctemplate_file = settings.get('pyramid_oereb.cfg.c2ctemplate.file',
                                        None)
    cfg_section = settings.get('pyramid_oereb.cfg.section', None)
    Config.init(cfg_file or cfg_c2ctemplate_file, cfg_section,
                cfg_file is None)
    Config.update_settings(settings)

    real_estate_config = Config.get_real_estate_config()
    municipality_config = Config.get_municipality_config()
    exclusion_of_liability_config = Config.get_exclusion_of_liability_config()
    glossary_config = Config.get_glossary_config()
    logos = Config.get_logo_config()
    app_schema_name = Config.get('app_schema').get('name')
    srid = Config.get('srid')

    plr_cadastre_authority = Config.get_plr_cadastre_authority()

    real_estate_reader = RealEstateReader(
        real_estate_config.get('source').get('class'),
        **real_estate_config.get('source').get('params'))

    municipality_reader = MunicipalityReader(
        municipality_config.get('source').get('class'),
        **municipality_config.get('source').get('params'))

    exclusion_of_liability_reader = ExclusionOfLiabilityReader(
        exclusion_of_liability_config.get('source').get('class'),
        **exclusion_of_liability_config.get('source').get('params'))

    glossary_reader = GlossaryReader(
        glossary_config.get('source').get('class'),
        **glossary_config.get('source').get('params'))

    plr_sources = []
    for plr in Config.get('plrs'):
        plr_source_class = DottedNameResolver().maybe_resolve(
            plr.get('source').get('class'))
        plr_sources.append(plr_source_class(**plr))

    extract_reader = ExtractReader(plr_sources, plr_cadastre_authority, logos)

    settings.update({
        'pyramid_oereb':
        parse(cfg_file or cfg_c2ctemplate_file, cfg_section, cfg_file is None)
    })
    processor = Processor(
        real_estate_reader=real_estate_reader,
        municipality_reader=municipality_reader,
        exclusion_of_liability_reader=exclusion_of_liability_reader,
        glossary_reader=glossary_reader,
        plr_sources=plr_sources,
        extract_reader=extract_reader,
    )

    def pyramid_oereb_processor(request):
        return processor

    config.add_request_method(pyramid_oereb_processor, reify=True)

    config.add_renderer('pyramid_oereb_extract_json',
                        'pyramid_oereb.lib.renderer.extract.json_.Renderer')
    config.add_renderer('pyramid_oereb_extract_xml',
                        'pyramid_oereb.lib.renderer.extract.xml_.Renderer')
    config.add_renderer('pyramid_oereb_extract_print',
                        Config.get('print').get('renderer'))
    config.add_renderer('pyramid_oereb_versions_xml',
                        'pyramid_oereb.lib.renderer.versions.xml_.Renderer')
    config.add_renderer(
        'pyramid_oereb_capabilities_xml',
        'pyramid_oereb.lib.renderer.capabilities.xml_.Renderer')
    config.add_renderer('pyramid_oereb_getegrid_xml',
                        'pyramid_oereb.lib.renderer.getegrid.xml_.Renderer')

    config.include('pyramid_oereb.routes')
Exemplo n.º 3
0
def _create_theme_tables(configuration_yaml_path,
                         theme,
                         section='pyramid_oereb',
                         c2ctemplate_style=False,
                         tables_only=False):
    """
    Create all tables defined in the specified module.

    Args:
        configuration_yaml_path (str): Path to the configuration file.
        theme (str): Code of the theme to create the tables for.
        section (str): Section within the specified configuration file used for pyramid_oereb. Default is
            'pyramid_oereb'.
        c2ctemplate_style (bool): True if the yaml use a c2c template style (vars.[section]).
            Default is False.
        tables_only (bool): True to skip creation of schema. Default is False.
    """

    # Parse themes from configuration
    Config.init(configuration_yaml_path, section, c2ctemplate_style)
    themes = Config.get('plrs')
    if not isinstance(themes, list):
        raise ConfigurationError('No list of themes found.')

    # Find the specified theme
    found = False
    for t in themes:
        if t.get('code') == theme:

            # Check required configuration parameters
            params = t.get('source').get('params')
            if not isinstance(params, dict):
                raise ConfigurationError(
                    'Missing params property in source definition.')
            if not ('db_connection' in params and 'models' in params):
                raise ConfigurationError(
                    'Params has to contain "db_connection" and "models" properties.'
                )

            # Create sqlalchemy engine for configured connection and load module containing models
            engine = create_engine(params.get('db_connection'), echo=True)
            models = DottedNameResolver().resolve(params.get('models'))

            if not tables_only:
                # Iterate over contained classes to collect needed schemas
                classes = inspect.getmembers(models, inspect.isclass)
                schemas = []
                create_schema_sql = 'CREATE SCHEMA IF NOT EXISTS {schema};'
                for c in classes:
                    class_ = c[1]
                    if hasattr(class_, '__table__'
                               ) and class_.__table__.schema not in schemas:
                        schemas.append(class_.__table__.schema)

                # Try to create missing schemas
                connection = engine.connect()
                try:
                    for schema in schemas:
                        connection.execute(
                            create_schema_sql.format(schema=schema))
                finally:
                    connection.close()

            # Create tables
            models.Base.metadata.create_all(engine)
            found = True
            break

    if not found:
        raise ValueError(
            'Specified theme "{theme}" not found in configuration.'.format(
                theme=theme))
Exemplo n.º 4
0
def create_tables_from_standard_configuration(configuration_yaml_path,
                                              section='pyramid_oereb',
                                              tables_only=False,
                                              sql_file=None):
    """
    Creates all schemas which are defined in the passed yaml file: <section>.<plrs>.[<plr>.<code>]. The code
    must be camel case. It will be transformed to snake case and used as schema name.
    Creates all tables inside the created schemas. This only affects the sqlalchemy models which are defined
    with the Base class from pyramid_oereb.standard.models.

    Args:
        configuration_yaml_path (str): The absolute path to the yaml file which contains the plr
            definitions.
        section (str): The section in yaml file where the plrs are configured in. Default is 'pyramid_oereb'.
        tables_only (bool): True to skip creation of schema. Default is False.
        sql_file (file): the file to generate. Default is None (in the database).
    """
    if Config.get_config() is None:
        Config.init(configuration_yaml_path, section)

    main_schema_engine = create_engine(
        Config.get('app_schema').get('db_connection'), echo=True)
    if sql_file is None:
        if not tables_only:
            main_schema_connection = main_schema_engine.connect()
            try:
                main_schema_connection.execute(
                    'CREATE SCHEMA IF NOT EXISTS {name};'.format(
                        name=Config.get('app_schema').get('name')))
            finally:
                main_schema_connection.close()
    else:
        sql_file.write('CREATE SCHEMA {name};\n'.format(
            name=Config.get('app_schema').get('name')))

    main_base_class = DottedNameResolver().maybe_resolve(
        '{package}.Base'.format(
            package=Config.get('app_schema').get('models')))
    if sql_file is None:
        main_base_class.metadata.create_all(main_schema_engine)
    else:
        for table in main_base_class.metadata.sorted_tables:
            create_table = str(CreateTable(table).compile(main_schema_engine))\
                .replace('DATETIME', 'timestamp')
            sql_file.write('{};\n'.format(create_table))

    for schema in Config.get('plrs'):

        plr_schema_engine = create_engine(
            schema.get('source').get('params').get('db_connection'), echo=True)

        if sql_file is None:
            if schema.get('standard'):

                if not tables_only:
                    plr_schema_connection = plr_schema_engine.connect()
                    try:
                        plr_schema_connection.execute(
                            'CREATE SCHEMA IF NOT EXISTS {name};'.format(
                                name=convert_camel_case_to_snake_case(
                                    schema.get('code'))))
                    finally:
                        plr_schema_connection.close()

                plr_base = DottedNameResolver().maybe_resolve(
                    '{package}.Base'.format(package=schema.get('source').get(
                        'params').get('models')))
                plr_base.metadata.create_all(plr_schema_engine)

        else:
            plr_base = DottedNameResolver().maybe_resolve(
                '{package}.Base'.format(
                    package=schema.get('source').get('params').get('models')))
            sql_file.write('CREATE SCHEMA {name};\n'.format(
                name=convert_camel_case_to_snake_case(schema.get('code'))))
            for table in plr_base.metadata.sorted_tables:
                create_table = str(CreateTable(table).compile(plr_schema_engine))\
                    .replace('DATETIME', 'timestamp')
                sql_file.write('{};\n'.format(create_table))
Exemplo n.º 5
0
def test_configuration_file_not_found():
    Config._config = None
    with pytest.raises(IOError) as excinfo:
        Config.init('not_existing_config.yml', 'invalidsection')
    assert ', Current working directory is ' in str(excinfo.value)
Exemplo n.º 6
0
def test_get_plr_cadastre_authority():
    Config._config = None
    Config.init('./tests/resources/test_config.yml', 'pyramid_oereb')
    plr_cadastre_authority = Config.get_plr_cadastre_authority()
    assert isinstance(plr_cadastre_authority, OfficeRecord)
Exemplo n.º 7
0
def test_wrong_configuration_section():
    Config._config = None
    with pytest.raises(ConfigurationError):
        Config.init('./tests/resources/test_config.yml', 'invalidsection')
Exemplo n.º 8
0
def test_missing_configuration_section():
    Config._config = None
    with pytest.raises(ConfigurationError):
        Config.init('myconfig.yml', None)
Exemplo n.º 9
0
def test_missing_configuration_file():
    Config._config = None
    with pytest.raises(ConfigurationError):
        Config.init(None, None)
Exemplo n.º 10
0
def create_legend_entries_in_standard_db(config,
                                         topic_code,
                                         temp_creation_path='/tmp/pyconizer',
                                         language='de',
                                         section='pyramid_oereb',
                                         c2ctemplate_style=False,
                                         image_format='image/png',
                                         image_height=36,
                                         image_width=72,
                                         encoding=None,
                                         replace_host=None,
                                         replace_layer=None,
                                         string_keys=False,
                                         by_type_code=False):
    """
    Uses the pyconizer lib to create images out of the OEREB server configuration. It is creating symbols for
    a dedicated topic. This function will clean all previously created icons from database.

    Args:
        config (str): The path to the used OEREB server configuration YAML file.
        topic_code (str): The topic code for which the symbols should be created. It must be configured in
            the passed yml.
        temp_creation_path: The path where the images are created in.
        language: The language which is used to produce the WMS rules. This is a tricky part. You must
            provide the language your WMS is using.
        section: The section which the config can be found in the yml.
        c2ctemplate_style (bool): True if the yaml use a c2c template style (vars.[section]).
            Default is False.
        image_format: The image format. This is passed throug to the WMS request. You need to provide a
            format your WMS is supporting here.
        image_height: The height of the produced image.
        image_width: The width of the produced image.
        encoding (str or unicode): The encoding which is used to encode the XML. Standard is None. This means
            the encoding is taken from the XML content itself. Only use this parameter if your XML content
            has no encoding set.
        replace_host (str or None): The host which should be used instead of the one which is in the data.
            This is only recommended on deploy process when your WMS might be already available on a DEV
            instance but not on the production system which is linked in the data. Then you can create legend
            entries by obtaining them from this DEV instance.
        replace_layer (str or None): The layer which should be used instead of the one which is in the data.
            This is only recommended on deploy process when your WMS might be already available on a DEV
            instance serving a special legend layer but not on the production system which is linked in
            the data. Then you can create legend entries by obtaining them from this DEV instances special
            legend layer.
        string_keys (bool): Switch for setting primary key for legend entries whether to string or integer
        by_type_code (bool): If set the process will use the type_code instead of name for obtaining the
            legend icons. This needs a WMS layer to be configured with the type_code in its name property. It
            prevents the legend entry creation process to be broken for case sensitive class names in
            MAPSERVER. Because the "RULE" parameter of the GetLegendGraphics request on MAPSERVER seems to be
            case insensitive.
    """

    # config object parsed from oereb configuration yml
    Config.init(config, section, c2ctemplate_style)
    db_connection = None
    found = False

    # try to find the topic in config and create the orm models for further processing
    for topic in Config.get('plrs'):
        if topic.get('code') == topic_code:
            db_connection = topic.get('source').get('params').get(
                'db_connection')
            Plr = DottedNameResolver().maybe_resolve(
                '{models_path}.PublicLawRestriction'.format(
                    models_path=topic.get('source').get('params').get(
                        'models')))
            LegendEntry = DottedNameResolver().maybe_resolve(
                '{models_path}.LegendEntry'.format(models_path=topic.get(
                    'source').get('params').get('models')))
            found = True
            break
    if not found:
        # at this point it was not possible to find the topic in configuration
        log.error(
            'The topic with code "{0}" was not found in passed configuration!'.
            format(topic_code))
        return

    # we can start process now...
    engine = create_engine(db_connection, echo=True)
    Session = orm.scoped_session(orm.sessionmaker(bind=engine))
    session = Session()

    # clean up table first
    session.execute(
        '''TRUNCATE TABLE {schema}.{table} RESTART IDENTITY'''.format(
            schema=LegendEntry.__table__.schema,
            table=LegendEntry.__table__.name))

    # select all plrs from distinct on information, view_service_id and type_code
    unique_plrs = session.query(Plr).distinct(Plr.view_service_id,
                                              Plr.type_code).all()
    pyconizer_config = []
    type_code_list = []

    # first create the configuration for the pyconizer package
    for unique_plr in unique_plrs:
        if unique_plr.type_code not in type_code_list:
            type_code_list.append(unique_plr.type_code)
        url, params = parse_url(unique_plr.view_service.reference_wms)
        layer_existent = False
        service_url = urlunsplit((url.scheme, url.netloc, url.path, '', '')) \
            if replace_host is None else replace_host
        layer = params.get(
            'LAYERS')[0] if replace_layer is None else replace_layer
        for layer_config in pyconizer_config:
            if layer_config.get('url') == service_url and \
                    layer_config.get('layer') == layer:
                layer_existent = True
        if not layer_existent:
            pyconizer_config.append({
                'url': service_url,
                'layer': layer,
                'get_styles': {
                    'request': 'GetStyles',
                    'service': 'WMS',
                    'srs': params.get('SRS'),
                    'version': params.get('VERSION')
                },
                'get_legend': {
                    'image_format': image_format,
                    'request': 'GetLegendGraphic',
                    'service': 'WMS',
                    'version': params.get('VERSION'),
                    'width': image_width,
                    'height': image_height
                }
            })

    # create the icons with pyconizer package
    create_icons_from_scratch(pyconizer_config,
                              temp_creation_path,
                              images=True,
                              encoding=encoding)

    # reuse plr information to build legend entries and assign the symbol
    i = 1
    for unique_plr in unique_plrs:
        url, params = parse_url(unique_plr.view_service.reference_wms)
        layer = params.get(
            'LAYERS')[0] if replace_layer is None else replace_layer

        # obtain symbol from pyconizer structure.
        if by_type_code:
            class_name = unique_plr.type_code
        else:
            if isinstance(unique_plr.information, dict):
                class_name = unique_plr.information.get(language)
            else:
                class_name = unique_plr.information
        symbol = get_icon(temp_creation_path, layer, class_name)
        if symbol:
            session.add(
                LegendEntry(id=str(i) if string_keys else i,
                            symbol=symbol,
                            legend_text=unique_plr.information,
                            type_code=unique_plr.type_code,
                            topic=unique_plr.topic,
                            type_code_list=''.join(type_code_list),
                            view_service_id=unique_plr.view_service_id))
            session.flush()
            i += 1
        else:
            log.warn('It was not possible to find a symbol for the class: {0}'.
                     format(class_name))
    session.commit()
    session.close()
Exemplo n.º 11
0
def test_get_logos_config():
    Config._config = None
    Config.init('./tests/resources/test_config.yml', 'pyramid_oereb')
    logos = Config.get_logo_config()
    assert isinstance(logos, dict)