예제 #1
0
파일: util.py 프로젝트: LayerManager/layman
def patch_after_feature_change(workspace,
                               publication_type,
                               publication,
                               *,
                               queue=None,
                               **kwargs):
    try:
        redis.create_lock(workspace, publication_type, publication,
                          common.PUBLICATION_LOCK_FEATURE_CHANGE)
    except LaymanError as exc:
        if exc.code == 49 and exc.private_data.get('can_run_later', False):
            celery_util.push_step_to_run_after_chain(
                workspace, publication_type, publication,
                'layman.util::patch_after_feature_change')
            return
        raise exc
    task_methods = tasks_util.get_source_task_methods(
        get_publication_types()[publication_type],
        'patch_after_feature_change')
    patch_chain = tasks_util.get_chain_of_methods(workspace,
                                                  publication,
                                                  task_methods,
                                                  kwargs,
                                                  'layername',
                                                  queue=queue)
    res = patch_chain()
    celery_util.set_publication_chain_info(workspace, publication_type,
                                           publication, task_methods, res)
예제 #2
0
def delete_publications(
    user,
    publ_type,
    is_chain_ready_fn,
    abort_publication_fn,
    delete_publication_fn,
    method,
    url_path,
    publ_param,
):
    from layman import authn
    actor_name = authn.get_authn_username()
    whole_infos = get_publication_infos(user, publ_type, {
        'actor_name': actor_name,
        'access_type': 'write'
    })

    for (_, _, publication) in whole_infos.keys():
        redis.create_lock(user, publ_type, publication, method)
        try:
            abort_publication_fn(user, publication)
            delete_publication_fn(user, publication)
            if is_chain_ready_fn(user, publication):
                redis.unlock_publication(user, publ_type, publication)
        except Exception as exc:
            try:
                if is_chain_ready_fn(user, publication):
                    redis.unlock_publication(user, publ_type, publication)
            finally:
                redis.unlock_publication(user, publ_type, publication)
            raise exc

    infos = [{
        'name':
        info["name"],
        'title':
        info.get("title", None),
        'url':
        url_for(**{
            'endpoint': url_path,
            publ_param: name,
            'workspace': user
        }),
        'uuid':
        info["uuid"],
        'access_rights':
        info['access_rights'],
    } for (name, info) in whole_infos.items()]
    return jsonify(infos)
예제 #3
0
def post(workspace):
    app.logger.info(f"POST Layers, user={g.user}")

    # FILE
    use_chunk_upload = False
    files = []
    if 'file' in request.files:
        files = [
            f for f in request.files.getlist("file")
            if len(f.filename) > 0
        ]
    if len(files) == 0 and len(request.form.getlist('file')) > 0:
        files = [
            filename for filename in request.form.getlist('file')
            if len(filename) > 0
        ]
        if len(files) > 0:
            use_chunk_upload = True
    if len(files) == 0:
        raise LaymanError(1, {'parameter': 'file'})

    # NAME
    unsafe_layername = request.form.get('name', '')
    if len(unsafe_layername) == 0:
        unsafe_layername = input_file.get_unsafe_layername(files)
    layername = util.to_safe_layer_name(unsafe_layername)
    util.check_layername(layername)
    info = util.get_layer_info(workspace, layername)
    if info:
        raise LaymanError(17, {'layername': layername})
    util.check_new_layername(workspace, layername)

    # CRS
    crs_id = None
    if len(request.form.get('crs', '')) > 0:
        crs_id = request.form['crs']
        if crs_id not in settings.INPUT_SRS_LIST:
            raise LaymanError(2, {'parameter': 'crs', 'supported_values': settings.INPUT_SRS_LIST})
    check_crs = crs_id is None

    # TITLE
    if len(request.form.get('title', '')) > 0:
        title = request.form['title']
    else:
        title = layername

    # DESCRIPTION
    description = request.form.get('description', '')

    # Style
    style_file = None
    if 'style' in request.files and not request.files['style'].filename == '':
        style_file = request.files['style']
    elif 'sld' in request.files and not request.files['sld'].filename == '':
        style_file = request.files['sld']
    style_type = input_style.get_style_type_from_file_storage(style_file)

    actor_name = authn.get_authn_username()

    task_options = {
        'crs_id': crs_id,
        'description': description,
        'title': title,
        'ensure_user': True,
        'check_crs': False,
        'actor_name': actor_name,
        'style_type': style_type,
        'store_in_geoserver': style_type.store_in_geoserver,
    }

    rest_common.setup_post_access_rights(request.form, task_options, actor_name)
    util.pre_publication_action_check(workspace,
                                      layername,
                                      task_options,
                                      )

    layerurl = url_for('rest_workspace_layer.get', layername=layername, workspace=workspace)

    layer_result = {
        'name': layername,
        'url': layerurl,
    }

    # FILE NAMES
    if use_chunk_upload:
        filenames = files
    else:
        filenames = [f.filename for f in files]
    input_file.check_filenames(workspace, layername, filenames, check_crs)

    redis_util.create_lock(workspace, LAYER_TYPE, layername, request.method)

    try:
        # register layer uuid
        uuid_str = uuid.assign_layer_uuid(workspace, layername)
        layer_result.update({
            'uuid': uuid_str,
        })
        task_options.update({'uuid': uuid_str, })

        # save files
        input_style.save_layer_file(workspace, layername, style_file, style_type)
        if use_chunk_upload:
            files_to_upload = input_chunk.save_layer_files_str(
                workspace, layername, files, check_crs)
            layer_result.update({
                'files_to_upload': files_to_upload,
            })
            task_options.update({
                'check_crs': check_crs,
            })
        else:
            input_file.save_layer_files(
                workspace, layername, files, check_crs)

        util.post_layer(
            workspace,
            layername,
            task_options,
            'layman.layer.filesystem.input_chunk' if use_chunk_upload else 'layman.layer.filesystem.input_file'
        )
    except Exception as exc:
        try:
            if util.is_layer_chain_ready(workspace, layername):
                redis_util.unlock_publication(workspace, LAYER_TYPE, layername)
        finally:
            redis_util.unlock_publication(workspace, LAYER_TYPE, layername)
        raise exc

    # app.logger.info('uploaded layer '+layername)
    return jsonify([layer_result]), 200
