def on_config_entity_post_save_layer(sender, **kwargs):
    """
        Sync tilestache to a ConfigEntity class after the latter is saved
        :param **kwargs: optional "db_entity_keys" to limit the layers created to those DbEntities
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture
    # Disable post save publishing on individual layers. The ConfigEntity is controlling publishing
    config_entity = InstanceBundle.extract_single_instance(**kwargs)
    logger.info("Handler: on_config_entity_post_save_layer for %s" % config_entity.full_name)

    #    Create LayerLibrary instances based on each LayerLibrary configuration if the configuration's scope
    #    matches that of config_entity
    client_layer_fixture = resolve_fixture(
        "presentation",
        "layer",
        LayerConfigurationFixture,
        config_entity.schema(),
        config_entity=config_entity)

    layer_library_configurations = FixtureList(client_layer_fixture.layer_libraries()).matching_scope(
        class_scope=config_entity.__class__
    )
    logger.info("Processing LayerLibrary Configurations %s" % ', '.join(map(
        lambda layer_library_configuration: layer_library_configuration.key,
        layer_library_configurations)))

    for layer_library_configuration in layer_library_configurations:
        _update_or_create_layer_library_and_layers(config_entity, layer_library_configuration, **kwargs)

    reset_queries()
def on_config_entity_post_save_layer(sender, **kwargs):
    """
        Sync tilestache to a ConfigEntity class after the latter is saved
        :param **kwargs: optional "db_entity_keys" to limit the layers created to those DbEntities
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture
    # Disable post save publishing on individual layers. The ConfigEntity is controlling publishing
    config_entity = InstanceBundle.extract_single_instance(**kwargs)
    logger.info("Handler: on_config_entity_post_save_layer for %s" %
                config_entity.full_name)

    #    Create LayerLibrary instances based on each LayerLibrary configuration if the configuration's scope
    #    matches that of config_entity
    client_layer_fixture = resolve_fixture("presentation",
                                           "layer",
                                           LayerConfigurationFixture,
                                           config_entity.schema(),
                                           config_entity=config_entity)

    layer_library_configurations = FixtureList(
        client_layer_fixture.layer_libraries()).matching_scope(
            class_scope=config_entity.__class__)
    logger.info("Processing LayerLibrary Configurations %s" % ', '.join(
        map(
            lambda layer_library_configuration: layer_library_configuration.
            key, layer_library_configurations)))

    for layer_library_configuration in layer_library_configurations:
        _update_or_create_layer_library_and_layers(
            config_entity, layer_library_configuration, **kwargs)

    reset_queries()
def on_layer_post_save_db_entity_process_layer(sender, **kwargs):
    """
        For db_entity create/update/clone, this creates or updates the layer
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    db_entity_interest = InstanceBundle.extract_single_instance(**kwargs)
    config_entity = db_entity_interest.config_entity.subclassed
    db_entity = db_entity_interest.db_entity

    logger.info("Handler: on_layer_post_save_db_enitty_process_layer for DbEntity: key %s, id %s" % (db_entity.key, db_entity.id))
    # Return if the db_entity was not created from an user imported feature
    # Configured layer saving is handled by after saving the ConfigEntity
    if not db_entity.feature_class_configuration.generated:
        return

    layer_configuration_fixture = resolve_fixture(
        "presentation",
        "layer",
        LayerConfigurationFixture,
        config_entity.schema(),
        config_entity=config_entity)

    # Update the layer via the layer library update_or_create
    # Find LayerLibraries matching the ConfigEntity class schope
    for layer_library_configuration in layer_configuration_fixture.layer_libraries():

        logger.info("Handler: Layer Library Configuration: %s" % layer_library_configuration)
        # Update/Create the layer library and layers
        _update_or_create_layer_library_and_layers(
            config_entity,
            layer_library_configuration,
            db_entity_keys=[db_entity.key])
def resolve_layer_configuration(config_entity, db_entity_key, layer):
    """
        Creates a LayerConfiguration for imported layers using the template
        LayerConfigurations designed in the LayerConfigurationFixture.import_layer_configurations
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    # if a layer exists and it has a layer configuration update it
    if layer and layer.configuration:
        layer_configuration = LayerConfiguration(**merge(
            dict(
                db_entity_key=layer.db_entity_key,
                layer_library_key=layer.key,
                visible=layer.visible,
                # Convert the LayerStyle to a dict, which is what a LayerConfiguration expects, and wipe out the ids
                layer_style=model_dict(layer.medium)),
            dict(
                built_form_set_key=layer.configuration.
                get('built_form_key', None),
                sort_priority=layer.configuration.get('sort_priority', None),
                attribute_sort_priority=layer.configuration.
                get('attribute_sort_priority', None),
                column_alias_lookup=layer.configuration.
                get('column_alias_lookup', None),
            ) if layer.configuration else dict()))
    # if the the layer configuration doesn't exist, utilize the default layer configuration
    else:
        client_layer_configuration = resolve_fixture(
            "presentation",
            "layer",
            LayerConfigurationFixture,
            config_entity.schema(),
            config_entity=config_entity)

        geometry_type = config_entity.db_entity_by_key(
            db_entity_key).geometry_type
        layer_configuration = copy.copy(
            list(
                client_layer_configuration.import_layer_configurations(
                    geometry_type))[0])
        # Update the template LayerConfiguration to our db_entity_key
        layer_configuration.db_entity_key = db_entity_key

    return layer_configuration
