Added entry point /p/<project_id>/quotas

At the moment this entry point only returns the total file size of all
files belonging to the project. It can be extended to return more info,
such as nr. of nodes/groups/etc.
This commit is contained in:
Sybren A. Stüvel 2016-05-06 12:04:22 +02:00
parent bbc30b9d99
commit 6f193da89d
2 changed files with 63 additions and 2 deletions

View File

@ -0,0 +1,27 @@
"""Utility functions for MongoDB stuff."""
from bson import ObjectId
from flask import current_app
from werkzeug.exceptions import NotFound
def find_one_or_404(collection_name, object_id):
"""Returns the found object from the collection, or raises a NotFound exception.
:param collection_name: name of the collection, such as 'users' or 'files'
:type collection_name: str
:param object_id: ID of the object to find.
:type object_id: str or bson.ObjectId
:returns: the found object
:rtype: dict
:raises: werkzeug.exceptions.NotFound
"""
collection = current_app.data.driver.db[collection_name]
found = collection.find_one(ObjectId(object_id))
if found is None:
raise NotFound()
return found

View File

@ -7,9 +7,10 @@ from eve.methods.post import post_internal
from eve.methods.patch import patch_internal
from flask import g, Blueprint, request, abort, current_app
from application.modules import mongo_utils
from application.utils import remove_private_keys, authorization, jsonify
from application.utils.gcs import GoogleCloudStorageBucket
from application.utils.authorization import user_has_role, check_permissions
from application.utils.authorization import user_has_role, check_permissions, require_login
from manage_extra.node_types.asset import node_type_asset
from manage_extra.node_types.comment import node_type_comment
from manage_extra.node_types.group import node_type_group
@ -49,7 +50,6 @@ def before_inserting_override_is_private_field(projects):
def before_edit_check_permissions(document, original):
# Allow admin users to do whatever they want.
# TODO: possibly move this into the check_permissions function.
if user_has_role(u'admin'):
@ -316,6 +316,40 @@ def abort_with_error(status):
abort(status if status // 100 >= 4 else 500)
@blueprint.route('/<string:project_id>/quotas')
@require_login()
def project_quotas(project_id):
"""Returns information about the project's limits."""
# Check that the user has GET permissions on the project itself.
project = mongo_utils.find_one_or_404('projects', project_id)
check_permissions(project, 'GET')
file_size_used = _project_total_file_size(project_id)
info = {
'file_size_quota': None, # TODO: implement this later.
'file_size_used': file_size_used,
}
return jsonify(info)
def _project_total_file_size(project_id):
"""Returns the total number of bytes used by files of this project."""
files = current_app.data.driver.db['files']
file_size_used = files.aggregate([
{'$match': {'project': ObjectId(project_id)}},
{'$project': {'length_aggregate_in_bytes': 1}},
{'$group': {'_id': None,
'all_files': {'$sum': '$length_aggregate_in_bytes'}}}
])
# The aggregate function returns a cursor, not a document.
return next(file_size_used)['all_files']
def setup_app(app, url_prefix):
app.on_replace_projects += override_is_private_field
app.on_replace_projects += before_edit_check_permissions