Пример #1
0
def create_update_taxonomy_post(prefer=None, q=None):
    if q:
        json_abort(
            422, {
                'message':
                'Query not appropriate when creating or updating taxonomy',
                'reason': 'search-query-not-allowed'
            })
    data = request.json
    if 'code' not in data:
        abort(Response('Code missing', status=400))
    code = data.pop('code')
    url = data.pop('url', None)
    select = data.pop('select', None)
    tax = current_flask_taxonomies.get_taxonomy(code=code, fail=False)
    if not tax:
        current_flask_taxonomies.permissions.taxonomy_create.enforce(
            request=request, code=code)
        current_flask_taxonomies.create_taxonomy(code=code,
                                                 extra_data=data,
                                                 url=url,
                                                 select=select)
        status_code = 201
    else:
        current_flask_taxonomies.permissions.taxonomy_update.enforce(
            request=request, taxonomy=tax)
        current_flask_taxonomies.update_taxonomy(tax,
                                                 extra_data=data,
                                                 url=url,
                                                 select=select)
        status_code = 200
    current_flask_taxonomies.commit()

    return get_taxonomy(code, prefer=prefer, status_code=status_code)
Пример #2
0
def delete_taxonomy_term(code=None,
                         slug=None,
                         prefer=None,
                         page=None,
                         size=None,
                         q=None):
    if q:
        json_abort(
            422, {
                'message': 'Query not appropriate when deleting term',
                'reason': 'search-query-not-allowed'
            })
    try:
        taxonomy = current_flask_taxonomies.get_taxonomy(code)
        ti = TermIdentification(taxonomy=code, slug=slug)
        term = current_flask_taxonomies.filter_term(ti).one()

        current_flask_taxonomies.permissions.taxonomy_term_delete.enforce(
            request=request, taxonomy=taxonomy, term=term)
        term = current_flask_taxonomies.delete_term(TermIdentification(
            taxonomy=code, slug=slug),
                                                    remove_after_delete=False)
        current_flask_taxonomies.commit()

    except TaxonomyTermBusyError as e:
        return json_abort(412, {'message': str(e), 'reason': 'term-busy'})
    except NoResultFound as e:
        return json_abort(404, {})
    return jsonify(term.json(representation=prefer))
Пример #3
0
def patch_taxonomy(code=None, prefer=None, page=None, size=None, q=None):
    if q:
        json_abort(
            422, {
                'message':
                'Query not appropriate when creating or updating taxonomy',
                'reason': 'search-query-not-allowed'
            })

    tax = current_flask_taxonomies.get_taxonomy(code=code, fail=False)
    if not tax:
        json_abort(404, {})

    current_flask_taxonomies.permissions.taxonomy_update.enforce(
        request=request, taxonomy=tax)

    data = {**(tax.extra_data or {}), 'url': tax.url, 'select': tax.select}
    data = jsonpatch.apply_patch(data, request.json)
    url = data.pop('url', None)
    select = data.pop('select', None)
    current_flask_taxonomies.update_taxonomy(tax,
                                             extra_data=data,
                                             url=url,
                                             select=select)
    status_code = 200
    current_flask_taxonomies.commit()

    return get_taxonomy(code,
                        prefer=prefer,
                        page=page,
                        size=size,
                        status_code=status_code)
Пример #4
0
def patch_taxonomy_term(code=None,
                        slug=None,
                        prefer=None,
                        page=None,
                        size=None,
                        q=None):
    if q:
        json_abort(
            422, {
                'message':
                'Query not appropriate when creating or updating term',
                'reason': 'search-query-not-allowed'
            })
    taxonomy = current_flask_taxonomies.get_taxonomy(code, fail=False)
    if not taxonomy:
        json_abort(404, {})
    prefer = taxonomy.merge_select(prefer)

    if INCLUDE_DELETED in prefer:
        status_cond = sqlalchemy.sql.true()
    else:
        status_cond = TaxonomyTerm.status == TermStatusEnum.alive

    ti = TermIdentification(taxonomy=code, slug=slug)
    term = current_flask_taxonomies.filter_term(
        ti, status_cond=status_cond).one_or_none()

    if not term:
        abort(404)

    current_flask_taxonomies.permissions.taxonomy_term_update.enforce(
        request=request, taxonomy=taxonomy, term=term)

    current_flask_taxonomies.update_term(
        term,
        status_cond=status_cond,
        extra_data=request.json,
        patch=True,
        status=TermStatusEnum.alive  # make it alive if it  was deleted
    )
    current_flask_taxonomies.commit()

    return get_taxonomy_term(code=code,
                             slug=slug,
                             prefer=prefer,
                             page=page,
                             size=size)
