Introducing Pillar Framework
Refactor of pillar-server and pillar-web into a single python package. This simplifies the overall architecture of pillar applications. Special thanks @sybren and @venomgfx
This commit is contained in:
128
pillar/api/latest.py
Normal file
128
pillar/api/latest.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import itertools
|
||||
|
||||
import pymongo
|
||||
from flask import Blueprint, current_app
|
||||
|
||||
from pillar.api.utils import jsonify
|
||||
|
||||
blueprint = Blueprint('latest', __name__)
|
||||
|
||||
|
||||
def keep_fetching(collection, db_filter, projection, sort, py_filter,
|
||||
batch_size=12):
|
||||
"""Yields results for which py_filter returns True"""
|
||||
|
||||
projection['_deleted'] = 1
|
||||
curs = collection.find(db_filter, projection).sort(sort)
|
||||
curs.batch_size(batch_size)
|
||||
|
||||
for doc in curs:
|
||||
if doc.get('_deleted'):
|
||||
continue
|
||||
doc.pop('_deleted', None)
|
||||
if py_filter(doc):
|
||||
yield doc
|
||||
|
||||
|
||||
def latest_nodes(db_filter, projection, py_filter, limit):
|
||||
nodes = current_app.data.driver.db['nodes']
|
||||
|
||||
proj = {
|
||||
'_created': 1,
|
||||
'_updated': 1,
|
||||
}
|
||||
proj.update(projection)
|
||||
|
||||
latest = keep_fetching(nodes, db_filter, proj,
|
||||
[('_created', pymongo.DESCENDING)],
|
||||
py_filter, limit)
|
||||
|
||||
result = list(itertools.islice(latest, limit))
|
||||
return result
|
||||
|
||||
|
||||
def has_public_project(node_doc):
|
||||
"""Returns True iff the project the node belongs to is public."""
|
||||
|
||||
project_id = node_doc.get('project')
|
||||
return is_project_public(project_id)
|
||||
|
||||
|
||||
# TODO: cache result, for a limited amt. of time, or for this HTTP request.
|
||||
def is_project_public(project_id):
|
||||
"""Returns True iff the project is public."""
|
||||
|
||||
project = current_app.data.driver.db['projects'].find_one(project_id)
|
||||
if not project:
|
||||
return False
|
||||
|
||||
return not project.get('is_private')
|
||||
|
||||
|
||||
@blueprint.route('/assets')
|
||||
def latest_assets():
|
||||
latest = latest_nodes({'node_type': 'asset',
|
||||
'properties.status': 'published'},
|
||||
{'name': 1, 'project': 1, 'user': 1, 'node_type': 1,
|
||||
'parent': 1, 'picture': 1, 'properties.status': 1,
|
||||
'properties.content_type': 1,
|
||||
'permissions.world': 1},
|
||||
has_public_project, 12)
|
||||
|
||||
embed_user(latest)
|
||||
embed_project(latest)
|
||||
|
||||
return jsonify({'_items': latest})
|
||||
|
||||
|
||||
def embed_user(latest):
|
||||
users = current_app.data.driver.db['users']
|
||||
|
||||
for comment in latest:
|
||||
user_id = comment['user']
|
||||
comment['user'] = users.find_one(user_id, {
|
||||
'auth': 0, 'groups': 0, 'roles': 0, 'settings': 0, 'email': 0,
|
||||
'_created': 0, '_updated': 0, '_etag': 0})
|
||||
|
||||
|
||||
def embed_project(latest):
|
||||
projects = current_app.data.driver.db['projects']
|
||||
|
||||
for comment in latest:
|
||||
project_id = comment['project']
|
||||
comment['project'] = projects.find_one(project_id, {'_id': 1, 'name': 1,
|
||||
'url': 1})
|
||||
|
||||
|
||||
@blueprint.route('/comments')
|
||||
def latest_comments():
|
||||
latest = latest_nodes({'node_type': 'comment',
|
||||
'properties.status': 'published'},
|
||||
{'project': 1, 'parent': 1, 'user': 1,
|
||||
'properties.content': 1, 'node_type': 1,
|
||||
'properties.status': 1,
|
||||
'properties.is_reply': 1},
|
||||
has_public_project, 6)
|
||||
|
||||
# Embed the comments' parents.
|
||||
nodes = current_app.data.driver.db['nodes']
|
||||
parents = {}
|
||||
for comment in latest:
|
||||
parent_id = comment['parent']
|
||||
|
||||
if parent_id in parents:
|
||||
comment['parent'] = parents[parent_id]
|
||||
continue
|
||||
|
||||
parent = nodes.find_one(parent_id)
|
||||
parents[parent_id] = parent
|
||||
comment['parent'] = parent
|
||||
|
||||
embed_project(latest)
|
||||
embed_user(latest)
|
||||
|
||||
return jsonify({'_items': latest})
|
||||
|
||||
|
||||
def setup_app(app, url_prefix):
|
||||
app.register_api_blueprint(blueprint, url_prefix=url_prefix)
|
Reference in New Issue
Block a user