Page MenuHome
No OneTemporary

import itertools
import logging
from pillarsdk import Node
from pillarsdk import Project
from pillarsdk.exceptions import ResourceNotFound
from flask import abort
from flask import Blueprint
from flask import current_app
from flask import render_template
from flask import redirect
from flask import request
from flask_login import current_user
from werkzeug.contrib.atom import AtomFeed
from pillar.web.utils import system_util
from pillar.web.nodes.routes import url_for_node
from pillar.web.nodes.custom.posts import posts_view
from pillar.web.nodes.custom.posts import posts_create
from pillar.web.utils import attach_project_pictures
from pillar.web.utils import current_user_is_authenticated
from pillar.web.utils import get_file
blueprint = Blueprint('main', __name__)
log = logging.getLogger(__name__)
def homepage():
# Workaround to cache rendering of a page if user not logged in
def render_page():
return render_template('join.html')
if current_user.is_anonymous:
return render_page()
# Get latest blog posts
api = system_util.pillar_api()
latest_posts = Node.all({
'projection': {'name': 1, 'project': 1, 'node_type': 1,
'picture': 1, 'properties.status': 1, 'properties.url': 1},
'where': {'node_type': 'post', 'properties.status': 'published'},
'embedded': {'project': 1},
'sort': '-_created',
'max_results': '5'
}, api=api)
# Append picture Files to last_posts
for post in latest_posts._items:
post.picture = get_file(post.picture, api=api)
# Get latest assets added to any project
latest_assets = Node.latest('assets', api=api)
# Append picture Files to latest_assets
for asset in latest_assets._items:
asset.picture = get_file(asset.picture, api=api)
# Get latest comments to any node
latest_comments = Node.latest('comments', api=api)
# Get a list of random featured assets
random_featured = get_random_featured_nodes()
# Parse results for replies
to_remove = []
for idx, comment in enumerate(latest_comments._items):
comment.attached_to = Node.find(comment.parent.parent,
{'projection': {
'_id': 1,
'name': 1,
except ResourceNotFound:
# Remove this comment
comment.attached_to = comment.parent
for idx in reversed(to_remove):
del latest_comments._items[idx]
main_project = Project.find(current_app.config['MAIN_PROJECT_ID'], api=api)
main_project.picture_header = get_file(main_project.picture_header, api=api)
# Merge latest assets and comments into one activity stream.
def sort_key(item):
return item._created
activities = itertools.chain(latest_posts._items,
activity_stream = sorted(activities, key=sort_key, reverse=True)
return render_template(
# @blueprint.errorhandler(500)
# def error_500(e):
# return render_template('errors/500.html'), 500
# @blueprint.errorhandler(404)
# def error_404(e):
# return render_template('errors/404.html'), 404
# @blueprint.errorhandler(403)
# def error_404(e):
# return render_template('errors/403_embed.html'), 403
def join():
"""Join page"""
return redirect('')
def services():
"""Services page"""
return render_template('services.html')
def main_blog(url=None):
"""Blog with project news"""
project_id = current_app.config['MAIN_PROJECT_ID']
return posts_view(project_id, url=url)
def main_posts_create():
project_id = current_app.config['MAIN_PROJECT_ID']
return posts_create(project_id)
def project_blog(project_url, url=None):
"""View project blog"""
return posts_view(project_url=project_url, url=url)
def get_projects(category):
"""Utility to get projects based on category. Should be moved on the API
and improved with more extensive filtering capabilities.
api = system_util.pillar_api()
projects = Project.all({
'where': {
'category': category,
'is_private': False},
'sort': '-_created',
}, api=api)
for project in projects._items:
attach_project_pictures(project, api)
return projects
def get_random_featured_nodes():
import random
api = system_util.pillar_api()
projects = Project.all({
'projection': {'nodes_featured': 1},
'where': {'is_private': False},
'max_results': '15'
}, api=api)
featured_nodes = (p.nodes_featured for p in projects._items if p.nodes_featured)
featured_nodes = [item for sublist in featured_nodes for item in sublist]
if len(featured_nodes) > 3:
featured_nodes = random.sample(featured_nodes, 3)
featured_node_documents = []
for node in featured_nodes:
node_document = Node.find(node, {
'projection': {'name': 1, 'project': 1, 'picture': 1,
'properties.content_type': 1, 'properties.url': 1},
'embedded': {'project': 1}
}, api=api)
node_document.picture = get_file(node_document.picture, api=api)
return featured_node_documents
def open_projects():
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
def render_page():
projects = get_projects('film')
return render_template(
return render_page()
def training():
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
def render_page():
projects = get_projects('training')
return render_template(
return render_page()
def gallery():
return redirect('/p/gallery')
def redir_textures():
return redirect('/p/textures')
def redir_hdri():
return redirect('/p/hdri')
def caminandes():
return redirect('/p/caminandes-3')
def cf2():
return redirect('/p/creature-factory-2')
def redir_characters():
return redirect('/p/characters')
def vrview():
"""Call this from iframes to render sperical content (video and images)"""
if 'image' not in request.args:
return redirect('/')
return render_template('vrview.html')
def error_403():
"""Custom entry point to display the not allowed template"""
return render_template('errors/403_embed.html')
# Shameful redirects
def redirect_cloud_blog():
return redirect('/blog')
def feeds_blogs():
"""Global feed generator for latest blogposts across all projects"""
def render_page():
feed = AtomFeed('Blender Cloud - Latest updates',
feed_url=request.url, url=request.url_root)
# Get latest blog posts
api = system_util.pillar_api()
latest_posts = Node.all({
'where': {'node_type': 'post', 'properties.status': 'published'},
'embedded': {'user': 1},
'sort': '-_created',
'max_results': '15'
}, api=api)
# Populate the feed
for post in latest_posts._items:
author = post.user.fullname
updated = post._updated if post._updated else post._created
url = url_for_node(node=post)
content =[:500]
content = u'<p>{0}... <a href="{1}">Read more</a></p>'.format(content, url)
feed.add(, unicode(content),
return feed.get_response()
return render_page()
def nodes_search_index():
return render_template('nodes/search.html')

File Metadata

Mime Type
Mon, Sep 28, 12:10 PM (1 d, 23 h)
Storage Engine
Storage Format
Raw Data
Storage Handle

Event Timeline