Beispiel #1
0
    def put(self, id):
        permission = auth.UpdatePatchPermission(id)
        if not permission.can():
            raise auth.PermissionDenied(permission)
        try:
            patch = JsonPatch(parse_json(request))
            affected_entities = patching.validate(
                patch, database.get_dataset())
        except ResourceError as e:
            return e.response()
        except patching.InvalidPatchError as e:
            if str(e) != 'Could not apply JSON patch to dataset.':
                return {'status': 400, 'message': str(e)}, 400

        db = database.get_db()
        curs = db.cursor()
        curs.execute('''
UPDATE patch_request SET
original_patch = ?,
updated_entities = ?,
removed_entities = ?,
updated_by = ?
WHERE id = ?
        ''', (patch.to_string(),
              json.dumps(sorted(affected_entities['updated'])),
              json.dumps(sorted(affected_entities['removed'])),
              g.identity.id, id)
        )
        db.commit()
Beispiel #2
0
    def get(self):
        args = dataset_parser.parse_args()

        dataset = database.get_dataset(args.get('version', None))

        if not dataset:
            if args['version']:
                return {'status': 404,
                        'message': 'Could not find given version.'}, 404
            else:
                return {'status': 501,
                        'message': 'No dataset loaded yet.'}, 501

        requested_etag = args.get('etag')
        dataset_etag = 'periodo-dataset-version-{}'.format(dataset['id'])

        if requested_etag == dataset_etag:
            return None, 304

        headers = {}
        headers['Last-Modified'] = format_date_time(dataset['created_at'])

        if not args['version']:
            headers['Cache-control'] = 'public, max-age=0'
        else:
            headers['Cache-control'] = 'public, max-age=604800'

        response = api.make_response(
            attach_to_dataset(json.loads(dataset['data'])), 200, headers)
        response.set_etag(dataset_etag, weak=True)

        return response
Beispiel #3
0
def void():
    if request.accept_mimetypes.best == 'text/html':
        return redirect(url_for('void_as_html'), code=303)
    return make_response(database.get_dataset()['description'], 200, {
        'Content-Type': 'text/turtle',
        'Link': '</>; rel="alternate"; type="text/html"',
    })
Beispiel #4
0
 def get(self):
     data = get_graphs()
     dataset = database.get_dataset()
     if dataset:
         dataset_url = url_for('dataset', _external=True)
         data['graphs'][dataset_url] = json.loads(dataset['data'])
     return cache.medium_time(
         api.make_response(data, 200, filename='periodo-graphs'))
Beispiel #5
0
def is_mergeable(patch_text, dataset=None):
    dataset = dataset or database.get_dataset()
    patch = from_text(patch_text)
    mergeable = True
    try:
        patch.apply(json.loads(dataset['data']))
    except (JsonPatchException, JsonPointerException):
        mergeable = False
    return mergeable
Beispiel #6
0
def merge(patch_id, user_id):
    row = database.query_db(
        'SELECT * FROM patch_request WHERE id = ?', (patch_id,), one=True)

    if not row:
        raise MergeError('No patch with ID {}.'.format(patch_id))
    if row['merged']:
        raise MergeError('Patch is already merged.')
    if not row['open']:
        raise MergeError('Closed patches cannot be merged.')

    dataset = database.get_dataset()
    mergeable = is_mergeable(row['original_patch'], dataset)

    if not mergeable:
        raise UnmergeablePatchError('Patch is not mergeable.')

    data = json.loads(dataset['data'])
    original_patch = from_text(row['original_patch'])
    applied_patch, id_map = replace_skolem_ids(
        original_patch, data, database.get_removed_entity_keys())
    created_entities = set(id_map.values())

    # Should this be ordered?
    new_data = applied_patch.apply(data)

    db = database.get_db()
    curs = db.cursor()
    curs.execute(
        '''
        UPDATE patch_request
        SET merged = 1,
            open = 0,
            merged_at = strftime('%s', 'now'),
            merged_by = ?,
            applied_to = ?,
            created_entities = ?,
            identifier_map = ?,
            applied_patch = ?
        WHERE id = ?;
        ''',
        (user_id,
         dataset['id'],
         json.dumps(sorted(created_entities)),
         json.dumps(id_map),
         applied_patch.to_string(),
         row['id'])
    )
    version_id = add_new_version_of_dataset(new_data)
    curs.execute(
        '''
        UPDATE patch_request
        SET resulted_in = ?
        WHERE id = ?;
        ''',
        (version_id, row['id'])
    )
Beispiel #7
0
def get_dataset(version=None):
    dataset = database.get_dataset(version)

    if not dataset:
        if version:
            raise ResourceError(404, 'Could not find given version.')
        else:
            raise ResourceError(501, 'No dataset loaded yet.')

    return dataset
Beispiel #8
0
def create_request(patch, user_id):
    dataset = database.get_dataset()
    affected_entities = validate(patch, dataset)
    cursor = database.get_db().cursor()
    cursor.execute('''
INSERT INTO patch_request
(created_by, updated_by, created_from, updated_entities, removed_entities,
 original_patch)
VALUES (?, ?, ?, ?, ?, ?)
    ''', (user_id, user_id, dataset['id'],
          json.dumps(sorted(affected_entities['updated'])),
          json.dumps(sorted(affected_entities['removed'])),
          patch.to_string()))
    return cursor.lastrowid
Beispiel #9
0
 def get(self, collection_id):
     version = request.args.get('version')
     new_location = redirect_to_last_update(collection_id, version)
     if new_location is not None:
         return new_location
     dataset = database.get_dataset(version=version)
     o = json.loads(dataset['data'])
     if 'periodCollections' not in o:
         abort(404)
     collection_key = identifier.prefix(collection_id)
     if collection_key not in o['periodCollections']:
         abort_gone_or_not_found(collection_key)
     collection = o['periodCollections'][collection_key]
     collection['@context'] = o['@context']
     return attach_to_dataset(collection)
Beispiel #10
0
def void():
    return make_response(database.get_dataset()['description'], 200, {
        'Content-Type': 'text/turtle',
        'Link': '</>; rel="alternate"; type="text/html"',
    })
Beispiel #11
0
def void_as_html():
    ttl = database.get_dataset()['description']
    return make_response(utils.highlight_ttl(ttl), 200, {
        'Content-Type': 'text/html',
        'Link': '</>; rel="alternate"; type="text/html"',
    })