Esempio n. 1
0
def item(app, environ, request, version, uid, cid, id):
    """GET, PUT or DELETE an item into collection_id."""

    if request.method == 'HEAD' or request.authorization.username != uid:
        return Response('Not Authorized', 401)

    global FIELDS

    dbpath = path(app.data_dir, uid, request.authorization.password)
    expire(dbpath, cid)

    if request.method == 'GET':
        try:
            with sqlite3.connect(dbpath) as db:
                res = db.execute('SELECT %s FROM %s WHERE id=?' % \
                    (','.join(FIELDS), cid), [id]).fetchone()
        except sqlite3.OperationalError:
            # table can not exists, e.g. (not a nice way to do, though)
            res = None

        if res is None:
            return Response(WEAVE_INVALID_WBO, 404)

        js = json.dumps(wbo2dict(res))
        return Response(js, 200, content_type='application/json',
                        headers={'X-Weave-Records': str(len(res))})

    since = request.headers.get('X-If-Unmodified-Since', None)
    if since and has_modified(float(since), dbpath, cid):
        return Response('Precondition Failed', 412)

    if  request.method == 'PUT':
        try:
            data = jsonloads(request.data)
        except ValueError:
            return Response(WEAVE_MALFORMED_JSON, 400)
        except TypeError:
            return Response(WEAVE_INVALID_WBO, 400)

        if id not in data:
            data['id'] = id

        try:
            obj = set_item(dbpath, uid, cid, data)
        except ValueError:
            return Response(WEAVE_INVALID_WBO, 400)

        return Response(json.dumps(obj['modified']), 200,
            content_type='application/json',
            headers={'X-Weave-Timestamp': round(obj['modified'], 2)})

    elif request.method == 'DELETE':
        with sqlite3.connect(dbpath) as db:
            db.execute('DELETE FROM %s WHERE id=?' % cid, [id])
        return Response(json.dumps(time.time()), 200,
            content_type='application/json')
Esempio n. 2
0
def item(app, environ, request, version, uid, cid, id):
    """GET, PUT or DELETE an item into collection_id."""

    if request.method == 'HEAD' or request.authorization.username != uid:
        return Response('Not Authorized', 401)

    dbpath = app.dbpath(uid, request.authorization.password)
    expire(dbpath, cid)

    if request.method == 'GET':
        try:
            with sqlite3.connect(dbpath) as db:
                res = db.execute('SELECT %s FROM %s WHERE id=?' % \
                    (','.join(FIELDS), cid), [id]).fetchone()
        except sqlite3.OperationalError:
            # table can not exists, e.g. (not a nice way to do, though)
            res = None

        if res is None:
            return Response(WEAVE_INVALID_WBO, 404)

        js = json.dumps(wbo2dict(res))
        return Response(js,
                        200,
                        content_type='application/json',
                        headers={'X-Weave-Records': str(len(res))})

    since = request.headers.get('X-If-Unmodified-Since', None)
    if since and has_modified(float(since), dbpath, cid):
        return Response('Precondition Failed', 412)

    if request.method == 'PUT':

        data = request.get_json()

        if id not in data:
            data['id'] = id

        try:
            obj = set_item(dbpath, uid, cid, data)
        except ValueError:
            return Response(WEAVE_INVALID_WBO, 400)

        return Response(
            json.dumps(obj['modified']),
            200,
            content_type='application/json',
            headers={'X-Weave-Timestamp': round(obj['modified'], 2)})

    elif request.method == 'DELETE':
        with sqlite3.connect(dbpath) as db:
            db.execute('DELETE FROM %s WHERE id=?' % cid, [id])
        return Response(json.dumps(time.time()),
                        200,
                        content_type='application/json')