Exemple #5
0
def update_or_create_analysis_modules(config_entity, **kwargs):
    """
        Creates a results library and Result instances upon saving a config_entity if they do not yet exist.
    :param config_entity
    :return:
    """
    from footprint.client.configuration.fixture import AnalysisModuleFixture
    from footprint.client.configuration import resolve_fixture
    analysis_module_fixture = resolve_fixture("analysis_module",
                                              "analysis_module",
                                              AnalysisModuleFixture,
                                              config_entity.schema(),
                                              config_entity=config_entity)

    for analysis_module_configuration in analysis_module_fixture.default_analysis_module_configurations(
    ):
        # Create the table the first time
        analysis_module, created, updated = AnalysisModule.objects.update_or_create(
            config_entity=config_entity,
            key=analysis_module_configuration.key,
            defaults=dict(
                name=analysis_module_configuration.name,
                description=analysis_module_configuration.description,
                partner_description=analysis_module_configuration.
                partner_description,
                configuration=remove_keys(
                    analysis_module_configuration.configuration,
                    ['key', 'name', 'description'])))

        # Update the updater field to the user calling the module, or default to superadmin
        if not analysis_module.updater:
            analysis_module.updater = kwargs.get(
                'user',
                get_user_model().objects.get(username=UserGroupKey.SUPERADMIN))
        # For the first run make the creator the updater
        if not analysis_module.creator:
            analysis_module.creator = analysis_module.updater
        # update_or_create will kick off the run for updates.
        # don't let it run here
        previous = analysis_module._no_post_save_task_run
        analysis_module._no_post_save_task_run = True
        analysis_module.save()
        analysis_module._no_post_save_task_run = previous
        analysis_module.init()
def update_or_create_layer_style_from_configuration(config_entity, db_entity, layer, layer_configuration):
    """
        Iterates through the LayerConfiguration and creates LayerStyle instances for each that contain default
        styling for the configured attributes
    :return:
    """

    # Find the corresponding config_entity_fixture, or parent fixture if it doesn't exist
    layer_fixture = resolve_fixture(
        "presentation",
        "layer",
        LayerConfigurationFixture,
        config_entity.schema(),
        config_entity=config_entity)

    logger.info("Configuring Layer Media for %s. Processing Layer Configurations" % config_entity.full_name)
    logger.info("Config Entity %s. layer_configuration %s. layer %s" % (config_entity, layer_configuration.__dict__, layer))

    layer_fixture.update_or_create_layer_style(config_entity, layer_configuration, layer)