예제 #4
0
def post(workspace):
    app.logger.info(f"POST Maps, user={g.user}")

    # FILE
    if 'file' in request.files and not request.files['file'].filename == '':
        file = request.files["file"]
    else:
        raise LaymanError(1, {'parameter': 'file'})
    file_json = util.check_file(file)

    # NAME
    unsafe_mapname = request.form.get('name', '')
    if len(unsafe_mapname) == 0:
        unsafe_mapname = input_file.get_unsafe_mapname(file_json)
    mapname = util.to_safe_map_name(unsafe_mapname)
    util.check_mapname(mapname)
    info = util.get_map_info(workspace, mapname)
    if info:
        raise LaymanError(24, {'mapname': mapname})

    # TITLE
    if len(request.form.get('title', '')) > 0:
        title = request.form['title']
    elif len(file_json.get('title', '')) > 0:
        title = file_json['title']
    else:
        title = mapname

    # DESCRIPTION
    if len(request.form.get('description', '')) > 0:
        description = request.form['description']
    else:
        description = file_json.get('abstract', '')

    mapurl = url_for('rest_workspace_map.get',
                     mapname=mapname,
                     workspace=workspace)

    redis_util.create_lock(workspace, MAP_TYPE, mapname, request.method)

    try:
        map_result = {
            'name': mapname,
            'url': mapurl,
        }

        actor_name = authn.get_authn_username()

        kwargs = {
            'title': title,
            'description': description,
            'actor_name': actor_name
        }

        rest_common.setup_post_access_rights(request.form, kwargs, actor_name)
        util.pre_publication_action_check(
            workspace,
            mapname,
            kwargs,
        )
        # register map uuid
        uuid_str = uuid.assign_map_uuid(workspace, mapname)
        kwargs['uuid'] = uuid_str

        map_result.update({
            'uuid': uuid_str,
        })

        file = FileStorage(io.BytesIO(json.dumps(file_json).encode()),
                           file.filename)
        input_file.save_map_files(workspace, mapname, [file])

        util.post_map(workspace, mapname, kwargs,
                      'layman.map.filesystem.input_file')
    except Exception as exception:
        try:
            if util.is_map_chain_ready(workspace, mapname):
                redis_util.unlock_publication(workspace, MAP_TYPE, mapname)
        finally:
            redis_util.unlock_publication(workspace, MAP_TYPE, mapname)
        raise exception

    # app.logger.info('uploaded map '+mapname)
    return jsonify([map_result]), 200