Esempio n. 3
0
def collection(app, environ, request, version, uid, cid):
    """/<float:version>/<username>/storage/<collection>"""

    if request.method == 'HEAD' or request.authorization.username != uid:
        return Response('Not Authorized', 401)

    dbpath = app.dbpath(uid, request.authorization.password)
    expire(dbpath, cid)

    ids    = request.args.get('ids', None)
    offset = request.args.get('offset', None)
    older  = request.args.get('older', None)
    newer  = request.args.get('newer', None)
    full   = request.args.get('full', False)
    index_above = request.args.get('index_above', None)
    index_below = request.args.get('index_below', None)
    limit  = request.args.get('limit', None)
    offset = request.args.get('offset', None)
    sort   = request.args.get('sort', None)
    parentid = request.args.get('parentid', None)
    predecessorid = request.args.get('predecessorid', None)

    try:
        older and float(older)
        newer and float(newer)
        limit and int(limit)
        offset and int(offset)
        index_above and int(index_above)
        index_below and int(index_below)
    except ValueError:
        raise BadRequest

    if limit is not None:
        limit = int(limit)

    if offset is not None:
        # we need both
        if limit is None:
            offset = None
        else:
            offset = int(offset)

    if not full:
        fields = ['id']
    else:
        fields = FIELDS

    # filters used in WHERE clause
    filters = {}
    if ids is not None:
        filters['id'] =  'IN', '(%s)' % ids
    if older is not None:
        filters['modified'] = '<', float(older)
    if newer is not None:
        filters['modified'] = '>', float(newer)
    if index_above is not None:
        filters['sortindex'] = '>', int(index_above)
    if index_below is not None:
        filters['sortindex'] = '<', int(index_below)
    if parentid is not None:
        filters['parentid'] = '=', "'%s'" % parentid
    if predecessorid is not None:
        filters['predecessorid'] = '=', "'%s'" % predecessorid

    filter_query, sort_query, limit_query = '', '', ''

    # ORDER BY x ASC|DESC
    if sort is not None:
        if sort == 'index':
            sort_query = ' ORDER BY sortindex DESC'
        elif sort == 'oldest':
            sort_query = ' ORDER BY modified ASC'
        elif sort == 'newest':
            sort_query = ' ORDER BY modified DESC'

    # WHERE x<y AND ...
    if filters:
        filter_query = ' WHERE '
        filter_query += ' AND '.join([k + ' ' + v[0] + ' ' + str(v[1])
            for k, v in iteritems(filters)])

    # LIMIT x [OFFSET y]
    if limit:
        limit_query += ' LIMIT %i' % limit
        if offset:
            limit_query += ' OFFSET %i' % offset

    if request.method == 'GET':
        # Returns a list of the WBO or ids contained in a collection.

        with sqlite3.connect(dbpath) as db:
            try:
                res = db.execute('SELECT %s FROM %s' % (','.join(fields), cid) \
                      + filter_query + sort_query + limit_query).fetchall()
            except sqlite3.OperationalError:
                res = []

        res = [v[0] if len(fields) == 1 else wbo2dict(v) for v in res]
        res, mime, records = convert(res, request.accept_mimetypes.best)

        return Response(res, 200, content_type=mime,
                        headers={'X-Weave-Records': str(records)})

    # before we write, check if the data has not been modified since the request
    since = request.headers.get('X-If-Unmodified-Since', None)
    if since and has_modified(float(since), dbpath, cid):
        raise PreconditionFailed

    if request.method == 'DELETE':
        try:
            with sqlite3.connect(dbpath) as db:
                select = 'SELECT id FROM %s' % cid + filter_query \
                       + sort_query + limit_query
                db.execute('DELETE FROM %s WHERE id IN (%s)' % (cid, select))
        except sqlite3.OperationalError:
            pass
        return Response(json.dumps(time.time()), 200)

    elif request.method in ('PUT', 'POST'):

        data = request.get_json()

        if isinstance(data, dict):
            data = [data]

        success, failed = [], []
        for item in data:
            if 'id' not in item:
                failed.append(item)
                continue

            try:
                o = set_item(dbpath, uid, cid, item)
                success.append(o['id'])
            except ValueError:
                failed.append(item['id'])

        js = json.dumps({'modified': round(time.time(), 2), 'success': success,
                         'failed': failed})
        return Response(js, 200, content_type='application/json',
                        headers={'X-Weave-Timestamp': round(time.time(), 2)})