def update_or_create_layer_library_and_layers(config_entity, **kwargs):
    #    Create LayerLibrary instances based on each LayerLibrary configuration if the configuration's scope
    #    matches that of config_entity
    client_layer_fixture = resolve_fixture(
        "presentation",
        "layer",
        LayerConfigurationFixture,
        config_entity.schema(),
        config_entity=config_entity)

    layer_library_configurations = FixtureList(client_layer_fixture.layer_libraries()).matching_scope(
        class_scope=config_entity.__class__
    )
    logger.info("Processing LayerLibrary Configurations %s" % ', '.join(map(
        lambda layer_library_configuration: layer_library_configuration.key,
        layer_library_configurations)))

    for layer_library_configuration in layer_library_configurations:
        _update_or_create_layer_library_and_layers(config_entity, layer_library_configuration, **kwargs)
def resolve_layer_configuration(config_entity, db_entity_key, layer):
    """
        Creates a LayerConfiguration for imported layers using the template
        LayerConfigurations designed in the LayerConfigurationFixture.import_layer_configurations
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    # if a layer exists and it has a layer configuration update it
    if layer and layer.configuration:
        layer_configuration = LayerConfiguration(
            **merge(
                dict(
                    db_entity_key=layer.db_entity_key,
                    layer_library_key=layer.key,
                    visible=layer.visible,
                    # Convert the LayerStyle to a dict, which is what a LayerConfiguration expects, and wipe out the ids
                    layer_style=model_dict(layer.medium)
                ),
                dict(
                    built_form_set_key=layer.configuration.get('built_form_key', None),
                    sort_priority=layer.configuration.get('sort_priority', None),
                    attribute_sort_priority=layer.configuration.get('attribute_sort_priority', None),
                    column_alias_lookup=layer.configuration.get('column_alias_lookup', None),
                ) if layer.configuration else dict()
            )
        )
    # if the the layer configuration doesn't exist, utilize the default layer configuration
    else:
        client_layer_configuration = resolve_fixture(
            "presentation",
            "layer",
            LayerConfigurationFixture,
            config_entity.schema(),
            config_entity=config_entity)

        geometry_type = config_entity.db_entity_by_key(db_entity_key).geometry_type
        layer_configuration = copy.copy(list(client_layer_configuration.import_layer_configurations(geometry_type))[0])
        # Update the template LayerConfiguration to our db_entity_key
        layer_configuration.db_entity_key = db_entity_key

    return layer_configuration
def update_or_create_layer_library_and_layers(config_entity, **kwargs):
    #    Create LayerLibrary instances based on each LayerLibrary configuration if the configuration's scope
    #    matches that of config_entity
    client_layer_fixture = resolve_fixture("presentation",
                                           "layer",
                                           LayerConfigurationFixture,
                                           config_entity.schema(),
                                           config_entity=config_entity)

    layer_library_configurations = FixtureList(
        client_layer_fixture.layer_libraries()).matching_scope(
            class_scope=config_entity.__class__)
    logger.info("Processing LayerLibrary Configurations %s" % ', '.join(
        map(
            lambda layer_library_configuration: layer_library_configuration.
            key, layer_library_configurations)))

    for layer_library_configuration in layer_library_configurations:
        _update_or_create_layer_library_and_layers(
            config_entity, layer_library_configuration, **kwargs)
def on_layer_post_save_process_layer(sender, **kwargs):
    """
        For layer create/update/clone, this updates the saved layer
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    layer = InstanceBundle.extract_single_instance(**kwargs)

    logger.info("Handler: No Post Save Publising %s" %
                layer._no_post_save_publishing)
    if layer._no_post_save_publishing:
        return

    db_entity_interest = layer.db_entity_interest
    db_entity = db_entity_interest.db_entity
    config_entity = db_entity_interest.config_entity.subclassed

    logger.info(
        "Handler: Layer Publishing. on_layer_post_save_process_layer %s for config entity %s and db_entity %s"
        % (layer.full_name, config_entity.name, db_entity.key))

    layer_configuration_fixture = resolve_fixture("presentation",
                                                  "layer",
                                                  LayerConfigurationFixture,
                                                  config_entity.schema(),
                                                  config_entity=config_entity)

    # Update the layer via the layer library update_or_create
    # Find LayerLibraries matching the ConfigEntity class schope
    for layer_library_configuration in layer_configuration_fixture.layer_libraries(
    ):

        logger.info("Handler: Layer Configuration: %s" %
                    layer_library_configuration)
        # Update/Create the layer library and layers
        _update_or_create_layer_library_and_layers(
            config_entity,
            layer_library_configuration,
            db_entity_keys=[db_entity.key])
