diff --git a/attract/modules.py b/attract/modules.py index a5b7427..109114a 100644 --- a/attract/modules.py +++ b/attract/modules.py @@ -20,7 +20,7 @@ def error_project_not_setup_for_attract(): return render_template('attract/errors/project_not_setup.html') -def attract_project_view(extra_project_projections=None): +def attract_project_view(extra_project_projections=None, extension_props=False): """Decorator, replaces the first parameter project_url with the actual project. Assumes the first parameter to the decorated function is 'project_url'. It then @@ -33,8 +33,14 @@ def attract_project_view(extra_project_projections=None): :param extra_project_projections: extra projections to use on top of the ones already used by this decorator. :type extra_project_projections: dict + :param extension_props: whether extension properties should be included. Includes them + in the projections, and verifies that they are there. + :type extension_props: bool """ + from .node_types.task import node_type_task + from . import EXTENSION_NAME + if callable(extra_project_projections): raise TypeError('Use with @attract_project_view() <-- note the parentheses') @@ -48,6 +54,8 @@ def attract_project_view(extra_project_projections=None): } if extra_project_projections: projections.update(extra_project_projections) + if extension_props: + projections['extension_props.%s' % EXTENSION_NAME] = 1 def decorator(wrapped): @functools.wraps(wrapped) @@ -59,12 +67,29 @@ def attract_project_view(extra_project_projections=None): {'projection': projections}, api=api) - node_type = project.get_node_type('attract_task') + node_type_name = node_type_task['name'] + node_type = project.get_node_type(node_type_name) if not node_type: - log.warning('createProject url=%s does not have node type attract.task', - project_url) + log.warning('createProject url=%s does not have node type %r', + project_url, node_type_name) return error_project_not_setup_for_attract() + if extension_props: + try: + pprops = project.extension_props.attract + except AttributeError: + log.warning("attract_project_view(%s): Project url=%r doesn't have any" + " extension properties.", wrapped, project_url) + if log.isEnabledFor(logging.DEBUG): + import pprint + log.debug('Project: %s', pprint.pformat(project.to_dict())) + return error_project_not_setup_for_attract() + + if pprops is None: + log.warning("attract_project_view(%s): Project url=%r doesn't have Attract" + " extension properties.", wrapped, project_url) + return error_project_not_setup_for_attract() + return wrapped(project, *args, **kwargs) return wrapper @@ -73,16 +98,11 @@ def attract_project_view(extra_project_projections=None): @blueprint.route('//subversion/kick') -@attract_project_view() +@attract_project_view(extension_props=True) def subversion_kick(project): from . import subversion - try: - pprops = project.extension_props.attract - except AttributeError: - log.warning("subversion_kick(): Project url=%s doesn't have Attract extension properties.", - project.url) - return error_project_not_setup_for_attract() + pprops = project.extension_props.attract svn_server_url = pprops.svn_url # 'svn://localhost/agent327' log.info('Re-examining SVN server %s', svn_server_url)