Esempio n. 4
0
def collection(app, environ, request, version, uid, cid):
    """/<float:version>/<username>/storage/<collection>"""

    if request.method == 'HEAD' or request.authorization.username != uid:
        return Response('Not Authorized', 401)

    dbpath = app.dbpath(uid, request.authorization.password)
    expire(dbpath, cid)

    ids = request.args.get('ids', None)
    offset = request.args.get('offset', None)
    older = request.args.get('older', None)
    newer = request.args.get('newer', None)
    full = request.args.get('full', False)
    index_above = request.args.get('index_above', None)
    index_below = request.args.get('index_below', None)
    limit = request.args.get('limit', None)
    offset = request.args.get('offset', None)
    sort = request.args.get('sort', None)
    parentid = request.args.get('parentid', None)
    predecessorid = request.args.get('predecessorid', None)

    try:
        older and float(older)
        newer and float(newer)
        limit and int(limit)
        offset and int(offset)
        index_above and int(index_above)
        index_below and int(index_below)
    except ValueError:
        raise BadRequest

    if limit is not None:
        limit = int(limit)

    if offset is not None:
        # we need both
        if limit is None:
            offset = None
        else:
            offset = int(offset)

    if not full:
        fields = ['id']
    else:
        fields = FIELDS

    # filters used in WHERE clause
    filters = {}
    if ids is not None:
        filters['id'] = 'IN', '(%s)' % ",".join("'" + x.strip() + "'"
                                                for x in ids.split(","))
    if older is not None:
        filters['modified'] = '<', float(older)
    if newer is not None:
        filters['modified'] = '>', float(newer)
    if index_above is not None:
        filters['sortindex'] = '>', int(index_above)
    if index_below is not None:
        filters['sortindex'] = '<', int(index_below)
    if parentid is not None:
        filters['parentid'] = '=', "'%s'" % parentid
    if predecessorid is not None:
        filters['predecessorid'] = '=', "'%s'" % predecessorid

    filter_query, sort_query, limit_query = '', '', ''

    # ORDER BY x ASC|DESC
    if sort is not None:
        if sort == 'index':
            sort_query = ' ORDER BY sortindex DESC'
        elif sort == 'oldest':
            sort_query = ' ORDER BY modified ASC'
        elif sort == 'newest':
            sort_query = ' ORDER BY modified DESC'

    # WHERE x<y AND ...
    if filters:
        filter_query = ' WHERE '
        filter_query += ' AND '.join(
            [k + ' ' + v[0] + ' ' + str(v[1]) for k, v in iteritems(filters)])

    # LIMIT x [OFFSET y]
    if limit:
        limit_query += ' LIMIT %i' % limit
        if offset:
            limit_query += ' OFFSET %i' % offset

    if request.method == 'GET':
        # Returns a list of the WBO or ids contained in a collection.

        with sqlite3.connect(dbpath) as db:
            try:
                res = db.execute('SELECT %s FROM %s' % (','.join(fields), cid) \
                      + filter_query + sort_query + limit_query).fetchall()
            except sqlite3.OperationalError:
                res = []

        res = [v[0] if len(fields) == 1 else wbo2dict(v) for v in res]
        res, mime, records = convert(res, request.accept_mimetypes.best)

        return Response(res,
                        200,
                        content_type=mime,
                        headers={'X-Weave-Records': str(records)})

    # before we write, check if the data has not been modified since the request
    since = request.headers.get('X-If-Unmodified-Since', None)
    if since and has_modified(float(since), dbpath, cid):
        raise PreconditionFailed

    if request.method == 'DELETE':
        try:
            with sqlite3.connect(dbpath) as db:
                select = 'SELECT id FROM %s' % cid + filter_query \
                       + sort_query + limit_query
                db.execute('DELETE FROM %s WHERE id IN (%s)' % (cid, select))
        except sqlite3.OperationalError:
            pass
        return Response(json.dumps(time.time()), 200)

    elif request.method in ('PUT', 'POST'):

        data = request.get_json()

        if isinstance(data, dict):
            data = [data]

        success, failed = [], []
        for item in data:
            if 'id' not in item:
                failed.append(item)
                continue

            try:
                o = set_item(dbpath, uid, cid, item)
                success.append(o['id'])
            except ValueError:
                failed.append(item['id'])

        js = json.dumps({
            'modified': round(time.time(), 2),
            'success': success,
            'failed': failed
        })
        return Response(js,
                        200,
                        content_type='application/json',
                        headers={'X-Weave-Timestamp': round(time.time(), 2)})