def update_or_create_analysis_modules(config_entity, **kwargs):
    """
        Creates a results library and Result instances upon saving a config_entity if they do not yet exist.
    :param config_entity
    :return:
    """
    from footprint.client.configuration.fixture import AnalysisModuleFixture
    from footprint.client.configuration import resolve_fixture
    analysis_module_fixture = resolve_fixture(
        "analysis_module",
        "analysis_module",
        AnalysisModuleFixture,
        config_entity.schema(),
        config_entity=config_entity)

    for analysis_module_configuration in analysis_module_fixture.default_analysis_module_configurations():
        # Create the table the first time
        analysis_module, created, updated = AnalysisModule.objects.update_or_create(
            config_entity=config_entity,
            key=analysis_module_configuration.key,
            defaults=dict(
                name=analysis_module_configuration.name,
                description=analysis_module_configuration.description,
                partner_description=analysis_module_configuration.partner_description,
                configuration=remove_keys(analysis_module_configuration.configuration, ['key', 'name', 'description']))
        )

        # Update the updater field to the user calling the module, or default to superadmin
        if not analysis_module.updater:
            analysis_module.updater = kwargs.get('user', get_user_model().objects.get(username=UserGroupKey.SUPERADMIN))
        # For the first run make the creator the updater
        if not analysis_module.creator:
            analysis_module.creator = analysis_module.updater
        # update_or_create will kick off the run for updates.
        # don't let it run here
        previous = analysis_module._no_post_save_task_run
        analysis_module._no_post_save_task_run = True
        analysis_module.save()
        analysis_module._no_post_save_task_run = previous
        analysis_module.init()