Пример #5
0
def delete_taxonomy(code=None):
    """
    Deletes a taxonomy.

    Note: this call is destructive in a sense that all its terms, regardless if used or not,
    are deleted as well. A tight user permissions should be employed.
    """
    try:
        tax = current_flask_taxonomies.get_taxonomy(code=code)
    except NoResultFound:
        json_abort(404, {})
        return  # make pycharm happy

    current_flask_taxonomies.permissions.taxonomy_delete.enforce(
        request=request, code=code)
    current_flask_taxonomies.delete_taxonomy(tax)
    current_flask_taxonomies.commit()
    return Response(status=204)
Пример #6
0
def create_update_taxonomy(code=None,
                           prefer=None,
                           page=None,
                           size=None,
                           q=None):
    if q:
        json_abort(
            422, {
                'message':
                'Query not appropriate when creating or updating taxonomy',
                'reason': 'search-query-not-allowed'
            })
    tax = current_flask_taxonomies.get_taxonomy(code=code, fail=False)

    if tax:
        current_flask_taxonomies.permissions.taxonomy_update.enforce(
            request=request, taxonomy=tax)
    else:
        current_flask_taxonomies.permissions.taxonomy_create.enforce(
            request=request, code=code)

    data = request.json
    url = data.pop('url', None)
    select = data.pop('select', None)
    if not tax:
        current_flask_taxonomies.create_taxonomy(code=code,
                                                 extra_data=request.json,
                                                 url=url,
                                                 select=select)
        status_code = 201
    else:
        current_flask_taxonomies.update_taxonomy(tax,
                                                 extra_data=request.json,
                                                 url=url,
                                                 select=select)
        status_code = 200
    current_flask_taxonomies.commit()
    return get_taxonomy(code,
                        prefer=prefer,
                        page=page,
                        size=size,
                        status_code=status_code)
Пример #7
0
def taxonomy_move_term(code=None,
                       slug=None,
                       prefer=None,
                       page=None,
                       size=None,
                       destination='',
                       rename='',
                       q=None):
    """Move term into a new parent or rename it."""
    if q:
        json_abort(
            422, {
                'message': 'Query not appropriate when moving term',
                'reason': 'search-query-not-allowed'
            })

    try:
        taxonomy = current_flask_taxonomies.get_taxonomy(code)
        ti = TermIdentification(taxonomy=taxonomy, slug=slug)
        term = current_flask_taxonomies.filter_term(ti).one()

        current_flask_taxonomies.permissions.taxonomy_term_move.enforce(
            request=request,
            taxonomy=taxonomy,
            term=term,
            destination=destination,
            rename=rename)
    except NoResultFound as e:
        return json_abort(404, {})

    if destination:
        if destination.startswith('http'):
            destination_path = urlparse(destination).path
            url_prefix = current_app.config['FLASK_TAXONOMIES_URL_PREFIX']
            if not destination_path.startswith(url_prefix):
                abort(
                    400, 'Destination not part of this server as it '
                    'does not start with config.FLASK_TAXONOMIES_URL_PREFIX')
            destination_path = destination_path[len(url_prefix):]
            destination_path = destination_path.split('/', maxsplit=1)
            if len(destination_path) > 1:
                destination_taxonomy, destination_slug = destination_path
            else:
                destination_taxonomy = destination_path[0]
                destination_slug = None
        else:
            destination_taxonomy = code
            destination_slug = destination
            if destination_slug.startswith('/'):
                destination_slug = destination_slug[1:]
        if not current_flask_taxonomies.filter_term(
                TermIdentification(taxonomy=code, slug=slug)).count():
            abort(404, 'Term %s/%s does not exist' % (code, slug))

        try:
            old_term, new_term = current_flask_taxonomies.move_term(
                TermIdentification(taxonomy=code, slug=slug),
                new_parent=TermIdentification(taxonomy=destination_taxonomy,
                                              slug=destination_slug)
                if destination_slug else '',
                remove_after_delete=False
            )  # do not remove the original node from the database,
            # just mark it as deleted
        except TaxonomyTermBusyError as e:
            return json_abort(412, {'message': str(e), 'reason': 'term-busy'})
    elif rename:
        new_slug = slug
        if new_slug.endswith('/'):
            new_slug = new_slug[:-1]
        if '/' in new_slug:
            new_slug = new_slug.rsplit('/')[0]
            new_slug = new_slug + '/' + rename
        else:
            new_slug = rename
        try:
            old_term, new_term = current_flask_taxonomies.rename_term(
                TermIdentification(taxonomy=code, slug=slug),
                new_slug=new_slug,
                remove_after_delete=False
            )  # do not remove the original node from the database, just mark it as deleted
        except TaxonomyTermBusyError as e:
            return json_abort(412, {'message': str(e), 'reason': 'term-busy'})
        destination_taxonomy = code
    else:
        abort(400, 'Pass either `destination` or `rename` parameters ')
        return  # just to make pycharm happy

    current_flask_taxonomies.commit()

    return get_taxonomy_term(code=destination_taxonomy,
                             slug=new_term.slug,
                             prefer=prefer,
                             page=page,
                             size=size)
