Now we organize training content into 'courses' and 'workshops'. This commit updates various endpoints and menus to reflect that decision.
201 lines
6.2 KiB
Python
201 lines
6.2 KiB
Python
import itertools
|
|
import logging
|
|
|
|
from pillarsdk import Node, Project
|
|
from pillarsdk.exceptions import ResourceNotFound
|
|
from flask_login import current_user
|
|
from flask import Blueprint, current_app, render_template, redirect, url_for
|
|
from pillar.web.utils import system_util, get_file, current_user_is_authenticated
|
|
from pillar.web.utils import attach_project_pictures
|
|
|
|
blueprint = Blueprint('cloud', __name__)
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
@blueprint.route('/')
|
|
def homepage():
|
|
|
|
if current_user.is_anonymous:
|
|
return redirect(url_for('cloud.welcome'))
|
|
|
|
# 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):
|
|
if comment.properties.is_reply:
|
|
try:
|
|
comment.attached_to = Node.find(comment.parent.parent,
|
|
{'projection': {
|
|
'_id': 1,
|
|
'name': 1,
|
|
}},
|
|
api=api)
|
|
except ResourceNotFound:
|
|
# Remove this comment
|
|
to_remove.append(idx)
|
|
else:
|
|
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_assets._items,
|
|
latest_comments._items)
|
|
activity_stream = sorted(activities, key=sort_key, reverse=True)
|
|
|
|
return render_template(
|
|
'homepage.html',
|
|
main_project=main_project,
|
|
latest_posts=latest_posts._items,
|
|
activity_stream=activity_stream,
|
|
random_featured=random_featured,
|
|
api=api)
|
|
|
|
|
|
@blueprint.route('/welcome')
|
|
def welcome():
|
|
# Workaround to cache rendering of a page if user not logged in
|
|
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
|
|
def render_page():
|
|
return render_template('welcome.html')
|
|
return render_page()
|
|
|
|
|
|
@blueprint.route('/about')
|
|
def about():
|
|
return render_template('about.html')
|
|
|
|
|
|
@blueprint.route('/services')
|
|
def services():
|
|
return render_template('services.html')
|
|
|
|
|
|
@blueprint.route('/join')
|
|
def join():
|
|
"""Join page"""
|
|
return redirect('https://store.blender.org/product/membership/')
|
|
|
|
|
|
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
|
|
|
|
|
|
@blueprint.route('/courses')
|
|
def courses():
|
|
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
|
|
def render_page():
|
|
projects = get_projects('course')
|
|
return render_template(
|
|
'projects_index_collection.html',
|
|
title='courses',
|
|
projects=projects._items,
|
|
api=system_util.pillar_api())
|
|
|
|
return render_page()
|
|
|
|
|
|
@blueprint.route('/open-projects')
|
|
def open_projects():
|
|
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
|
|
def render_page():
|
|
projects = get_projects('film')
|
|
return render_template(
|
|
'projects_index_collection.html',
|
|
title='open-projects',
|
|
projects=projects._items,
|
|
api=system_util.pillar_api())
|
|
|
|
return render_page()
|
|
|
|
|
|
@blueprint.route('/workshops')
|
|
def workshops():
|
|
@current_app.cache.cached(timeout=3600, unless=current_user_is_authenticated)
|
|
def render_page():
|
|
projects = get_projects('workshop')
|
|
return render_template(
|
|
'projects_index_collection.html',
|
|
title='workshops',
|
|
projects=projects._items,
|
|
api=system_util.pillar_api())
|
|
|
|
return render_page()
|
|
|
|
|
|
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)
|
|
featured_node_documents.append(node_document)
|
|
|
|
return featured_node_documents
|