示例#1
0
    def delete(self, path):
        """Delete a file under a given path."""
        internal_path = validate_path(path)

        parent = Path('/')
        entry = None
        for part in internal_path.parts:
            entry = mongo.db.index.find_one({
                'name': part,
                'parent': str(parent)
            })
            if entry is None:
                abort(404)
            parent /= part

        if entry['is_directory']:
            abort(404)

        for server in entry['servers']:
            response = requests.delete(f'http://{server}/file/{internal_path}')
            mongo.db.servers.replace_one(
                {'_id': server},
                {
                    '_id': server,
                    'free_space': int(response.text)
                },
            )

        mongo.db.index.delete_one(entry)

        return jsonify(get_min_free_space())
示例#2
0
def initialize():
    """Wipe everything from the storage servers."""
    for server in mongo.db.servers.find():
        response = requests.post(f'http://{server["_id"]}/initialize')
        server['free_space'] = int(response.text)
        mongo.db.servers.replace_one({'_id': server['_id']}, server)

    mongo.db.index.remove()
    return jsonify(get_min_free_space())
示例#3
0
    def put(self, path):
        """Update a file under a given path."""
        if 'file' not in request.files:
            abort(400, 'No file attached.')
        file = request.files['file']

        internal_path = validate_path(path)

        *parents, name = internal_path.parts
        parent = Path('/')
        entry = None
        for part in parents:
            entry = mongo.db.index.find_one({
                'name': part,
                'parent': str(parent)
            })
            if entry is None:
                mongo.db.index.insert_one({
                    'name': part,
                    'parent': str(parent),
                    'is_directory': True
                })
            parent /= part

        entry = mongo.db.index.find_one({'name': name, 'parent': str(parent)})
        if entry is not None:
            abort(400, 'A file with this name already exists.')

        ok_servers = []
        for server in mongo.db.servers.find():
            response = requests.post(
                f'http://{server["_id"]}/file/{internal_path}',
                files={'file': file.stream})
            if not response.ok:
                continue

            server['free_space'] = int(response.text)
            mongo.db.servers.replace_one({'_id': server['_id']}, server)
            ok_servers.append(server['_id'])

        mongo.db.index.replace_one({
            'name': name,
        }, {
            'name': name,
            'parent': str(parent),
            'is_directory': False,
            'size': get_file_size(file),
            'last_modified': int(time.time()),
            'servers': ok_servers,
        },
                                   upsert=True)

        return jsonify(get_min_free_space())
示例#4
0
def copy(path: str):
    """Copy the file to the specified location."""
    src_internal_path = validate_path(path)
    dst_internal_path = validate_path(request.json["destination"].lstrip('/'))

    src_parent = Path('/')
    src_entry = None
    for part in src_internal_path.parts:
        src_entry = mongo.db.index.find_one({
            'name': part,
            'parent': str(src_parent)
        })
        if src_entry is None:
            abort(404)
        src_parent /= part

    if src_entry is None or src_entry[
            'is_directory'] or not src_entry['servers']:
        abort(404)

    *dst_parents, dst_name = dst_internal_path.parts
    dst_parent = Path('/')
    dst_entry = None
    for part in dst_parents:
        dst_entry = mongo.db.index.find_one({
            'name': part,
            'parent': str(dst_parent)
        })
        if dst_entry is None:
            mongo.db.index.insert_one({
                'name': part,
                'parent': str(dst_parent),
                'is_directory': True
            })
        dst_parent /= part

    dst_entry = mongo.db.index.find_one({
        'name': dst_name,
        'parent': str(dst_parent)
    })
    if dst_entry is not None:
        abort(400, 'A file with this name already exists.')

    server = choose_server(among=src_entry['servers'])

    file = requests.get(f'http://{server}/file/{src_internal_path}')
    if not file.ok:
        abort(400, 'Copying failed.')

    ok_servers = []
    for server in mongo.db.servers.find():
        response = requests.post(
            f'http://{server["_id"]}/file/{str(dst_internal_path)}',
            files={'file': io.BytesIO(file.content)})
        if not response.ok:
            continue

        server['free_space'] = int(response.text)
        mongo.db.servers.replace_one({'_id': server['_id']}, server)
        ok_servers.append(server['_id'])

    mongo.db.index.insert_one({
        'name': dst_name,
        'parent': str(dst_parent),
        'is_directory': False,
        'size': len(file.content),
        'last_modified': int(time.time()),
        'servers': ok_servers,
    })

    return jsonify(get_min_free_space())
示例#5
0
def free_space():
    """Return the amount of free space among the storage servers."""
    return jsonify(get_min_free_space())