Added project settings allowing setup + editing task types.

- Attract added to Project Settings screen
- setting up project for Attract
- editing shot/asset task types

To do: add checks that the user is allowed to use Attract in the first
place.
This commit is contained in:
2017-06-14 17:35:14 +02:00
parent 725f93175c
commit 9ea75c30e3
7 changed files with 252 additions and 14 deletions

View File

@@ -1,18 +1,21 @@
import functools
import logging
from flask import Blueprint, render_template, redirect, url_for
from flask import Blueprint, render_template, redirect, url_for, request, jsonify
import flask_login
import werkzeug.exceptions as wz_exceptions
from pillar.auth import current_web_user as current_user
from pillar.web.utils import attach_project_pictures
import pillar.web.subquery
from pillar.web.system_util import pillar_api
from pillar.web.projects.routes import project_view
import pillarsdk
from attract import current_attract
from attract.node_types.task import node_type_task
from attract.node_types.shot import node_type_shot
from attract.node_types.asset import node_type_asset
blueprint = Blueprint('attract', __name__)
log = logging.getLogger(__name__)
@@ -38,7 +41,7 @@ def index():
projs_with_summaries = [
(proj, current_attract.shot_manager.shot_status_summary(proj['_id']))
for proj in projects['_items']
]
]
# Fetch all activities for all Attract projects.
id_to_proj = {p['_id']: p for p in projects['_items']}
@@ -137,8 +140,8 @@ def attract_project_view(extra_project_projections=None, extension_props=False):
@blueprint.route('/<project_url>')
@attract_project_view(extension_props=True)
def project_index(project, attract_props):
@attract_project_view(extension_props=False)
def project_index(project):
return redirect(url_for('attract.shots.perproject.index', project_url=project.url))
@@ -152,3 +155,88 @@ def help(project):
nt_shot['dyn_schema']['status']['allowed'])
return render_template('attract/help.html', statuses=statuses)
def project_settings(project: pillarsdk.Project, **template_args: dict):
"""Renders the project settings page for Attract projects."""
from . import EXTENSION_NAME
# Based on the project state, we can render a different template.
if not current_attract.is_attract_project(project):
return render_template('attract/project_settings/offer_setup.html',
project=project, **template_args)
ntn_shot = node_type_shot['name']
ntn_asset = node_type_asset['name']
try:
attract_props = project['extension_props'][EXTENSION_NAME]
except KeyError:
# Not set up for attract, can happen.
shot_task_types = []
asset_task_types = []
else:
shot_task_types = attract_props['task_types'][ntn_shot]
asset_task_types = attract_props['task_types'][ntn_asset]
return render_template('attract/project_settings/settings.html',
project=project,
asset_node_type_name=ntn_asset,
shot_node_type_name=ntn_shot,
shot_task_types=shot_task_types,
asset_task_types=asset_task_types,
**template_args)
@blueprint.route('/<project_url>/<node_type_name>/set-task-types', methods=['POST'])
@attract_project_view(extension_props=True)
def save_task_types(project, attract_props, node_type_name: str):
from . import EXTENSION_NAME
from . import setup
import re
from collections import OrderedDict
valid_name_re = re.compile(r'^[0-9a-zA-Z &+\-.,_]+$')
if (not node_type_name.startswith('%s_' % EXTENSION_NAME)
or node_type_name not in attract_props['task_types']
or not valid_name_re.match(node_type_name)):
log.info('%s: received invalid node type name %r', request.endpoint, node_type_name)
raise wz_exceptions.BadRequest('Invalid node type name')
task_types_field = request.form.get('task_types')
if not task_types_field:
raise wz_exceptions.BadRequest('No task types given')
task_types = [
tt for tt in (tt.strip()
for tt in task_types_field.split('\n'))
if tt
]
task_types = list(OrderedDict.fromkeys(task_types)) # removes duplicates, maintains order.
if not all(valid_name_re.match(tt) for tt in task_types):
raise wz_exceptions.BadRequest('Invalid task type given')
setup.set_task_types(project.to_dict(), node_type_name, task_types)
return jsonify(task_types=task_types)
@blueprint.route('/<project_url>/setup-for-attract', methods=['POST'])
@flask_login.login_required
@project_view()
def setup_for_attract(project: pillarsdk.Project):
import attract.setup
project_id = project._id
if not project.has_method('PUT'):
log.warning('User %s tries to set up project %s for Attract, but has no PUT rights.',
current_user, project_id)
raise wz_exceptions.Forbidden()
log.info('User %s sets up project %s for Attract', current_user, project_id)
attract.setup.setup_for_attract(project.url)
return '', 204