Пример #8
0
def _create_update_taxonomy_term_internal(code,
                                          slug,
                                          prefer,
                                          page,
                                          size,
                                          extra_data,
                                          if_none_match=False,
                                          if_match=False):
    try:
        taxonomy = current_flask_taxonomies.get_taxonomy(code)
        prefer = taxonomy.merge_select(prefer)

        if INCLUDE_DELETED in prefer:
            status_cond = sqlalchemy.sql.true()
        else:
            status_cond = TaxonomyTerm.status == TermStatusEnum.alive

        slug = '/'.join(slugify(x) for x in slug.split('/'))

        ti = TermIdentification(taxonomy=code, slug=slug)
        term = original_term = current_flask_taxonomies.filter_term(
            ti, status_cond=sqlalchemy.sql.true()).one_or_none()

        if term and INCLUDE_DELETED not in prefer:
            if term.status != TermStatusEnum.alive:
                term = None

        if if_none_match and term:
            json_abort(
                412, {
                    'message':
                    'The taxonomy already contains a term on this slug. ' +
                    'As If-None-Match: \'*\' has been requested, not modifying the term',
                    'reason':
                    'term-exists'
                })

        if if_match and not term:
            json_abort(
                412, {
                    'message':
                    'The taxonomy does not contain a term on this slug. ' +
                    'As If-Match: \'*\' has been requested, not creating a new term',
                    'reason':
                    'term-does-not-exist'
                })

        if term:
            current_flask_taxonomies.permissions.taxonomy_term_update.enforce(
                request=request, taxonomy=taxonomy, term=term)
            current_flask_taxonomies.update_term(term,
                                                 status_cond=status_cond,
                                                 extra_data=extra_data)
            status_code = 200
        else:
            if original_term:
                # there is a deleted term, so return a 409 Conflict
                json_abort(
                    409, {
                        'message':
                        'The taxonomy already contains a deleted term on this slug. '
                        'To reuse the term, repeat the operation with `del` in '
                        'representation:include.',
                        'reason':
                        'deleted-term-exists'
                    })

            current_flask_taxonomies.permissions.taxonomy_term_create.enforce(
                request=request, taxonomy=taxonomy, slug=slug)
            current_flask_taxonomies.create_term(ti, extra_data=extra_data)
            status_code = 201

        current_flask_taxonomies.commit()

        return get_taxonomy_term(code=code,
                                 slug=slug,
                                 prefer=prefer,
                                 page=page,
                                 size=size,
                                 status_code=status_code)

    except NoResultFound:
        json_abort(404, {})
    except:
        traceback.print_exc()
        raise