Introducing endpoint for stats

This endpoint can be queried on a daily basis to retrieve cloud usage  stats. For assets and comments we take into considerations only those who belong to public projects.
This commit is contained in:
2017-03-17 09:40:50 +01:00
parent 59ffebd33e
commit e09c73ec39
3 changed files with 110 additions and 1 deletions

View File

@@ -49,7 +49,11 @@ class CloudExtension(PillarExtension):
:rtype: list of flask.Blueprint objects.
"""
from . import routes
return [routes.blueprint]
import cloud.stats.routes
return [
routes.blueprint,
cloud.stats.routes.blueprint,
]
@property
def template_path(self):

47
cloud/stats/__init__.py Normal file
View File

@@ -0,0 +1,47 @@
"""Interesting usage metrics"""
from flask import current_app
pipeline = [
{'$match': {'_deleted': {'$ne': 'true'}}},
{
'$lookup':
{
'from': "projects",
'localField': "project",
'foreignField': "_id",
'as': "project",
}
},
{
'$unwind':
{
'path': '$project',
}
},
{
'$project':
{
'p.is_private': 1,
}
},
{'$match': {'p.is_private': {'$ne': True}}},
{'$count': 'tot'}
]
def count_nodes(query=None) -> int:
c = current_app.db()['nodes']
# If we provide a query, we extend the first $match step in the aggregation pipeline with
# with the extra parameters (for example node_type)
if query:
pipeline[0]['$match'].update(query)
# Return either a list with one item or an empty list
r = list(c.aggregate(pipeline=pipeline))
count = 0 if not r else r[0]['tot']
return count
def count_users() -> int:
u = current_app.db()['users']
return u.count()

58
cloud/stats/routes.py Normal file
View File

@@ -0,0 +1,58 @@
import logging
import datetime
import functools
from flask import Blueprint, jsonify
from cloud.stats import count_nodes, count_users
blueprint = Blueprint('cloud.stats', __name__, url_prefix='/s')
log = logging.getLogger(__name__)
@functools.lru_cache()
def get_stats(before: datetime.datetime):
query_comments = {'node_type': 'comment'}
query_assets = {'node_type': 'asset'}
# TODO Actually query per home project (and 1 blend per project)
query_user_blender_sync = {'name': 'startup.blend'}
if before:
d = {'_created': {'$lt': before}}
query_comments.update(d)
query_assets.update(d)
query_user_blender_sync.update(d)
stats = {
'comments': count_nodes(query_comments),
'assets': count_nodes(query_assets),
'users_total': count_users(),
'users_blender_sync': count_nodes(query_user_blender_sync),
}
return stats
@blueprint.route('/')
@blueprint.route('/before/<int:before>')
def index(before: int=0):
"""
This endpoint is queried on a daily basis by grafista to retrieve cloud usage
stats. For assets and comments we take into considerations only those who belong
to public projects.
These is the data we retrieve
- Comments count
- Assets count (video, images and files)
- Users count (subscribers count goes via store)
- Blender Sync users
"""
# TODO: Implement project-level metrics (and update ad every child update)
if before:
before = datetime.datetime.strptime(before, '%Y%m%d')
else:
today = datetime.date.today()
before = datetime.datetime(today.year, today.month, today.day)
return jsonify(get_stats(before))