def on_layer_post_save_process_layer(sender, **kwargs):
    """
        For layer create/update/clone, this updates the saved layer
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    layer = InstanceBundle.extract_single_instance(**kwargs)

    logger.info("Handler: No Post Save Publising %s" % layer._no_post_save_publishing)
    if layer._no_post_save_publishing:
        return

    db_entity_interest = layer.db_entity_interest
    db_entity = db_entity_interest.db_entity
    config_entity = db_entity_interest.config_entity.subclassed

    logger.info("Handler: Layer Publishing. on_layer_post_save_process_layer %s for config entity %s and db_entity %s" %
                (layer.full_name, config_entity.name, db_entity.key))

    layer_configuration_fixture = resolve_fixture(
        "presentation",
        "layer",
        LayerConfigurationFixture,
        config_entity.schema(),
        config_entity=config_entity)

    # Update the layer via the layer library update_or_create
    # Find LayerLibraries matching the ConfigEntity class schope
    for layer_library_configuration in layer_configuration_fixture.layer_libraries():

        logger.info("Handler: Layer Configuration: %s" % layer_library_configuration)
        # Update/Create the layer library and layers
        _update_or_create_layer_library_and_layers(
            config_entity,
            layer_library_configuration,
            db_entity_keys=[db_entity.key])
def on_layer_post_save_db_entity_process_layer(sender, **kwargs):
    """
        For db_entity create/update/clone, this creates or updates the layer
    """
    from footprint.client.configuration.fixture import LayerConfigurationFixture
    from footprint.client.configuration.utils import resolve_fixture

    db_entity_interest = InstanceBundle.extract_single_instance(**kwargs)
    config_entity = db_entity_interest.config_entity.subclassed
    db_entity = db_entity_interest.db_entity

    logger.info(
        "Handler: on_layer_post_save_db_enitty_process_layer for DbEntity: key %s, id %s"
        % (db_entity.key, db_entity.id))
    # Return if the db_entity was not created from an user imported feature
    # Configured layer saving is handled by after saving the ConfigEntity
    if not db_entity.feature_class_configuration.generated:
        return

    layer_configuration_fixture = resolve_fixture("presentation",
                                                  "layer",
                                                  LayerConfigurationFixture,
                                                  config_entity.schema(),
                                                  config_entity=config_entity)

    # Update the layer via the layer library update_or_create
    # Find LayerLibraries matching the ConfigEntity class schope
    for layer_library_configuration in layer_configuration_fixture.layer_libraries(
    ):

        logger.info("Handler: Layer Library Configuration: %s" %
                    layer_library_configuration)
        # Update/Create the layer library and layers
        _update_or_create_layer_library_and_layers(
            config_entity,
            layer_library_configuration,
            db_entity_keys=[db_entity.key])
def update_or_create_layer_style_from_configuration(config_entity, db_entity,
                                                    layer,
                                                    layer_configuration):
    """
        Iterates through the LayerConfiguration and creates LayerStyle instances for each that contain default
        styling for the configured attributes
    :return:
    """

    # Find the corresponding config_entity_fixture, or parent fixture if it doesn't exist
    layer_fixture = resolve_fixture("presentation",
                                    "layer",
                                    LayerConfigurationFixture,
                                    config_entity.schema(),
                                    config_entity=config_entity)

    logger.info(
        "Configuring Layer Media for %s. Processing Layer Configurations" %
        config_entity.full_name)
    logger.info("Config Entity %s. layer_configuration %s. layer %s" %
                (config_entity, layer_configuration.__dict__, layer))

    layer_fixture.update_or_create_layer_style(config_entity,
                                               layer_configuration, layer)
def update_or_create_behaviors(config_entity, **kwargs):
    """
        Creates Behaviors when saving a config_entity if they do not yet exist.
        :param config_entity
        :return:
    """

    # Just process Regions and GlobalConfig
    if not isinstance(config_entity, GlobalConfig, Region):
        return

    from footprint.client.configuration.fixture import BehaviorFixture

    client_behavior_fixture = resolve_fixture(
        "behavior",
        "behavior",
        BehaviorFixture,
        config_entity.schema(),
        config_entity=config_entity)

    # Create each ResultLibrary and store them as a dict keyed by their key
    result_library_lookup = map_to_dict(lambda result_library_config: [
        result_library_config.key,
        ResultLibrary.objects.update_or_create(
            key=result_library_config.key,
            config_entity=config_entity,
            scope=config_entity.schema(),
            defaults=dict(
                name=result_library_config.name.format(config_entity.name),
                description=result_library_config.description.format(config_entity.name)
            )
        )[0]],
        client_result.result_libraries())

    #for key, result_library in result_library_lookup.items():
    #    result_library.results.all().delete()

    # Create each configured Result
    for result_config in filter(lambda result:
                                    not db_entity_keys or
                                    result.result_db_entity_key in db_entity_keys or
                                    result.source_db_entity_key in db_entity_keys,
                                client_result.results()):

        logger.info("Result Publishing Result DbEntity Key: %s" % result_config.result_db_entity_key)
        # Create the db_entity and db_entity_interest for the result
        db_entity = result_config.update_or_create_db_entity(config_entity)
        # Make the db_entity the default selected one for its key
        previous = config_entity._no_post_save_publishing
        config_entity._no_post_save_publishing = True
        config_entity.save()
        config_entity._no_post_save_publishing = previous

        # Test the query
        db_entity.parse_query(config_entity)

        db_entity_interest = DbEntityInterest.objects.get(
            config_entity=config_entity,
            db_entity__key=result_config.result_db_entity_key
        )

        # Create a result for each result key given.
        result, created, updated = Result.objects.update_or_create(
            db_enitty_interest=db_entity_interest,
            defaults=dict(
                # Use the Result's custom Medium, keyed by the Result key
                medium=result_config.resolve_result_medium(),
                configuration=result_config.get_presentation_medium_configuration())
        )
        # If created, add the result to the matching result library
        if created:
            result_library_lookup[result_config.result_library_key].presentation_media.add(result)

    # Remove orphan results and their DbEntityInterests/DbEntities
    result_library_ids = map(lambda result_library: result_library.id, ResultLibrary.objects.filter(config_entity=config_entity))
    valid_result_keys = map(lambda result_config: result_config.result_db_entity_key, client_result.results())
    orphan_results = Result.objects.filter(presentation__id__in=result_library_ids).exclude(db_entity_key__in=valid_result_keys)
    DbEntityInterest.objects.filter(config_entity=config_entity, db_entity__key__in=map(lambda result: result.db_entity_key, orphan_results)).delete()
    orphan_results.delete()