diff --git a/CHANGES.rst b/CHANGES.rst
index 4e21113..4ce934a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,16 @@ Changelog
2.1.3 (unreleased)
------------------
+- Python 3 compatibility.
+ [thet]
+
+- Code cleanup:
+ - Remove bootstrap.py
+ - Format code according to Plone standards: black, isort.
+ Format zcml using zpretty.
+ Format xml using zpretty.
+ [thet]
+
- update to build on Plone 5.1 latest
[tkimnguyen]
diff --git a/base.cfg b/base.cfg
index 2c001d0..21ce67f 100644
--- a/base.cfg
+++ b/base.cfg
@@ -23,7 +23,7 @@ eggs = plone.app.workflowmanager
[code-analysis]
recipe = plone.recipe.codeanalysis
directory = ${buildout:directory}/src/plone/app/workflowmanager/
-flake8-exclude = bootstrap.py,bootstrap-buildout.py,docs,*.egg.,omelette
+flake8-exclude = docs,*.egg.,omelette
flake8-max-complexity = 15
diff --git a/bootstrap.py b/bootstrap.py
deleted file mode 100644
index daeeef5..0000000
--- a/bootstrap.py
+++ /dev/null
@@ -1,127 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-
-$Id$
-"""
-
-import os, shutil, sys, tempfile, urllib2
-from optparse import OptionParser
-
-tmpeggs = tempfile.mkdtemp()
-
-is_jython = sys.platform.startswith('java')
-
-# parsing arguments
-parser = OptionParser(
- 'This is a custom version of the zc.buildout %prog script. It is '
- 'intended to meet a temporary need if you encounter problems with '
- 'the zc.buildout 1.5 release.')
-parser.add_option("-v", "--version", dest="version", default='1.4.4',
- help='Use a specific zc.buildout version. *This '
- 'bootstrap script defaults to '
- '1.4.4, unlike usual buildpout bootstrap scripts.*')
-parser.add_option("-d", "--distribute",
- action="store_true", dest="distribute", default=False,
- help="Use Disribute rather than Setuptools.")
-
-parser.add_option("-c", None, action="store", dest="config_file",
- help=("Specify the path to the buildout configuration "
- "file to be used."))
-
-options, args = parser.parse_args()
-
-# if -c was provided, we push it back into args for buildout' main function
-if options.config_file is not None:
- args += ['-c', options.config_file]
-
-if options.version is not None:
- VERSION = '==%s' % options.version
-else:
- VERSION = ''
-
-USE_DISTRIBUTE = options.distribute
-args = args + ['bootstrap']
-
-to_reload = False
-try:
- import pkg_resources
- if not hasattr(pkg_resources, '_distribute'):
- to_reload = True
- raise ImportError
-except ImportError:
- ez = {}
- if USE_DISTRIBUTE:
- exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
- ).read() in ez
- ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
- else:
- exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
- ).read() in ez
- ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
-
- if to_reload:
- reload(pkg_resources)
- else:
- import pkg_resources
-
-if sys.platform == 'win32':
- def quote(c):
- if ' ' in c:
- return '"%s"' % c # work around spawn lamosity on windows
- else:
- return c
-else:
- def quote (c):
- return c
-
-ws = pkg_resources.working_set
-
-if USE_DISTRIBUTE:
- requirement = 'distribute'
-else:
- requirement = 'setuptools'
-
-env = dict(os.environ,
- PYTHONPATH=
- ws.find(pkg_resources.Requirement.parse(requirement)).location
- )
-
-cmd = [quote(sys.executable),
- '-c',
- quote('from setuptools.command.easy_install import main; main()'),
- '-mqNxd',
- quote(tmpeggs)]
-
-if 'bootstrap-testing-find-links' in os.environ:
- cmd.extend(['-f', os.environ['bootstrap-testing-find-links']])
-
-cmd.append('zc.buildout' + VERSION)
-
-if is_jython:
- import subprocess
- exitcode = subprocess.Popen(cmd, env=env).wait()
-else: # Windows prefers this, apparently; otherwise we would prefer subprocess
- exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
-assert exitcode == 0
-
-ws.add_entry(tmpeggs)
-ws.require('zc.buildout' + VERSION)
-import zc.buildout.buildout
-zc.buildout.buildout.main(args)
-shutil.rmtree(tmpeggs)
diff --git a/setup.py b/setup.py
index 4a4ed1b..50c91f5 100644
--- a/setup.py
+++ b/setup.py
@@ -1,58 +1,58 @@
from setuptools import find_packages
from setuptools import setup
-version = '2.1.3.dev0'
-setup(name='plone.app.workflowmanager',
- version=version,
- description="A workflow manager for Plone",
- long_description=(
- open("README.rst").read() + "\n" +
- open("CHANGES.rst").read()
- ),
- # Get more strings from https://pypi.python.org/pypi?%3Aaction=list_classifiers
- classifiers=[
- "Framework :: Plone",
- "Framework :: Plone :: 4.3",
- "Framework :: Plone :: 5.0",
- "Framework :: Plone :: 5.1",
- "Intended Audience :: Customer Service",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: GNU General Public License (GPL)",
- "Operating System :: OS Independent",
- "Programming Language :: Other Scripting Engines",
- "Programming Language :: Python",
- "Topic :: Internet :: WWW/HTTP :: Site Management",
- "Topic :: Software Development :: Libraries :: Python Modules",
- ],
- keywords='plone workflow manager gui',
- author='Nathan Van Gheem',
- author_email='nguyen@plone.org',
- url='https://github.com/plone/plone.app.workflowmanager',
- license='GPL',
- packages=find_packages('src'),
- package_dir={'': 'src'},
- namespace_packages=['plone', 'plone.app'],
- include_package_data=True,
- zip_safe=False,
- install_requires=[
- 'Plone',
- 'setuptools',
- 'plone.api',
- 'plone.app.jquery>=1.7',
- 'plone.app.jquerytools',
- ],
- extras_require={
- 'test': [
- 'plone.app.testing',
- 'plone.app.jquerytools',
- 'plone.app.robotframework',
- 'interlude',
- 'unittest2',
- ]
- },
- entry_points="""
+version = "2.1.3.dev0"
+
+setup(
+ name="plone.app.workflowmanager",
+ version=version,
+ description="A workflow manager for Plone",
+ long_description=(open("README.rst").read() + "\n" + open("CHANGES.rst").read()),
+ # Get more strings from https://pypi.python.org/pypi?%3Aaction=list_classifiers
+ classifiers=[
+ "Framework :: Plone",
+ "Framework :: Plone :: 4.3",
+ "Framework :: Plone :: 5.0",
+ "Framework :: Plone :: 5.1",
+ "Framework :: Plone :: 5.2",
+ "Intended Audience :: Customer Service",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: GNU General Public License (GPL)",
+ "Operating System :: OS Independent",
+ "Programming Language :: Other Scripting Engines",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Topic :: Internet :: WWW/HTTP :: Site Management",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ ],
+ keywords="plone workflow manager gui",
+ author="Nathan Van Gheem",
+ author_email="nguyen@plone.org",
+ url="https://github.com/plone/plone.app.workflowmanager",
+ license="GPL",
+ packages=find_packages("src"),
+ package_dir={"": "src"},
+ namespace_packages=["plone", "plone.app"],
+ include_package_data=True,
+ zip_safe=False,
+ install_requires=[
+ "Plone",
+ "setuptools",
+ "plone.api",
+ ],
+ extras_require={
+ "test": [
+ "plone.app.testing",
+ "plone.app.robotframework",
+ "interlude",
+ ]
+ },
+ entry_points="""
[z3c.autoinclude.plugin]
target = plone
""",
- )
+)
diff --git a/src/plone/__init__.py b/src/plone/__init__.py
index f48ad10..05f0beb 100644
--- a/src/plone/__init__.py
+++ b/src/plone/__init__.py
@@ -1,6 +1,7 @@
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
- __import__('pkg_resources').declare_namespace(__name__)
+ __import__("pkg_resources").declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
+
__path__ = extend_path(__path__, __name__)
diff --git a/src/plone/app/__init__.py b/src/plone/app/__init__.py
index f48ad10..05f0beb 100644
--- a/src/plone/app/__init__.py
+++ b/src/plone/app/__init__.py
@@ -1,6 +1,7 @@
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
- __import__('pkg_resources').declare_namespace(__name__)
+ __import__("pkg_resources").declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
+
__path__ = extend_path(__path__, __name__)
diff --git a/src/plone/app/workflowmanager/__init__.py b/src/plone/app/workflowmanager/__init__.py
index c32d387..f6f961a 100644
--- a/src/plone/app/workflowmanager/__init__.py
+++ b/src/plone/app/workflowmanager/__init__.py
@@ -1,3 +1,4 @@
-#
from zope.i18nmessageid.message import MessageFactory
-WMMessageFactory = MessageFactory('plone.app.workflowmanager')
\ No newline at end of file
+
+
+WMMessageFactory = MessageFactory("plone.app.workflowmanager")
diff --git a/src/plone/app/workflowmanager/actionmanager.py b/src/plone/app/workflowmanager/actionmanager.py
index 6d7f022..b3876c7 100644
--- a/src/plone/app/workflowmanager/actionmanager.py
+++ b/src/plone/app/workflowmanager/actionmanager.py
@@ -1,23 +1,23 @@
-from zope.component import queryUtility
-
-from plone.memoize.instance import memoize
-from plone.contentrules.engine.interfaces import IRuleStorage
-from plone.contentrules.engine.interfaces import IRuleAssignmentManager
-from plone.app.contentrules.conditions.wftransition import \
- WorkflowTransitionCondition
+from plone.app.contentrules.conditions.wftransition import WorkflowTransitionCondition
+from plone.app.contentrules.rule import get_assignments
+from plone.app.contentrules.rule import Rule
+from plone.app.workflowmanager.utils import generateRuleName
+from plone.app.workflowmanager.utils import generateRuleNameOld
from plone.contentrules.engine import utils
-from plone.app.contentrules.rule import Rule, get_assignments
from plone.contentrules.engine.assignments import RuleAssignment
+from plone.contentrules.engine.interfaces import IRuleAssignmentManager
+from plone.contentrules.engine.interfaces import IRuleStorage
+from plone.memoize.instance import memoize
from Products.CMFCore.interfaces._events import IActionSucceededEvent
from Products.CMFCore.utils import getToolByName
-from plone.app.workflowmanager.utils import generateRuleName, generateRuleNameOld
-
+from zope.component import queryUtility
from zope.i18nmessageid import MessageFactory
+
+
_ = MessageFactory(u"plone")
class RuleAdapter(object):
-
def __init__(self, rule, transition):
self.rule = rule
self.transition = transition
@@ -25,7 +25,7 @@ def __init__(self, rule, transition):
@property
@memoize
def portal(self):
- return getToolByName(self.transition, 'portal_url').getPortalObject()
+ return getToolByName(self.transition, "portal_url").getPortalObject()
def activate(self):
"""
@@ -39,9 +39,10 @@ def activate(self):
self.rule.event = IActionSucceededEvent
assignable = IRuleAssignmentManager(self.portal)
- path = '/'.join(self.portal.getPhysicalPath())
- assignable[self.rule.__name__] = RuleAssignment(self.rule.id,
- enabled=True, bubbles=True)
+ path = "/".join(self.portal.getPhysicalPath())
+ assignable[self.rule.__name__] = RuleAssignment(
+ self.rule.id, enabled=True, bubbles=True
+ )
assignments = get_assignments(self.rule)
if not path in assignments:
assignments.insert(path)
@@ -57,10 +58,11 @@ def action_index(self, action):
return self.rule.actions.index(action)
def action_url(self, action):
- return '%s/%s/++action++%d/edit' % (
+ return "%s/%s/++action++%d/edit" % (
self.portal.absolute_url(),
self.rule.id,
- self.action_index(action), )
+ self.action_index(action),
+ )
def delete_action(self, index):
self.rule.actions.remove(self.rule.actions[index])
@@ -71,7 +73,6 @@ def actions(self):
class ActionManager(object):
-
def get_rule(self, transition):
rulename = generateRuleName(transition)
rulename_old = generateRuleNameOld(transition)
@@ -87,11 +88,13 @@ def create(self, transition):
rule_id = generateRuleName(transition)
r = Rule()
r.title = _(u"%s transition content rule") % transition.id
- r.description = _(u"This content rule was automatically created "
- u"the workflow manager to create actions on "
- u"workflow events. If you want the behavior to "
- u"work as expected, do not modify this out of "
- u"the workflow manager.")
+ r.description = _(
+ u"This content rule was automatically created "
+ u"the workflow manager to create actions on "
+ u"workflow events. If you want the behavior to "
+ u"work as expected, do not modify this out of "
+ u"the workflow manager."
+ )
self.storage[rule_id] = r
rule = RuleAdapter(r, transition)
rule.activate()
diff --git a/src/plone/app/workflowmanager/browser/actions.py b/src/plone/app/workflowmanager/browser/actions.py
index f45121e..53d2f0b 100644
--- a/src/plone/app/workflowmanager/browser/actions.py
+++ b/src/plone/app/workflowmanager/browser/actions.py
@@ -1,27 +1,31 @@
-from controlpanel import Base
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from .controlpanel import Base
from plone.app.contentrules.rule import Rule
-from plone.app.workflowmanager.actionmanager import RuleAdapter, ActionManager
-from urllib import urlencode
-from zope.i18nmessageid import MessageFactory
+from plone.app.workflowmanager.actionmanager import ActionManager
+from plone.app.workflowmanager.actionmanager import RuleAdapter
from plone.app.workflowmanager.utils import generateRuleName
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from six.moves.urllib.parse import urlencode
+from zope.i18nmessageid import MessageFactory
+
+
_ = MessageFactory(u"plone")
class DeleteActionView(Base):
- template = ViewPageTemplateFile('templates/delete-action.pt')
+ template = ViewPageTemplateFile("templates/delete-action.pt")
def __call__(self):
self.errors = {}
- if self.request.get('form.actions.delete', False):
+ if self.request.get("form.actions.delete", False):
self.authorize()
rule = self.actions.get_rule(self.selected_transition)
- rule.delete_action(int(self.request.get('action_index')))
+ rule.delete_action(int(self.request.get("action_index")))
return self.handle_response(
- message=_(u"Action has been deleted successfully."))
+ message=_(u"Action has been deleted successfully.")
+ )
- elif self.request.get('form.actions.cancel', False):
+ elif self.request.get("form.actions.cancel", False):
return self.handle_response()
else:
return self.handle_response(tmpl=self.template)
@@ -29,20 +33,19 @@ def __call__(self):
class AddActionView(Base):
- template = ViewPageTemplateFile('templates/add-action.pt')
+ template = ViewPageTemplateFile("templates/add-action.pt")
def __call__(self):
self.errors = {}
- if self.request.get('form.actions.add', False):
+ if self.request.get("form.actions.add", False):
self.authorize()
am = ActionManager()
rule = am.get_rule(self.selected_transition)
if rule is None:
rule_id = generateRuleName(self.selected_transition)
r = Rule()
- r.title = u"%s transition content rule" % (
- self.selected_transition.id)
+ r.title = u"%s transition content rule" % (self.selected_transition.id)
r.description = """This content rule was automatically created
by the workflow manager to support actions on workflow transitions. If you want
the behavior to work as expected, do not modify this outside of the workflow
@@ -51,12 +54,14 @@ def __call__(self):
rule = RuleAdapter(r, self.selected_transition)
rule.activate()
- editurl = '%s/%s/+action' % (self.portal.absolute_url(), rule.id)
- data = urlencode({
- ':action': self.request.get('action-type',
- 'plone.actions.Mail'),
- 'form.button.AddAction': 'Add'})
+ editurl = "%s/%s/+action" % (self.portal.absolute_url(), rule.id)
+ data = urlencode(
+ {
+ ":action": self.request.get("action-type", "plone.actions.Mail"),
+ "form.button.AddAction": "Add",
+ }
+ )
- return self.handle_response(load=editurl + '?' + data)
+ return self.handle_response(load=editurl + "?" + data)
else:
return self.handle_response(tmpl=self.template)
diff --git a/src/plone/app/workflowmanager/browser/configure.zcml b/src/plone/app/workflowmanager/browser/configure.zcml
index c028acd..841a16d 100644
--- a/src/plone/app/workflowmanager/browser/configure.zcml
+++ b/src/plone/app/workflowmanager/browser/configure.zcml
@@ -2,197 +2,205 @@
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:zcml="http://namespaces.zope.org/zcml"
- i18n_domain="plone.app.workflowmanager">
-
-
-
-
-
-
-
-
+ i18n_domain="plone.app.workflowmanager"
+ >
+
+
+ name="workflowmanager-content"
+ attribute="render_content_template"
+ />
+ name="workflowmanage-item"
+ attribute="retrieve_item"
+ />
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+ class=".workflow.UpdateSecuritySettings"
+ />
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ class=".actions.DeleteActionView"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plone/app/workflowmanager/browser/controlpanel.py b/src/plone/app/workflowmanager/browser/controlpanel.py
index 30eeab3..3a57a41 100644
--- a/src/plone/app/workflowmanager/browser/controlpanel.py
+++ b/src/plone/app/workflowmanager/browser/controlpanel.py
@@ -1,39 +1,45 @@
-from urllib import urlencode
-try:
- import json
-except:
- import simplejson as json
-
-from Acquisition import aq_get
from AccessControl import Unauthorized
+from Acquisition import aq_get
+from plone.app.workflowmanager import WMMessageFactory as _
+from plone.app.workflowmanager.actionmanager import ActionManager
+from plone.app.workflowmanager.browser.layout import GraphLayout
+from plone.app.workflowmanager.graphviz import HAS_GRAPHVIZ
+from plone.app.workflowmanager.permissions import allowed_guard_permissions
+from plone.app.workflowmanager.permissions import managed_permissions
+from plone.memoize.view import memoize
+from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-
-from zope.component import getUtility
+from six.moves.urllib.parse import urlencode
from zope.component import getMultiAdapter
+from zope.component import getUtility
from zope.schema.interfaces import IVocabularyFactory
+
import zope.i18n
+import six
+
+
+try:
+ import json
+except:
+ import simplejson as json
+
+
-from Products.CMFCore.utils import getToolByName
-from plone.memoize.view import memoize
-from plone.app.workflowmanager.browser.layout import GraphLayout
-from plone.app.workflowmanager.permissions import managed_permissions
-from plone.app.workflowmanager.permissions import allowed_guard_permissions
-from plone.app.workflowmanager.graphviz import HAS_GRAPHVIZ
-from plone.app.workflowmanager.actionmanager import ActionManager
-from plone.app.workflowmanager import WMMessageFactory as _
plone_shipped_workflows = [
- 'folder_workflow',
- 'intranet_folder_workflow',
- 'intranet_workflow',
- 'one_state_workflow',
- 'plone_workflow',
- 'simple_publication_workflow',
- 'comment_review_workflow']
+ "folder_workflow",
+ "intranet_folder_workflow",
+ "intranet_workflow",
+ "one_state_workflow",
+ "plone_workflow",
+ "simple_publication_workflow",
+ "comment_review_workflow",
+]
+
class Base(BrowserView):
"""
@@ -58,10 +64,9 @@ class Base(BrowserView):
errors = {}
next_id = None # the id of the next workflow to be viewed
- label = _(u'Workflow Manager')
- description = _(u'Manage your custom workflows TTW.')
- wrapped_dialog_template = ViewPageTemplateFile(
- 'templates/wrapped-dialog.pt')
+ label = _(u"Workflow Manager")
+ description = _(u"Manage your custom workflows TTW.")
+ wrapped_dialog_template = ViewPageTemplateFile("templates/wrapped-dialog.pt")
@property
@memoize
@@ -81,19 +86,18 @@ def allowed_guard_permissions(self):
@property
@memoize
def portal(self):
- utool = getToolByName(self.context, 'portal_url')
+ utool = getToolByName(self.context, "portal_url")
return utool.getPortalObject()
@property
@memoize
def portal_workflow(self):
- return getToolByName(self.context, 'portal_workflow')
+ return getToolByName(self.context, "portal_workflow")
@property
@memoize
def available_workflows(self):
- return [w for w in self.workflows
- if w.id not in plone_shipped_workflows]
+ return [w for w in self.workflows if w.id not in plone_shipped_workflows]
@property
@memoize
@@ -105,7 +109,7 @@ def workflows(self):
@property
@memoize
def selected_workflow(self):
- selected = self.request.get('selected-workflow')
+ selected = self.request.get("selected-workflow")
if type(selected) == list and len(selected) > 0:
selected = selected[0]
@@ -115,7 +119,7 @@ def selected_workflow(self):
@property
@memoize
def selected_state(self):
- state = self.request.get('selected-state')
+ state = self.request.get("selected-state")
if type(state) == list and len(state) > 0:
state = state[0]
@@ -125,7 +129,7 @@ def selected_state(self):
@property
@memoize
def selected_transition(self):
- transition = self.request.get('selected-transition')
+ transition = self.request.get("selected-transition")
if type(transition) == list and len(transition) > 0:
transition = transition[0]
@@ -136,36 +140,38 @@ def selected_transition(self):
@memoize
def available_states(self):
wf = self.selected_workflow
- if wf is not None:
- states = [wf.states[state] for state in wf.states.objectIds()]
- states.sort(lambda x, y: cmp(x.title.lower(), y.title.lower()))
- return states
- else:
+ if wf is None:
return []
+ states = sorted(
+ wf.states.objectValues(),
+ key=lambda x: x.title.lower(),
+ )
+ return states
@property
@memoize
def available_transitions(self):
wf = self.selected_workflow
- if wf is not None:
- transitions = wf.transitions.objectIds()
- transitions = [wf.transitions[t] for t in transitions]
- transitions.sort(
- lambda x, y: cmp(x.title.lower(), y.title.lower()))
- return transitions
- else:
+ if wf is None:
return []
+ transitions = sorted(
+ wf.transitions.objectValues(),
+ key=lambda x: x.title.lower(),
+ )
+ return transitions
def authorize(self):
- authenticator = getMultiAdapter((self.context, self.request),
- name=u"authenticator")
+ authenticator = getMultiAdapter(
+ (self.context, self.request), name=u"authenticator"
+ )
if not authenticator.verify():
raise Unauthorized
def render_transitions_template(self):
return self.workflow_transitions_template(
available_states=self.available_states,
- available_transitions=self.available_transitions)
+ available_transitions=self.available_transitions,
+ )
def get_transition(self, id):
if id in self.selected_workflow.transitions.objectIds():
@@ -174,14 +180,15 @@ def get_transition(self, id):
@property
@memoize
def assignable_types(self):
- vocab_factory = getUtility(IVocabularyFactory,
- name="plone.app.vocabularies.ReallyUserFriendlyTypes")
+ vocab_factory = getUtility(
+ IVocabularyFactory, name="plone.app.vocabularies.ReallyUserFriendlyTypes"
+ )
types = []
for v in vocab_factory(self.context):
types.append(dict(id=v.value, title=v.title))
def _key(v):
- return v['title']
+ return v["title"]
types.sort(key=_key)
return types
@@ -193,11 +200,9 @@ def assigned_types(self):
chain = self.portal_workflow.listChainOverrides()
nondefault = [info[0] for info in chain]
for type_ in self.assignable_types:
- if type_['id'] in nondefault:
- chain = self.portal_workflow.getChainForPortalType(
- type_['id'])
- if len(chain) > 0 and chain[0] == \
- self.selected_workflow.id:
+ if type_["id"] in nondefault:
+ chain = self.portal_workflow.getChainForPortalType(type_["id"])
+ if len(chain) > 0 and chain[0] == self.selected_workflow.id:
types.append(type_)
except:
pass
@@ -217,7 +222,9 @@ def get_state(self, id):
def get_transition_paths(self, state=None):
if state is not None:
- states = [state,]
+ states = [
+ state,
+ ]
else:
states = self.available_states
@@ -230,7 +237,10 @@ def get_transition_paths(self, state=None):
for trans in state.transitions:
current_transition = self.get_transition(trans)
if current_transition is not None:
- if current_transition.id is not None and current_transition.new_state_id is not None:
+ if (
+ current_transition.id is not None
+ and current_transition.new_state_id is not None
+ ):
nextState = current_transition.new_state_id
@@ -238,9 +248,11 @@ def get_transition_paths(self, state=None):
paths[stateId] = dict()
if nextState not in paths[stateId]:
- paths[stateId][nextState] = dict()
+ paths[stateId][nextState] = dict()
- paths[state.id][nextState][current_transition.id] = current_transition.title
+ paths[state.id][nextState][
+ current_transition.id
+ ] = current_transition.title
return json.dumps(paths)
@@ -256,28 +268,29 @@ def get_debug_mode(self):
def next_url(self):
return self.get_url()
- def get_url(self, relative=None, workflow=None, transition=None,
- state=None, **kwargs):
+ def get_url(
+ self, relative=None, workflow=None, transition=None, state=None, **kwargs
+ ):
url = self.context.absolute_url()
if relative:
- url = url + '/' + relative.lstrip('/')
+ url = url + "/" + relative.lstrip("/")
else:
- url = url + '/@@workflowmanager'
+ url = url + "/@@workflowmanager"
params = {}
if not workflow:
if self.next_id:
- params['selected-workflow'] = self.next_id
+ params["selected-workflow"] = self.next_id
elif self.selected_workflow:
- params['selected-workflow'] = self.selected_workflow.id
+ params["selected-workflow"] = self.selected_workflow.id
else:
- params['selected-workflow'] = workflow.id
+ params["selected-workflow"] = workflow.id
if transition:
- params['selected-transition'] = transition.id
+ params["selected-transition"] = transition.id
if state:
- params['selected-state'] = state.id
+ params["selected-state"] = state.id
params.update(kwargs)
@@ -288,7 +301,7 @@ def get_url(self, relative=None, workflow=None, transition=None,
@memoize
def getGroups(self):
- gf = aq_get(self.context, '__allow_groups__', None, 1)
+ gf = aq_get(self.context, "__allow_groups__", None, 1)
if gf is None:
return ()
try:
@@ -301,11 +314,10 @@ def getGroups(self):
@property
@memoize
def context_state(self):
- return getMultiAdapter((self.context, self.request),
- name=u'plone_portal_state')
+ return getMultiAdapter((self.context, self.request), name=u"plone_portal_state")
def wrap_template(self, tmpl, **options):
- ajax = self.request.get('ajax', None)
+ ajax = self.request.get("ajax", None)
if ajax:
return tmpl(options=options)
else:
@@ -315,51 +327,59 @@ def wrap_template(self, tmpl, **options):
def has_graphviz(self):
return HAS_GRAPHVIZ
- def handle_response(self, message=None, tmpl=None, redirect=None,
- load=None, justdoerrors=False,
- **kwargs):
- ajax = self.request.get('ajax', None)
- status = {'status': 'ok'}
+ def handle_response(
+ self,
+ message=None,
+ tmpl=None,
+ redirect=None,
+ load=None,
+ justdoerrors=False,
+ **kwargs
+ ):
+ ajax = self.request.get("ajax", None)
+ status = {"status": "ok"}
if len(self.errors) > 0:
- status['status'] = 'error'
+ status["status"] = "error"
if ajax:
- status['errors'] = [[k, v] for k, v in self.errors.items()]
+ status["errors"] = [[k, v] for k, v in self.errors.items()]
else:
- status['errors'] = self.errors
+ status["errors"] = self.errors
elif redirect:
- status['status'] = 'redirect'
+ status["status"] = "redirect"
- if type(redirect) in (str, unicode):
- status['location'] = redirect
+ if type(redirect) in (str, six.text_type):
+ status["location"] = redirect
else:
- status['location'] = self.next_url
+ status["location"] = self.next_url
elif load:
- status['status'] = 'load'
- status['url'] = load
+ status["status"] = "load"
+ status["url"] = load
else:
- status['status'] = 'ok'
+ status["status"] = "ok"
if message:
- status['message'] = zope.i18n.translate(message, context=self.request)
+ status["message"] = zope.i18n.translate(message, context=self.request)
if ajax:
- self.request.response.setHeader('X-Theme-Disabled', 'True')
+ self.request.response.setHeader("X-Theme-Disabled", "True")
if tmpl and not justdoerrors:
return tmpl.__of__(self.context)(**kwargs)
else:
- if 'graph_updates' in kwargs:
- #The response will default to HTML (not JSON) if we try to pass HTML back
- self.request.response.setHeader('Content-Type', 'application/JSON;;charset="utf-8"')
+ if "graph_updates" in kwargs:
+ # The response will default to HTML (not JSON) if we try to pass HTML back
+ self.request.response.setHeader(
+ "Content-Type", 'application/JSON;;charset="utf-8"'
+ )
- status['graph_updates'] = kwargs['graph_updates']
+ status["graph_updates"] = kwargs["graph_updates"]
return json.dumps(status)
else:
if redirect:
- return self.request.response.redirect(status['location'])
- elif status['status'] == 'load':
- return self.request.response.redirect(status['url'])
+ return self.request.response.redirect(status["location"])
+ elif status["status"] == "load":
+ return self.request.response.redirect(status["url"])
elif tmpl:
return self.wrap_template(tmpl, **kwargs)
else:
@@ -367,18 +387,15 @@ def handle_response(self, message=None, tmpl=None, redirect=None,
class ControlPanel(Base):
- template = ViewPageTemplateFile('templates/controlpanel.pt')
- content_template = ViewPageTemplateFile('templates/content.pt')
- workflow_state_template = \
- ViewPageTemplateFile('templates/workflow-state.pt')
- workflow_transition_template = \
- ViewPageTemplateFile('templates/workflow-transition.pt')
- workflow_graph_template = \
- ViewPageTemplateFile('templates/workflow-graph.pt')
- state_template = \
- ViewPageTemplateFile('templates/state.pt')
- transition_template = \
- ViewPageTemplateFile('templates/transition.pt')
+ template = ViewPageTemplateFile("templates/controlpanel.pt")
+ content_template = ViewPageTemplateFile("templates/content.pt")
+ workflow_state_template = ViewPageTemplateFile("templates/workflow-state.pt")
+ workflow_transition_template = ViewPageTemplateFile(
+ "templates/workflow-transition.pt"
+ )
+ workflow_graph_template = ViewPageTemplateFile("templates/workflow-graph.pt")
+ state_template = ViewPageTemplateFile("templates/state.pt")
+ transition_template = ViewPageTemplateFile("templates/transition.pt")
def __call__(self):
return self.template()
@@ -394,11 +411,13 @@ def retrieve_item(self):
transition = self.selected_transition
if state:
- return self.workflow_state_template(state=state,
- available_transitions=self.available_transitions)
+ return self.workflow_state_template(
+ state=state, available_transitions=self.available_transitions
+ )
elif transition:
- return self.workflow_transition_template(transition=transition,
- available_states=self.available_states)
+ return self.workflow_transition_template(
+ transition=transition, available_states=self.available_states
+ )
def render_states(self):
return self.state_template(states=self.available_states)
@@ -406,12 +425,13 @@ def render_states(self):
def render_transitions(self):
return self.transition_template(transitions=self.available_transitions)
-class Path():
+
+class Path:
"""Very simple class to represent a single path from state->transition->state"""
- start = ''
- transition = ''
- end = ''
+ start = ""
+ transition = ""
+ end = ""
def __init__(self, start, transition, end):
self.start = start
diff --git a/src/plone/app/workflowmanager/browser/layout.py b/src/plone/app/workflowmanager/browser/layout.py
index 57f76e0..74e25ca 100644
--- a/src/plone/app/workflowmanager/browser/layout.py
+++ b/src/plone/app/workflowmanager/browser/layout.py
@@ -1,7 +1,8 @@
+from plone import api
from Products.Five.browser import BrowserView
import json
-from plone import api
+import six
class GraphLayout(BrowserView):
@@ -22,7 +23,7 @@ def __init__(self, context, request, workflow=None):
self.REGISTRY_KEY = "plone.app.workflowmanager.layouts"
if workflow is None:
- self.workflow = self.request.form['workflow'] or None
+ self.workflow = self.request.form["workflow"] or None
else:
self.workflow = workflow
self.layout = {}
@@ -32,12 +33,12 @@ def __init__(self, context, request, workflow=None):
layouts = {}
if self.workflow not in layouts:
- layouts[unicode(self.workflow)] = u'{}'
+ layouts[six.text_type(self.workflow)] = u"{}"
else:
self.layout = json.loads(layouts[self.workflow])
def __call__(self):
- self.layout = json.loads(self.request.form['layout'])
+ self.layout = json.loads(self.request.form["layout"])
self.saveLayout()
def getLayouts(self):
@@ -45,11 +46,11 @@ def getLayouts(self):
def saveLayout(self):
layouts = self.getLayouts() or {}
- layouts[unicode(self.workflow)] = unicode(json.dumps(self.layout))
+ layouts[six.text_type(self.workflow)] = six.text_type(json.dumps(self.layout))
api.portal.set_registry_record(self.REGISTRY_KEY, layouts)
def getLayout(self):
- if(self.workflow == ''):
+ if self.workflow == "":
return False
return json.dumps(self.layout)
diff --git a/src/plone/app/workflowmanager/browser/resources/fix-bootstrap.py b/src/plone/app/workflowmanager/browser/resources/fix-bootstrap.py
index 706f6a5..6acb16b 100644
--- a/src/plone/app/workflowmanager/browser/resources/fix-bootstrap.py
+++ b/src/plone/app/workflowmanager/browser/resources/fix-bootstrap.py
@@ -4,24 +4,28 @@
# one area of the site
#
-_input = open('bootstrap.css')
-_output = open('bootstrap-fixed.css', 'w')
-_prefix = '.wm'
+_input = open("bootstrap.css")
+_output = open("bootstrap-fixed.css", "w")
+_prefix = ".wm"
_ignored_rules = (
- '.tooltip',
- '.popover',
- '.top',
- '.right',
- '.left',
- '.bottom',
- '.modal')
+ ".tooltip",
+ ".popover",
+ ".top",
+ ".right",
+ ".left",
+ ".bottom",
+ ".modal",
+)
for line in _input.readlines():
# starts with class rule
stripped = line.strip()
- if line and not stripped.startswith('@') and \
- (stripped.endswith('{') or stripped.endswith(',')):
+ if (
+ line
+ and not stripped.startswith("@")
+ and (stripped.endswith("{") or stripped.endswith(","))
+ ):
valid = True
for ignored in _ignored_rules:
if ignored in line:
@@ -31,9 +35,9 @@
# find replacement position
pos = 0
try:
- while line[pos] in (' ', '\t'):
+ while line[pos] in (" ", "\t"):
pos += 1
- line = line[:pos] + _prefix + ' ' + line[pos:]
+ line = line[:pos] + _prefix + " " + line[pos:]
except IndexError:
pass
_output.write(line)
diff --git a/src/plone/app/workflowmanager/browser/state.py b/src/plone/app/workflowmanager/browser/state.py
index 406d89d..1d34ac1 100644
--- a/src/plone/app/workflowmanager/browser/state.py
+++ b/src/plone/app/workflowmanager/browser/state.py
@@ -1,31 +1,28 @@
from Persistence import PersistentMapping
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-
-from plone.app.workflowmanager.utils import clone_state
from plone.app.workflow.remap import remap_workflow
-
+from plone.app.workflowmanager import WMMessageFactory as _
from plone.app.workflowmanager.browser import validators
-from plone.app.workflowmanager.permissions import managed_permissions
from plone.app.workflowmanager.browser.controlpanel import Base
-from plone.app.workflowmanager import WMMessageFactory as _
+from plone.app.workflowmanager.permissions import managed_permissions
+from plone.app.workflowmanager.utils import clone_state
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
import json
-from sets import Set
class AddState(Base):
- template = ViewPageTemplateFile('templates/add-new-state.pt')
- new_state_template = ViewPageTemplateFile('templates/state.pt')
+ template = ViewPageTemplateFile("templates/add-new-state.pt")
+ new_state_template = ViewPageTemplateFile("templates/state.pt")
def __call__(self):
self.errors = {}
- if not self.request.get('form.actions.add', False):
+ if not self.request.get("form.actions.add", False):
return self.handle_response(tmpl=self.template)
else:
self.authorize()
- state = validators.not_empty(self, 'state-name')
- state_id = validators.id(self, 'state-name',
- self.selected_workflow.states)
+ state = validators.not_empty(self, "state-name")
+ state_id = validators.id(self, "state-name", self.selected_workflow.states)
if not self.errors:
# must have state to go on
@@ -33,7 +30,7 @@ def __call__(self):
workflow.states.addState(state_id)
new_state = workflow.states[state_id]
- clone_of_id = self.request.get('clone-from-state')
+ clone_of_id = self.request.get("clone-from-state")
if clone_of_id:
# manage_copy|paste|clone doesn't work?
clone_state(new_state, workflow.states[clone_of_id])
@@ -41,15 +38,17 @@ def __call__(self):
new_state.title = state
# if added from transition screen
- referenced_transition = self.request.get(
- 'referenced-transition', None)
+ referenced_transition = self.request.get("referenced-transition", None)
if referenced_transition:
- new_state.transitions = \
- new_state.transitions + (referenced_transition, )
+ new_state.transitions = new_state.transitions + (
+ referenced_transition,
+ )
- msg = _('msg_state_created',
- default=u'"${state_id}" state successfully created.',
- mapping={'state_id': new_state.id})
+ msg = _(
+ "msg_state_created",
+ default=u'"${state_id}" state successfully created.',
+ mapping={"state_id": new_state.id},
+ )
arbitraryStateList = []
arbitraryStateList.append(new_state)
@@ -58,23 +57,21 @@ def __call__(self):
updates = dict()
- updates['element'] = new_elements
- updates['type'] = u'state'
- updates['action'] = u'add'
- updates['objectId'] = new_state.id
- updates['transitions'] = new_state.transitions
+ updates["element"] = new_elements
+ updates["type"] = u"state"
+ updates["action"] = u"add"
+ updates["objectId"] = new_state.id
+ updates["transitions"] = new_state.transitions
return self.handle_response(
- message=msg,
- graph_updates=updates,
- state=new_state)
+ message=msg, graph_updates=updates, state=new_state
+ )
else:
- return self.handle_response(tmpl=self.template,
- justdoerrors=True)
+ return self.handle_response(tmpl=self.template, justdoerrors=True)
class DeleteState(Base):
- template = ViewPageTemplateFile('templates/delete-state.pt')
+ template = ViewPageTemplateFile("templates/delete-state.pt")
def __call__(self):
self.errors = {}
@@ -88,78 +85,94 @@ def __call__(self):
self.is_using_state = True
break
- if self.request.get('form.actions.delete', False):
+ if self.request.get("form.actions.delete", False):
self.authorize()
if self.is_using_state:
- replacement = self.request.get('replacement-state',
- self.available_states[0].id)
+ replacement = self.request.get(
+ "replacement-state", self.available_states[0].id
+ )
for transition in self.available_transitions:
if state_id == transition.new_state_id:
transition.new_state_id = replacement
chains = self.portal_workflow.listChainOverrides()
- types_ids = [c[0] for c in chains
- if self.selected_workflow.id in c[1]]
- remap_workflow(self.context, types_ids,
- (self.selected_workflow.id, ), {state_id: replacement})
+ types_ids = [c[0] for c in chains if self.selected_workflow.id in c[1]]
+ remap_workflow(
+ self.context,
+ types_ids,
+ (self.selected_workflow.id,),
+ {state_id: replacement},
+ )
self.selected_workflow.states.deleteStates([state_id])
updates = dict()
- updates['objectId'] = state_id
- updates['action'] = u'delete'
- updates['type'] = u'state'
+ updates["objectId"] = state_id
+ updates["action"] = u"delete"
+ updates["type"] = u"state"
try:
- updates['replacement'] = replacement
+ updates["replacement"] = replacement
except UnboundLocalError:
pass
return self.handle_response(
- message=_('msg_state_deleted',
+ message=_(
+ "msg_state_deleted",
default=u'"${id}" state has been successfully deleted.',
- mapping={'id': state_id}),
- graph_updates=updates)
- elif self.request.get('form.actions.cancel', False) == 'Cancel':
+ mapping={"id": state_id},
+ ),
+ graph_updates=updates,
+ )
+ elif self.request.get("form.actions.cancel", False) == "Cancel":
return self.handle_response(
- message=_('msg_state_deletion_canceled',
+ message=_(
+ "msg_state_deletion_canceled",
default=u'Deleting the "${id}" state has been canceled.',
- mapping={'id': state_id}))
+ mapping={"id": state_id},
+ )
+ )
else:
return self.handle_response(tmpl=self.template)
class SaveState(Base):
- updated_state_template = ViewPageTemplateFile('templates/state.pt')
+ updated_state_template = ViewPageTemplateFile("templates/state.pt")
+
def update_selected_transitions(self):
wf = self.selected_workflow
- state = wf.states[self.request.get('selected-state')]
+ state = wf.states[self.request.get("selected-state")]
transitions = wf.transitions.objectIds()
selected_transitions = []
for transition in transitions:
- key = 'transition-%s-state-%s' % (transition, state.id)
+ key = "transition-%s-state-%s" % (transition, state.id)
if key in self.request:
selected_transitions.append(transition)
state.transitions = tuple(selected_transitions)
def update_state_permissions(self):
wf = self.selected_workflow
- state = wf.states[self.request.get('selected-state')]
+ state = wf.states[self.request.get("selected-state")]
perm_roles = PersistentMapping()
available_roles = state.getAvailableRoles()
for managed_perm in managed_permissions(wf.id):
selected_roles = []
for role in available_roles:
- key = 'permission-%s-role-%s-state-%s' % (
- managed_perm['name'], role, state.id)
+ key = "permission-%s-role-%s-state-%s" % (
+ managed_perm["name"],
+ role,
+ state.id,
+ )
if key in self.request:
selected_roles.append(role)
- acquire_key = 'permission-acquire-%s-state-%s' % (
- managed_perm['name'], state.id)
+ acquire_key = "permission-acquire-%s-state-%s" % (
+ managed_perm["name"],
+ state.id,
+ )
if acquire_key in self.request:
acquired = True
else:
@@ -168,43 +181,42 @@ def update_state_permissions(self):
if len(selected_roles) > 0:
if not acquired:
selected_roles = tuple(selected_roles)
- perm_roles[managed_perm['perm']] = selected_roles
- if managed_perm['perm'] not in wf.permissions:
- wf.permissions = wf.permissions + (managed_perm['perm'], )
- elif managed_perm['perm'] in wf.permissions:
+ perm_roles[managed_perm["perm"]] = selected_roles
+ if managed_perm["perm"] not in wf.permissions:
+ wf.permissions = wf.permissions + (managed_perm["perm"],)
+ elif managed_perm["perm"] in wf.permissions:
# it's managed, no perms set, but still could save acquired
if acquired:
- perm_roles[managed_perm['perm']] = []
+ perm_roles[managed_perm["perm"]] = []
else:
- perm_roles[managed_perm['perm']] = ()
+ perm_roles[managed_perm["perm"]] = ()
elif not acquired:
# not already managing perms, but no longer acquire permissions
- if managed_perm['perm'] not in wf.permissions:
- wf.permissions = wf.permissions + (managed_perm['perm'], )
- perm_roles[managed_perm['perm']] = ()
+ if managed_perm["perm"] not in wf.permissions:
+ wf.permissions = wf.permissions + (managed_perm["perm"],)
+ perm_roles[managed_perm["perm"]] = ()
state.permission_roles = perm_roles
def update_state_properties(self):
wf = self.selected_workflow
- state = wf.states[self.request.get('selected-state')]
+ state = wf.states[self.request.get("selected-state")]
- if ('state-%s-initial-state' % state.id) in self.request:
+ if ("state-%s-initial-state" % state.id) in self.request:
wf.initial_state = state.id
- title = self.request.get('state-%s-title' % state.id, False)
+ title = self.request.get("state-%s-title" % state.id, False)
if title:
state.title = title
- description = self.request.get('state-%s-description' % state.id,
- False)
+ description = self.request.get("state-%s-description" % state.id, False)
if description:
state.description = description
def update_state_group_roles(self):
wf = self.selected_workflow
- state = wf.states[self.request.get('selected-state')]
+ state = wf.states[self.request.get("selected-state")]
group_roles = PersistentMapping()
available_roles = state.getAvailableRoles()
@@ -214,30 +226,29 @@ def update_state_group_roles(self):
selected_roles = []
for role in available_roles:
- key = "group-%s-role-%s-state-%s" % (
- group['id'], role, state.id)
+ key = "group-%s-role-%s-state-%s" % (group["id"], role, state.id)
if key in self.request:
selected_roles.append(role)
if len(selected_roles) > 0:
- group_roles[group['id']] = tuple(selected_roles)
+ group_roles[group["id"]] = tuple(selected_roles)
- if group['id'] not in wf.groups:
- wf.groups = wf.groups + (group['id'], )
+ if group["id"] not in wf.groups:
+ wf.groups = wf.groups + (group["id"],)
state.group_roles = group_roles
def __call__(self):
- if self.request.get('form-box') is not None:
- form_data = self.request.get('form-box')
+ if self.request.get("form-box") is not None:
+ form_data = self.request.get("form-box")
form_data = json.loads(form_data)
- for name in form_data:
+ for name in form_data:
self.request[name] = form_data[name]
self.authorize()
self.errors = {}
wf = self.selected_workflow
- state = wf.states[self.request.get('selected-state')]
+ state = wf.states[self.request.get("selected-state")]
oldTransitions = state.transitions
@@ -253,35 +264,35 @@ def __call__(self):
updated_state = self.updated_state_template(states=arbitraryStateList)
- #transitions that were added...
- add = list( Set(newTransitions) - Set(oldTransitions) )
+ # transitions that were added...
+ add = list(set(newTransitions) - set(oldTransitions))
- #transitions that were removed
- remove = list( Set(oldTransitions) - Set(newTransitions) )
+ # transitions that were removed
+ remove = list(set(oldTransitions) - set(newTransitions))
update = dict()
- update['objectId']=state.id
- update['action']=u'update'
- update['type']=u'state'
- update['element']=updated_state
- update['add'] = add
- update['remove'] = remove
+ update["objectId"] = state.id
+ update["action"] = u"update"
+ update["type"] = u"state"
+ update["element"] = updated_state
+ update["add"] = add
+ update["remove"] = remove
+
+ return self.handle_response(graph_updates=update)
- return self.handle_response(
- graph_updates=update)
class EditState(Base):
- template = ViewPageTemplateFile('templates/workflow-state.pt')
+ template = ViewPageTemplateFile("templates/workflow-state.pt")
def __call__(self):
wf = self.selected_workflow
- if (wf == None):
+ if wf == None:
return self.handle_response()
state = self.selected_state
- if( state == None ):
+ if state == None:
return self.handle_response()
transitions = self.available_transitions
@@ -289,5 +300,4 @@ def __call__(self):
return self.render_state_template(state, transitions)
def render_state_template(self, state, transitions):
- return self.template(state=state,
- available_transitions=transitions)
+ return self.template(state=state, available_transitions=transitions)
diff --git a/src/plone/app/workflowmanager/browser/transition.py b/src/plone/app/workflowmanager/browser/transition.py
index 4c7e63a..648b203 100644
--- a/src/plone/app/workflowmanager/browser/transition.py
+++ b/src/plone/app/workflowmanager/browser/transition.py
@@ -1,31 +1,30 @@
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-
-from Products.DCWorkflow.Transitions import TRIGGER_AUTOMATIC
-from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
-
-from plone.app.workflowmanager.browser.controlpanel import Base
-from plone.app.workflowmanager.utils import clone_transition
+from plone.app.workflowmanager import WMMessageFactory as _
from plone.app.workflowmanager.browser import validators
+from plone.app.workflowmanager.browser.controlpanel import Base
from plone.app.workflowmanager.permissions import allowed_guard_permissions
+from plone.app.workflowmanager.utils import clone_transition
+from Products.DCWorkflow.Transitions import TRIGGER_AUTOMATIC
+from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-from plone.app.workflowmanager import WMMessageFactory as _
import json
class AddTransition(Base):
- template = ViewPageTemplateFile('templates/add-new-transition.pt')
- new_transition_template = ViewPageTemplateFile('templates/transition.pt')
+ template = ViewPageTemplateFile("templates/add-new-transition.pt")
+ new_transition_template = ViewPageTemplateFile("templates/transition.pt")
def __call__(self):
self.errors = {}
- if not self.request.get('form.actions.add', False):
+ if not self.request.get("form.actions.add", False):
return self.handle_response(tmpl=self.template)
else:
self.authorize()
- transition = validators.not_empty(self, 'transition-name')
- transition_id = validators.id(self, 'transition-name',
- self.selected_workflow.transitions)
+ transition = validators.not_empty(self, "transition-name")
+ transition_id = validators.id(
+ self, "transition-name", self.selected_workflow.transitions
+ )
if not self.errors:
# must have transition to go on
@@ -33,52 +32,58 @@ def __call__(self):
workflow.transitions.addTransition(transition_id)
new_transition = workflow.transitions[transition_id]
- clone_of_id = self.request.get('clone-from-transition')
+ clone_of_id = self.request.get("clone-from-transition")
new_transition.title = transition
if clone_of_id:
# manage_copy|paste|clone doesn't work?
- clone_transition(new_transition,
- workflow.transitions[clone_of_id])
+ clone_transition(new_transition, workflow.transitions[clone_of_id])
else:
new_transition.actbox_name = transition
- new_transition.actbox_url = \
- "%(content_url)s/content_status_modify?workflow_action=" + transition_id
- new_transition.actbox_category = 'workflow'
- new_transition.script_name = ''
- new_transition.after_script_name = ''
+ new_transition.actbox_url = (
+ "%(content_url)s/content_status_modify?workflow_action="
+ + transition_id
+ )
+ new_transition.actbox_category = "workflow"
+ new_transition.script_name = ""
+ new_transition.after_script_name = ""
# if added from state screen
- referenced_state = self.request.get('referenced-state', None)
+ referenced_state = self.request.get("referenced-state", None)
if referenced_state:
state = self.selected_workflow.states[referenced_state]
- state.transitions += (new_transition.id, )
+ state.transitions += (new_transition.id,)
arbitraryTransitionList = []
arbitraryTransitionList.append(new_transition)
- new_element = self.new_transition_template(transitions=arbitraryTransitionList)
+ new_element = self.new_transition_template(
+ transitions=arbitraryTransitionList
+ )
updates = dict()
- updates['objectId'] = new_transition.id
- updates['element'] = new_element
- updates['action'] = u'add'
- updates['type'] = u'transition'
+ updates["objectId"] = new_transition.id
+ updates["element"] = new_element
+ updates["action"] = u"add"
+ updates["type"] = u"transition"
return self.handle_response(
- message=_('msg_transition_created',
+ message=_(
+ "msg_transition_created",
default=u'"${transition_id}" transition successfully created.',
- mapping={'transition_id': new_transition.id}),
+ mapping={"transition_id": new_transition.id},
+ ),
graph_updates=updates,
- transition=new_transition)
+ transition=new_transition,
+ )
else:
- return self.handle_response(tmpl=self.template,
- justdoerrors=True)
+ return self.handle_response(tmpl=self.template, justdoerrors=True)
class SaveTransition(Base):
- transition_template = ViewPageTemplateFile('templates/transition.pt')
+ transition_template = ViewPageTemplateFile("templates/transition.pt")
+
def update_guards(self):
wf = self.selected_workflow
transition = self.selected_transition
@@ -86,20 +91,21 @@ def update_guards(self):
perms = []
for key, perm in allowed_guard_permissions(wf.getId()).items():
- key = 'transition-%s-guard-permission-%s' % (transition.id, key)
+ key = "transition-%s-guard-permission-%s" % (transition.id, key)
if key in self.request and perm not in guard.permissions:
perms.append(perm)
guard.permissions = tuple(perms)
- roles = validators.parse_set_value(self, 'transition-%s-guard-roles' %
- transition.id)
+ roles = validators.parse_set_value(
+ self, "transition-%s-guard-roles" % transition.id
+ )
okay_roles = set(wf.getAvailableRoles())
guard.roles = tuple(roles & okay_roles)
- groups = validators.parse_set_value(self,
- 'transition-%s-guard-groups' %
- transition.id)
- okay_groups = set([g['id'] for g in self.getGroups()])
+ groups = validators.parse_set_value(
+ self, "transition-%s-guard-groups" % transition.id
+ )
+ okay_groups = set([g["id"] for g in self.getGroups()])
guard.groups = tuple(groups & okay_groups)
transition.guard = guard
@@ -107,32 +113,34 @@ def update_guards(self):
def update_transition_properties(self):
transition = self.selected_transition
- if ('transition-%s-autotrigger' % transition.id) in self.request:
+ if ("transition-%s-autotrigger" % transition.id) in self.request:
transition.trigger_type = TRIGGER_AUTOMATIC
else:
transition.trigger_type = TRIGGER_USER_ACTION
- if ('transition-%s-display-name' % transition.id) in self.request:
- transition.actbox_name = \
- self.request.get('transition-%s-display-name' % transition.id)
+ if ("transition-%s-display-name" % transition.id) in self.request:
+ transition.actbox_name = self.request.get(
+ "transition-%s-display-name" % transition.id
+ )
- if ('transition-%s-new-state' % transition.id) in self.request:
- transition.new_state_id = \
- self.request.get('transition-%s-new-state' % transition.id)
+ if ("transition-%s-new-state" % transition.id) in self.request:
+ transition.new_state_id = self.request.get(
+ "transition-%s-new-state" % transition.id
+ )
- if ('transition-%s-title' % transition.id) in self.request:
- transition.title = \
- self.request.get('transition-%s-title' % transition.id)
+ if ("transition-%s-title" % transition.id) in self.request:
+ transition.title = self.request.get("transition-%s-title" % transition.id)
- if ('transition-%s-description' % transition.id) in self.request:
- transition.description = \
- self.request.get('transition-%s-description' % transition.id)
+ if ("transition-%s-description" % transition.id) in self.request:
+ transition.description = self.request.get(
+ "transition-%s-description" % transition.id
+ )
for state in self.available_states:
- key = 'transition-%s-state-%s-selected' % (transition.id, state.id)
+ key = "transition-%s-state-%s-selected" % (transition.id, state.id)
if key in self.request:
if transition.id not in state.transitions:
- state.transitions += (transition.id, )
+ state.transitions += (transition.id,)
else:
if transition.id in state.transitions:
transitions = list(state.transitions)
@@ -140,11 +148,11 @@ def update_transition_properties(self):
state.transitions = transitions
def __call__(self):
- if self.request.get('form-box') is not None:
- form_data = self.request.get('form-box')
+ if self.request.get("form-box") is not None:
+ form_data = self.request.get("form-box")
form_data = json.loads(form_data)
- for name in form_data:
+ for name in form_data:
self.request[name] = form_data[name]
self.authorize()
@@ -162,26 +170,25 @@ def __call__(self):
element = self.transition_template(transitions=arbitraryTransitionList)
updates = dict()
- updates['objectId'] = transition.id
- updates['element'] = element
- updates['type'] = u'transition'
- updates['action'] = u'update'
+ updates["objectId"] = transition.id
+ updates["element"] = element
+ updates["type"] = u"transition"
+ updates["action"] = u"update"
- return self.handle_response(
- graph_updates=updates)
+ return self.handle_response(graph_updates=updates)
class DeleteTransition(Base):
- template = ViewPageTemplateFile('templates/delete-transition.pt')
+ template = ViewPageTemplateFile("templates/delete-transition.pt")
def __call__(self):
self.errors = {}
transition = self.selected_transition
transition_id = transition.id
- if self.request.get('form.actions.delete', False):
+ if self.request.get("form.actions.delete", False):
self.authorize()
- #delete any associated rules also.
+ # delete any associated rules also.
self.actions.delete_rule_for(self.selected_transition)
self.selected_workflow.transitions.deleteTransitions([transition_id])
@@ -193,35 +200,39 @@ def __call__(self):
state.transitions = tuple(transitions)
updates = dict()
- updates['objectId'] = transition_id
- updates['action'] = u'delete'
- updates['type'] = u'transition'
-
- msg = _('msg_transition_deleted',
- default=u'"${id}" transition has been successfully deleted.',
- mapping={'id': transition_id})
- return self.handle_response(message=msg,
- graph_updates=updates)
- elif self.request.get('form.actions.cancel', False) == 'Cancel':
- msg = _('msg_deleting_canceled',
- default=u'Deleting the "${id}" transition has been canceled.',
- mapping={'id': transition_id})
+ updates["objectId"] = transition_id
+ updates["action"] = u"delete"
+ updates["type"] = u"transition"
+
+ msg = _(
+ "msg_transition_deleted",
+ default=u'"${id}" transition has been successfully deleted.',
+ mapping={"id": transition_id},
+ )
+ return self.handle_response(message=msg, graph_updates=updates)
+ elif self.request.get("form.actions.cancel", False) == "Cancel":
+ msg = _(
+ "msg_deleting_canceled",
+ default=u'Deleting the "${id}" transition has been canceled.',
+ mapping={"id": transition_id},
+ )
return self.handle_response(message=msg)
else:
return self.handle_response(tmpl=self.template)
+
class EditTransition(Base):
- template = ViewPageTemplateFile('templates/workflow-transition.pt')
+ template = ViewPageTemplateFile("templates/workflow-transition.pt")
def __call__(self):
wf = self.selected_workflow
- if (wf == None):
+ if wf == None:
return self.handle_response()
transition = self.selected_transition
- if( transition == None ):
+ if transition == None:
return self.handle_response()
states = self.available_states
@@ -229,6 +240,4 @@ def __call__(self):
return self.render_transition_template(transition, states)
def render_transition_template(self, transition, states):
- return self.template(transition=transition,
- available_states=states)
-
+ return self.template(transition=transition, available_states=states)
diff --git a/src/plone/app/workflowmanager/browser/validators.py b/src/plone/app/workflowmanager/browser/validators.py
index 8070e91..3a6d634 100644
--- a/src/plone/app/workflowmanager/browser/validators.py
+++ b/src/plone/app/workflowmanager/browser/validators.py
@@ -1,30 +1,37 @@
from OFS.ObjectManager import checkValidId
-from zope.i18n import translate
-from Products.CMFCore.utils import getToolByName
-from plone.app.workflowmanager.utils import generate_id
from plone.app.workflowmanager import WMMessageFactory as _
+from plone.app.workflowmanager.utils import generate_id
+from Products.CMFCore.utils import getToolByName
+from zope.i18n import translate
+import six
def not_empty(form, name):
- v = form.request.get(name, '').strip()
- if v is None or (type(v) in (str, unicode) and \
- len(v) == 0) or (type(v) in (tuple, set, list) and len(v) == 0):
- form.errors[name] = translate(_(u'This field is required.'),
- context=form.request)
+ v = form.request.get(name, "").strip()
+ if (
+ v is None
+ or (type(v) in (str, six.text_type) and len(v) == 0)
+ or (type(v) in (tuple, set, list) and len(v) == 0)
+ ):
+ form.errors[name] = translate(
+ _(u"This field is required."), context=form.request
+ )
return v
def id(form, name, container):
- elt_id = form.request.get(name, '').strip()
- putils = getToolByName(form.context, 'plone_utils')
- elt_id = generate_id(putils.normalizeString(unicode(elt_id, encoding='utf-8')),
- container.objectIds())
+ elt_id = form.request.get(name, "").strip()
+ putils = getToolByName(form.context, "plone_utils")
+ elt_id = generate_id(
+ putils.normalizeString(six.text_type(elt_id, encoding="utf-8")), container.objectIds()
+ )
try:
checkValidId(container, elt_id)
except:
- form.errors[name] = translate(_(u'Invalid name. Please try another.'),
- context=form.request)
+ form.errors[name] = translate(
+ _(u"Invalid name. Please try another."), context=form.request
+ )
return elt_id
@@ -32,8 +39,8 @@ def id(form, name, container):
def parse_set_value(form, key):
val = form.request.get(key)
if val:
- if type(val) in (str, unicode):
- return set(val.split(','))
+ if type(val) in (str, six.text_type):
+ return set(val.split(","))
elif type(val) in (tuple, list):
return set(val)
else:
diff --git a/src/plone/app/workflowmanager/browser/workflow.py b/src/plone/app/workflowmanager/browser/workflow.py
index 8c5adcb..60ecbfe 100644
--- a/src/plone/app/workflowmanager/browser/workflow.py
+++ b/src/plone/app/workflowmanager/browser/workflow.py
@@ -1,17 +1,15 @@
-from random import randint
-from urllib import urlencode
-
from DateTime import DateTime
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-
+from plone.app.workflowmanager import WMMessageFactory as _
+from plone.app.workflowmanager.browser import validators
from plone.app.workflowmanager.browser.controlpanel import Base
from plone.app.workflowmanager.graphviz import getGraph
-from plone.app.workflowmanager.browser import validators
-from plone.app.workflowmanager import WMMessageFactory as _
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from random import randint
+from six.moves.urllib.parse import urlencode
class DeleteWorkflow(Base):
- template = ViewPageTemplateFile('templates/delete-workflow.pt')
+ template = ViewPageTemplateFile("templates/delete-workflow.pt")
def __call__(self):
self.errors = {}
@@ -21,43 +19,45 @@ def __call__(self):
if not self.can_delete:
return self.handle_response(
tmpl=self.template,
- message=_(u'You can not delete this workflow until no content '
- u'types are specified to use this workflow.'))
- elif self.request.get('form.actions.delete', False) == 'Delete':
+ message=_(
+ u"You can not delete this workflow until no content "
+ u"types are specified to use this workflow."
+ ),
+ )
+ elif self.request.get("form.actions.delete", False) == "Delete":
self.authorize()
- #delete all rules also.
+ # delete all rules also.
for transition in self.available_transitions:
self.actions.delete_rule_for(transition)
self.portal_workflow.manage_delObjects([self.selected_workflow.id])
return self.handle_response(redirect=True)
- elif self.request.get('form.actions.cancel', False) == 'Cancel':
+ elif self.request.get("form.actions.cancel", False) == "Cancel":
return self.handle_response()
else:
return self.handle_response(tmpl=self.template)
class AddWorkflow(Base):
- template = ViewPageTemplateFile('templates/add-new-workflow.pt')
+ template = ViewPageTemplateFile("templates/add-new-workflow.pt")
def __call__(self):
self.errors = {}
- workflow = validators.not_empty(self, 'workflow-name')
- workflow_id = validators.id(self, 'workflow-name',
- self.portal_workflow)
+ workflow = validators.not_empty(self, "workflow-name")
+ workflow_id = validators.id(self, "workflow-name", self.portal_workflow)
- if not self.request.get('form.actions.add', False):
+ if not self.request.get("form.actions.add", False):
return self.handle_response(tmpl=self.template)
elif self.errors:
return self.handle_response(tmpl=self.template, justdoerrors=True)
else:
self.authorize()
# must have state to go on
- cloned_from_workflow = \
- self.portal_workflow[self.request.get('clone-from-workflow')]
+ cloned_from_workflow = self.portal_workflow[
+ self.request.get("clone-from-workflow")
+ ]
- self.context.portal_workflow.manage_clone(cloned_from_workflow,
- workflow_id)
+ self.context.portal_workflow.manage_clone(cloned_from_workflow, workflow_id)
new_workflow = self.context.portal_workflow[workflow_id]
new_workflow.title = workflow
self.next_id = new_workflow.id
@@ -66,47 +66,57 @@ def __call__(self):
class UpdateSecuritySettings(Base):
- template = ViewPageTemplateFile('templates/update-security-settings.pt')
+ template = ViewPageTemplateFile("templates/update-security-settings.pt")
def __call__(self):
- if self.request.get('form.actions.confirm', False):
+ if self.request.get("form.actions.confirm", False):
self.authorize()
count = self.portal_workflow._recursiveUpdateRoleMappings(
- self.portal,
- {self.selected_workflow.id: self.selected_workflow})
+ self.portal, {self.selected_workflow.id: self.selected_workflow}
+ )
return self.handle_response(
- message=_('msg_updated_objects',
- default="Updated ${count} objects.",
- mapping={'count': count}))
+ message=_(
+ "msg_updated_objects",
+ default="Updated ${count} objects.",
+ mapping={"count": count},
+ )
+ )
else:
return self.handle_response(tmpl=self.template)
class Assign(Base):
- template = ViewPageTemplateFile('templates/assign.pt')
+ template = ViewPageTemplateFile("templates/assign.pt")
def __call__(self):
self.errors = {}
- if self.request.get('form.actions.next', False):
+ if self.request.get("form.actions.next", False):
self.authorize()
- params = urlencode({'type_id': self.request.get('type_id'),
- 'new_workflow': self.selected_workflow.id})
- return self.handle_response(load=self.context_state.portal_url() +
- '/@@content-controlpanel?' + params)
+ params = urlencode(
+ {
+ "type_id": self.request.get("type_id"),
+ "new_workflow": self.selected_workflow.id,
+ }
+ )
+ return self.handle_response(
+ load=self.context_state.portal_url()
+ + "/@@content-controlpanel?"
+ + params
+ )
else:
return self.handle_response(tmpl=self.template)
class SanityCheck(Base):
- template = ViewPageTemplateFile('templates/sanity-check.pt')
+ template = ViewPageTemplateFile("templates/sanity-check.pt")
def __call__(self):
self.errors = {}
states = self.available_states
transitions = self.available_transitions
- self.errors['state-errors'] = []
- self.errors['transition-errors'] = []
+ self.errors["state-errors"] = []
+ self.errors["transition-errors"] = []
for state in states:
found = False
@@ -115,12 +125,14 @@ def __call__(self):
found = True
break
- if self.selected_workflow.initial_state == state.id and \
- len(state.transitions) > 0:
+ if (
+ self.selected_workflow.initial_state == state.id
+ and len(state.transitions) > 0
+ ):
found = True
if not found:
- self.errors['state-errors'].append(state)
+ self.errors["state-errors"].append(state)
for transition in transitions:
found = False
@@ -133,22 +145,26 @@ def __call__(self):
break
if not found:
- self.errors['transition-errors'].append(transition)
+ self.errors["transition-errors"].append(transition)
state_ids = [s.id for s in states]
- if not self.selected_workflow.initial_state or \
- self.selected_workflow.initial_state not in state_ids:
- self.errors['initial-state-error'] = True
-
- self.has_errors = len(self.errors['state-errors']) > 0 or \
- len(self.errors['transition-errors']) > 0 or \
- 'initial-state-error' in self.errors
+ if (
+ not self.selected_workflow.initial_state
+ or self.selected_workflow.initial_state not in state_ids
+ ):
+ self.errors["initial-state-error"] = True
+
+ self.has_errors = (
+ len(self.errors["state-errors"]) > 0
+ or len(self.errors["transition-errors"]) > 0
+ or "initial-state-error" in self.errors
+ )
return self.handle_response(tmpl=self.template)
class Graph(Base):
- template = ViewPageTemplateFile('templates/diagram.pt')
+ template = ViewPageTemplateFile("templates/diagram.pt")
def __call__(self):
# generate a random number ot prevent browser from caching this...
@@ -157,8 +173,8 @@ def __call__(self):
def image(self):
resp = self.request.response
- resp.setHeader('Content-Type', 'image/gif')
- resp.setHeader('Last-Modified', DateTime().rfc822())
+ resp.setHeader("Content-Type", "image/gif")
+ resp.setHeader("Last-Modified", DateTime().rfc822())
graph = getGraph(self.selected_workflow)
resp.setHeader("Content-Length", len(graph))
return graph
diff --git a/src/plone/app/workflowmanager/configure.zcml b/src/plone/app/workflowmanager/configure.zcml
index d91cc58..52b2d98 100644
--- a/src/plone/app/workflowmanager/configure.zcml
+++ b/src/plone/app/workflowmanager/configure.zcml
@@ -1,32 +1,35 @@
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
+ xmlns:i18n="http://namespaces.zope.org/i18n"
+ xmlns:zcml="http://namespaces.zope.org/zcml"
+ i18n_domain="plone.app.workflowmanager"
+ >
-
-
-
+
-
+
+ name="default"
+ title="Workflow Manager"
+ description="Workflow Manager for Plone."
+ provides="Products.GenericSetup.interfaces.EXTENSION"
+ for="Products.CMFPlone.interfaces.IPloneSiteRoot"
+ directory="profiles/default"
+ />
+ name="uninstall"
+ title="Workflow Manager (uninstall)"
+ description="Uninstalls the Workflow Manager for Plone."
+ provides="Products.GenericSetup.interfaces.EXTENSION"
+ directory="profiles/uninstall"
+ />
diff --git a/src/plone/app/workflowmanager/graphviz.py b/src/plone/app/workflowmanager/graphviz.py
index 03d7c58..96ae1c6 100644
--- a/src/plone/app/workflowmanager/graphviz.py
+++ b/src/plone/app/workflowmanager/graphviz.py
@@ -2,17 +2,19 @@
# This code is directly adapted from
# DCWorkflowGraph and isn't change much at all.
#
-import os
-from tempfile import mktemp
from os.path import join
-
from Products.CMFCore.utils import getToolByName
+from tempfile import mktemp
-DOT_EXE = 'dot'
-bin_search_path = ''
+import os
+import six
-if os.name == 'nt':
- DOT_EXE = 'dot.exe'
+
+DOT_EXE = "dot"
+bin_search_path = ""
+
+if os.name == "nt":
+ DOT_EXE = "dot.exe"
# patch from Joachim Bauch bauch@struktur.de
# on Windows, the path to the ATT Graphviz installation
@@ -20,13 +22,15 @@
try:
import win32api
import win32con
+
# make sure that "key" is defined in our except block
key = None
try:
key = win32api.RegOpenKeyEx(
- win32con.HKEY_LOCAL_MACHINE, r'SOFTWARE\ATT\Graphviz')
- value, type = win32api.RegQueryValueEx(key, 'InstallPath')
- bin_search_path = [join(str(value), 'bin')]
+ win32con.HKEY_LOCAL_MACHINE, r"SOFTWARE\ATT\Graphviz"
+ )
+ value, type = win32api.RegQueryValueEx(key, "InstallPath")
+ bin_search_path = [join(str(value), "bin")]
except:
if key:
win32api.RegCloseKey(key)
@@ -37,7 +41,7 @@
pass
else:
# for posix systems
- DOT_EXE = 'dot'
+ DOT_EXE = "dot"
path = os.getenv("PATH")
bin_search_path = path.split(":")
@@ -62,6 +66,7 @@ def bin_search(binary):
raise MissingBinary('Unable to find binary "%s"' % binary)
return result
+
try:
bin = bin_search(DOT_EXE)
HAS_GRAPHVIZ = True
@@ -80,21 +85,21 @@ def getObjectTitle(object):
if not title:
title = id
else:
- title = '%s\\n(id: %s)' % (title, id)
+ title = "%s\\n(id: %s)" % (title, id)
return title
def getGuardTitle(guard):
- out = ''
+ out = ""
if guard is not None:
if guard.expr:
- out += 'Expression: %s; ' % guard.expr.text
+ out += "Expression: %s; " % guard.expr.text
if guard.permissions:
- out += 'Permissions: %s; ' % ','.join(guard.permissions)
+ out += "Permissions: %s; " % ",".join(guard.permissions)
if guard.roles:
- out += 'Roles: %s; ' % ','.join(guard.roles)
+ out += "Roles: %s; " % ",".join(guard.roles)
if guard.groups:
- out += 'Groups: %s; ' % ','.join(guard.groups)
+ out += "Groups: %s; " % ",".join(guard.groups)
return out
@@ -114,15 +119,17 @@ def getPOT(wf):
s_id = s.getId()
s_title = getObjectTitle(s)
out.append(
- '"%s" [shape=box,label="%s",style="filled",fillcolor="#ffcc99"];' % (
- s_id, s_title))
+ '"%s" [shape=box,label="%s",style="filled",fillcolor="#ffcc99"];'
+ % (s_id, s_title)
+ )
for t_id in s.transitions:
transitions_with_init_state.append(t_id)
try:
t = wf.transitions[t_id]
except KeyError:
- out.append(('# transition "%s" from state "%s" '
- 'is missing' % (t_id, s_id)))
+ out.append(
+ ('# transition "%s" from state "%s" ' "is missing" % (t_id, s_id))
+ )
continue
new_state_id = t.new_state_id
@@ -153,11 +160,10 @@ def getPOT(wf):
transitions[key] = value
for k, v in transitions.items():
- out.append('"%s" -> "%s" [label="%s"];' % (k[0], k[1],
- ',\\n'.join(v)))
+ out.append('"%s" -> "%s" [label="%s"];' % (k[0], k[1], ",\\n".join(v)))
- out.append('}')
- return '\n'.join(out)
+ out.append("}")
+ return "\n".join(out)
def getGraph(workflow, format="gif"):
@@ -166,19 +172,18 @@ def getGraph(workflow, format="gif"):
http://www.openflow.it/wwwopenflow/Download/OpenFlowEditor_0_4.tgz
"""
pot = getPOT(workflow)
- portal_properties = getToolByName(workflow, 'portal_properties')
- encoding = portal_properties.site_properties.getProperty(
- 'default_charset', 'utf-8')
- if isinstance(pot, unicode):
+ portal_properties = getToolByName(workflow, "portal_properties")
+ encoding = portal_properties.site_properties.getProperty("default_charset", "utf-8")
+ if isinstance(pot, six.text_type):
pot = pot.encode(encoding)
- infile = mktemp('.dot')
- f = open(infile, 'w')
+ infile = mktemp(".dot")
+ f = open(infile, "wb")
f.write(pot)
f.close()
- outfile = mktemp('.gif')
- os.system('%s -Tgif -o %s %s' % (bin, outfile, infile))
- out = open(outfile, 'rb')
+ outfile = mktemp(".gif")
+ os.system("%s -Tgif -o %s %s" % (bin, outfile, infile))
+ out = open(outfile, "rb")
result = out.read()
out.close()
os.remove(outfile)
diff --git a/src/plone/app/workflowmanager/permissions.py b/src/plone/app/workflowmanager/permissions.py
index 68121d5..dc26365 100644
--- a/src/plone/app/workflowmanager/permissions.py
+++ b/src/plone/app/workflowmanager/permissions.py
@@ -8,14 +8,14 @@ def managed_permissions(wfid=None):
return []
site = getSite()
- wtool = getToolByName(site, 'portal_workflow')
+ wtool = getToolByName(site, "portal_workflow")
wf = wtool.get(wfid)
items = []
for permission in wf.permissions:
data = {}
- data['perm'] = permission
- data['name'] = _(permission)
- data['description'] = u''
+ data["perm"] = permission
+ data["name"] = _(permission)
+ data["description"] = u""
items.append(data)
return items
@@ -24,6 +24,6 @@ def managed_permissions(wfid=None):
def allowed_guard_permissions(wfid=None):
res = {}
for item in managed_permissions(wfid):
- res[item.get('name')] = item.get('name')
+ res[item.get("name")] = item.get("name")
return res
diff --git a/src/plone/app/workflowmanager/profiles/default/controlpanel.xml b/src/plone/app/workflowmanager/profiles/default/controlpanel.xml
index 4c66457..11f9b58 100644
--- a/src/plone/app/workflowmanager/profiles/default/controlpanel.xml
+++ b/src/plone/app/workflowmanager/profiles/default/controlpanel.xml
@@ -1,15 +1,21 @@
-
\ No newline at end of file
+
+
diff --git a/src/plone/app/workflowmanager/profiles/default/metadata.xml b/src/plone/app/workflowmanager/profiles/default/metadata.xml
index 5476488..a036d4b 100644
--- a/src/plone/app/workflowmanager/profiles/default/metadata.xml
+++ b/src/plone/app/workflowmanager/profiles/default/metadata.xml
@@ -1,7 +1,5 @@
1
-
- profile-plone.app.jquerytools:default
-
+
diff --git a/src/plone/app/workflowmanager/profiles/default/registry.xml b/src/plone/app/workflowmanager/profiles/default/registry.xml
index 123a0cf..a66c262 100644
--- a/src/plone/app/workflowmanager/profiles/default/registry.xml
+++ b/src/plone/app/workflowmanager/profiles/default/registry.xml
@@ -1,10 +1,10 @@
-
-
- Layouts
-
-
-
-
+
+
+ Layouts
+
+
+
+
diff --git a/src/plone/app/workflowmanager/profiles/uninstall/controlpanel.xml b/src/plone/app/workflowmanager/profiles/uninstall/controlpanel.xml
index 707f351..e438ad0 100644
--- a/src/plone/app/workflowmanager/profiles/uninstall/controlpanel.xml
+++ b/src/plone/app/workflowmanager/profiles/uninstall/controlpanel.xml
@@ -1,15 +1,22 @@
-
\ No newline at end of file
+
diff --git a/src/plone/app/workflowmanager/profiles/uninstall/registry.xml b/src/plone/app/workflowmanager/profiles/uninstall/registry.xml
index c4deda6..1d4f2db 100644
--- a/src/plone/app/workflowmanager/profiles/uninstall/registry.xml
+++ b/src/plone/app/workflowmanager/profiles/uninstall/registry.xml
@@ -1,9 +1,11 @@
-
-
- Layouts
-
-
-
-
+
+
+ Layouts
+
+
+
+
diff --git a/src/plone/app/workflowmanager/testing.py b/src/plone/app/workflowmanager/testing.py
index 45d7035..4cc7c16 100644
--- a/src/plone/app/workflowmanager/testing.py
+++ b/src/plone/app/workflowmanager/testing.py
@@ -1,87 +1,106 @@
-from plone.app.testing import TEST_USER_NAME, PLONE_FIXTURE, login, \
- IntegrationTesting, PloneSandboxLayer, applyProfile, setRoles, \
- TEST_USER_ID, TEST_USER_PASSWORD, FunctionalTesting
-
-#from Products.CMFCore.utils import getToolByName
-from zope.interface.declarations import alsoProvides
+from plone.app.contentrules.actions.notify import NotifyAction
+from plone.app.testing import applyProfile
+from plone.app.testing import FunctionalTesting
+from plone.app.testing import IntegrationTesting
+from plone.app.testing import login
+from plone.app.testing import PLONE_FIXTURE
+from plone.app.testing import PloneSandboxLayer
+from plone.app.testing import setRoles
+from plone.app.testing import TEST_USER_ID
+from plone.app.testing import TEST_USER_NAME
+from plone.app.testing import TEST_USER_PASSWORD
+from plone.app.workflowmanager.actionmanager import ActionManager
+from plone.app.workflowmanager.browser.actions import AddActionView
+from plone.app.workflowmanager.browser.workflow import AddWorkflow
+from plone.keyring.interfaces import IKeyManager
+from plone.protect.authenticator import createToken
+from zope.annotation.interfaces import IAttributeAnnotatable
from zope.component import getUtility
from zope.configuration import xmlconfig
+# from Products.CMFCore.utils import getToolByName
+from zope.interface.declarations import alsoProvides
from zope.publisher.browser import TestRequest
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-from plone.app.workflowmanager.browser.workflow import AddWorkflow
-from plone.app.workflowmanager.browser.actions import AddActionView
-from plone.app.workflowmanager.actionmanager import ActionManager
-from plone.app.contentrules.actions.notify import NotifyAction
-from plone.keyring.interfaces import IKeyManager
-from plone.protect.authenticator import createToken
+import hmac
+import unittest
-import unittest2 as unittest
try:
from hashlib import sha1 as sha
except ImportError:
import sha
-import hmac
class ManagerFixture(PloneSandboxLayer):
- defaultBases = (PLONE_FIXTURE, )
+ defaultBases = (PLONE_FIXTURE,)
def setUpZope(self, app, configurationContext):
# Load ZCML
import plone.app.workflowmanager
- xmlconfig.file('configure.zcml',
- plone.app.workflowmanager, context=configurationContext)
+
+ xmlconfig.file(
+ "configure.zcml", plone.app.workflowmanager, context=configurationContext
+ )
def setUpPloneSite(self, portal):
- applyProfile(portal, 'plone.app.workflowmanager:default')
- setRoles(portal, TEST_USER_ID, ['Manager', 'Owner'])
+ applyProfile(portal, "plone.app.workflowmanager:default")
+ setRoles(portal, TEST_USER_ID, ["Manager", "Owner"])
import transaction
+
transaction.commit()
login(portal, TEST_USER_NAME)
MANAGER_FIXTURE = ManagerFixture()
INTEGRATION_MANAGER_TESTING = IntegrationTesting(
- bases=(MANAGER_FIXTURE, ), name='INTEGRATION_MANAGER_TESTING')
+ bases=(MANAGER_FIXTURE,), name="INTEGRATION_MANAGER_TESTING"
+)
FUNCTIONAL_MANAGER_TESTING = FunctionalTesting(
- bases=(MANAGER_FIXTURE,), name="FUNCTIONAL_MANAGER_TESTING")
+ bases=(MANAGER_FIXTURE,), name="FUNCTIONAL_MANAGER_TESTING"
+)
def browserLogin(portal, browser, username=None, password=None):
handleErrors = browser.handleErrors
try:
browser.handleErrors = False
- browser.open(portal.absolute_url() + '/login_form')
+ browser.open(portal.absolute_url() + "/login_form")
if username is None:
username = TEST_USER_NAME
if password is None:
password = TEST_USER_PASSWORD
- browser.addHeader('Authorization',
- 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD,))
+ browser.addHeader(
+ "Authorization", "Basic %s:%s" % (TEST_USER_NAME, TEST_USER_PASSWORD,)
+ )
finally:
browser.handleErrors = handleErrors
class BaseTest(unittest.TestCase):
-
def setUp(self):
- portal = self.layer['portal']
-
- req = self.getRequest({'workflow-name': 'workflow-1',
- 'form.actions.add': 'create',
- 'clone-from-workflow': 'simple_publication_workflow'}, True)
+ portal = self.layer["portal"]
+
+ req = self.getRequest(
+ {
+ "workflow-name": "workflow-1",
+ "form.actions.add": "create",
+ "clone-from-workflow": "simple_publication_workflow",
+ },
+ True,
+ )
alsoProvides(req, IAttributeAnnotatable)
AddWorkflow(portal, req)()
# add some rules/actions
- req = self.getRequest({
- 'form.actions.add': 'Add',
- 'selected-transition': 'publish',
- 'selected-state': 'published',
- 'selected-workflow': 'workflow-1'}, True)
+ req = self.getRequest(
+ {
+ "form.actions.add": "Add",
+ "selected-transition": "publish",
+ "selected-state": "published",
+ "selected-workflow": "workflow-1",
+ },
+ True,
+ )
view = AddActionView(portal, req)
view()
self.selected_workflow = view.selected_workflow
@@ -91,17 +110,16 @@ def setUp(self):
am = ActionManager()
rule = am.get_rule(self.selected_transition)
action = NotifyAction()
- action.message = 'foobar'
- action.message_type = 'info'
+ action.message = "foobar"
+ action.message_type = "info"
rule.actions.append(action)
def getRequest(self, form={}, authentic=False):
if authentic:
- form['_authenticator'] = createToken()
+ form["_authenticator"] = createToken()
- req = TestRequest(form=form, environ={
- 'SERVER_URL': 'http://nohost',
- 'HTTP_HOST': 'nohost'
- })
+ req = TestRequest(
+ form=form, environ={"SERVER_URL": "http://nohost", "HTTP_HOST": "nohost"}
+ )
alsoProvides(req, IAttributeAnnotatable)
return req
diff --git a/src/plone/app/workflowmanager/tests/__init__.py b/src/plone/app/workflowmanager/tests/__init__.py
index 1023dcd..188517f 100644
--- a/src/plone/app/workflowmanager/tests/__init__.py
+++ b/src/plone/app/workflowmanager/tests/__init__.py
@@ -1,7 +1,4 @@
-
-
class TestResponse(object):
-
def __init__(self):
self.headers = {}
self.redirect = False
diff --git a/src/plone/app/workflowmanager/tests/robot/CustomSeleniumLibrary.py b/src/plone/app/workflowmanager/tests/robot/CustomSeleniumLibrary.py
index bd73de4..5c26d02 100644
--- a/src/plone/app/workflowmanager/tests/robot/CustomSeleniumLibrary.py
+++ b/src/plone/app/workflowmanager/tests/robot/CustomSeleniumLibrary.py
@@ -1,10 +1,11 @@
+from __future__ import print_function
from Selenium2Library import Selenium2Library
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
+from selenium.webdriver.support import expected_conditions as EC
+from selenium.webdriver.support.ui import WebDriverWait
-class CustomSeleniumLibrary(Selenium2Library):
+class CustomSeleniumLibrary(Selenium2Library):
def clear_element(self, element):
self._current_browser().find_element_by_id(element).clear()
return True
@@ -15,21 +16,29 @@ def get_newest_tinyMCE_window(self):
return True
def get_new_window_id(self):
- frame = self._current_browser().execute_script('return tinyMCE.activeEditor.windowManager._frontWindow().iframeElement.id')
+ frame = self._current_browser().execute_script(
+ "return tinyMCE.activeEditor.windowManager._frontWindow().iframeElement.id"
+ )
return frame
def handle_prompts(self):
# Thanks to nemesys on StackOverflow :)
try:
- WebDriverWait(self._current_browser(), 3).until(EC.alert_is_present(), 'Failure')
+ WebDriverWait(self._current_browser(), 3).until(
+ EC.alert_is_present(), "Failure"
+ )
alert = self._current_browser().switch_to_alert()
alert.accept()
- print "alert accepted"
+ print("alert accepted")
except TimeoutException:
raise AssertionError("No confirmation alert.")
def wait_for_new_window(self):
wait = WebDriverWait(self._current_browser(), 10)
- wait.until(lambda driver: self._current_browser().find_element_by_id(self.get_new_window_id()))
+ wait.until(
+ lambda driver: self._current_browser().find_element_by_id(
+ self.get_new_window_id()
+ )
+ )
return True
diff --git a/src/plone/app/workflowmanager/tests/test_actions.py b/src/plone/app/workflowmanager/tests/test_actions.py
index d42c23a..baf1504 100644
--- a/src/plone/app/workflowmanager/tests/test_actions.py
+++ b/src/plone/app/workflowmanager/tests/test_actions.py
@@ -1,20 +1,17 @@
-import unittest2 as unittest
-
-from zope.component import getUtility, getMultiAdapter
-
-from Products.CMFCore.utils import getToolByName
-
-from plone.app.testing import TEST_USER_NAME
from plone.app.testing import login
-
-from plone.contentrules.rule.interfaces import IRuleAction
-
-from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
-from plone.app.workflowmanager.testing import BaseTest
-from plone.app.workflowmanager.browser.actions import AddActionView
-from plone.app.workflowmanager.browser.actions import DeleteActionView
+from plone.app.testing import TEST_USER_NAME
from plone.app.workflowmanager.actionmanager import ActionManager
from plone.app.workflowmanager.actionmanager import RuleAdapter
+from plone.app.workflowmanager.browser.actions import AddActionView
+from plone.app.workflowmanager.browser.actions import DeleteActionView
+from plone.app.workflowmanager.testing import BaseTest
+from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
+from plone.contentrules.rule.interfaces import IRuleAction
+from Products.CMFCore.utils import getToolByName
+from zope.component import getMultiAdapter
+from zope.component import getUtility
+
+import unittest
class TestActions(BaseTest):
@@ -22,12 +19,16 @@ class TestActions(BaseTest):
layer = INTEGRATION_MANAGER_TESTING
def test_adding_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'form.actions.add': 'Add',
- 'selected-transition': 'retract',
- 'selected-workflow': 'workflow-1'}, True)
+ req = self.getRequest(
+ {
+ "form.actions.add": "Add",
+ "selected-transition": "retract",
+ "selected-workflow": "workflow-1",
+ },
+ True,
+ )
view = AddActionView(portal, req)
view()
am = ActionManager()
@@ -36,48 +37,54 @@ def test_adding_action(self):
@unittest.skip("'rule' is None before and after calling view.")
def test_adding_action_fails(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-transition': 'retract',
- 'selected-workflow': 'workflow-1'}, True)
+ req = self.getRequest(
+ {"selected-transition": "retract", "selected-workflow": "workflow-1"}, True
+ )
view = AddActionView(portal, req)
try:
view()
- except AttributeError, ex:
- self.assertTrue("'TestRequest' object has no attribute 'RESPONSE'"
- in str(ex))
+ except AttributeError as ex:
+ self.assertTrue(
+ "'TestRequest' object has no attribute 'RESPONSE'" in str(ex)
+ )
am = ActionManager()
rule = am.get_rule(view.selected_transition)
self.assertTrue(rule is None)
@unittest.skip("'rule' is None before and after calling view.")
def test_accessing_adding_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-transition': 'publish',
- 'selected-workflow': 'workflow-1'}, True)
+ req = self.getRequest(
+ {"selected-transition": "publish", "selected-workflow": "workflow-1"}, True
+ )
view = DeleteActionView(portal, req)
try:
view()
- except AttributeError, ex:
- self.assertTrue("'TestRequest' object has no attribute 'RESPONSE'"
- in str(ex))
+ except AttributeError as ex:
+ self.assertTrue(
+ "'TestRequest' object has no attribute 'RESPONSE'" in str(ex)
+ )
am = ActionManager()
rule = am.get_rule(view.selected_transition)
self.assertTrue(len(rule.actions) == 1)
def test_removing_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'form.actions.delete': 'Delete',
- 'selected-transition': 'publish',
- 'selected-workflow': 'workflow-1',
- 'action_index': '0'}, True)
+ req = self.getRequest(
+ {
+ "form.actions.delete": "Delete",
+ "selected-transition": "publish",
+ "selected-workflow": "workflow-1",
+ "action_index": "0",
+ },
+ True,
+ )
view = DeleteActionView(portal, req)
view()
am = ActionManager()
@@ -85,13 +92,17 @@ def test_removing_action(self):
self.assertEquals(len(rule.actions), 0)
def test_cancel_removing_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'form.actions.cancel': 'Cancel',
- 'selected-transition': 'publish',
- 'selected-workflow': 'workflow-1'}, True)
+ req = self.getRequest(
+ {
+ "form.actions.cancel": "Cancel",
+ "selected-transition": "publish",
+ "selected-workflow": "workflow-1",
+ },
+ True,
+ )
view = DeleteActionView(portal, req)
view()
am = ActionManager()
@@ -99,115 +110,117 @@ def test_cancel_removing_action(self):
self.assertEquals(len(rule.actions), 1)
def test_action_manager_to_create_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
am = ActionManager()
- pw = getToolByName(portal, 'portal_workflow')
- workflow = pw['simple_publication_workflow']
- transition = workflow.transitions['publish']
+ pw = getToolByName(portal, "portal_workflow")
+ workflow = pw["simple_publication_workflow"]
+ transition = workflow.transitions["publish"]
am.delete_rule_for(transition)
rule = am.create(transition)
- element = getUtility(IRuleAction, name='plone.actions.Copy')
- adding = getMultiAdapter((rule.rule, self.layer['request']),
- name='+action')
- addview = getMultiAdapter((adding, self.layer['request']),
- name=element.addview)
+ element = getUtility(IRuleAction, name="plone.actions.Copy")
+ adding = getMultiAdapter((rule.rule, self.layer["request"]), name="+action")
+ addview = getMultiAdapter((adding, self.layer["request"]), name=element.addview)
try:
createAndAdd = addview.form_instance.createAndAdd
except AttributeError:
createAndAdd = addview.createAndAdd
- createAndAdd(data={'target_folder': '/target'})
+ createAndAdd(data={"target_folder": "/target"})
self.assertEquals(len(rule.actions), 1)
def test_action_manager_get_action(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
am = ActionManager()
- pw = getToolByName(portal, 'portal_workflow')
- workflow = pw['simple_publication_workflow']
- transition = workflow.transitions['publish']
+ pw = getToolByName(portal, "portal_workflow")
+ workflow = pw["simple_publication_workflow"]
+ transition = workflow.transitions["publish"]
am.delete_rule_for(transition)
rule = am.create(transition)
- element = getUtility(IRuleAction, name='plone.actions.Copy')
- adding = getMultiAdapter((rule.rule, self.layer['request']),
- name='+action')
- addview = getMultiAdapter((adding, self.layer['request']),
- name=element.addview)
+ element = getUtility(IRuleAction, name="plone.actions.Copy")
+ adding = getMultiAdapter((rule.rule, self.layer["request"]), name="+action")
+ addview = getMultiAdapter((adding, self.layer["request"]), name=element.addview)
try:
createAndAdd = addview.form_instance.createAndAdd
except AttributeError:
createAndAdd = addview.createAndAdd
- createAndAdd(data={'target_folder': '/target'})
+ createAndAdd(data={"target_folder": "/target"})
ra = RuleAdapter(rule, transition)
action = ra.get_action(0)
- self.assertEquals(action.element, 'plone.actions.Copy')
+ self.assertEquals(action.element, "plone.actions.Copy")
def test_action_manager_action_index(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
am = ActionManager()
- pw = getToolByName(portal, 'portal_workflow')
- workflow = pw['simple_publication_workflow']
- transition = workflow.transitions['publish']
+ pw = getToolByName(portal, "portal_workflow")
+ workflow = pw["simple_publication_workflow"]
+ transition = workflow.transitions["publish"]
rule = am.create(transition)
- element = getUtility(IRuleAction, name='plone.actions.Copy')
- adding = getMultiAdapter((rule.rule, self.layer['request']),
- name='+action')
- addview = getMultiAdapter((adding, self.layer['request']),
- name=element.addview)
+ element = getUtility(IRuleAction, name="plone.actions.Copy")
+ adding = getMultiAdapter((rule.rule, self.layer["request"]), name="+action")
+ addview = getMultiAdapter((adding, self.layer["request"]), name=element.addview)
try:
createAndAdd = addview.form_instance.createAndAdd
except AttributeError:
createAndAdd = addview.createAndAdd
- createAndAdd(data={'target_folder': '/target'})
+ createAndAdd(data={"target_folder": "/target"})
ra = RuleAdapter(rule, transition)
action = ra.get_action(0)
self.assertEquals(ra.action_index(action), 0)
def test_action_manager_action_url(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
am = ActionManager()
- pw = getToolByName(portal, 'portal_workflow')
- workflow = pw['simple_publication_workflow']
- transition = workflow.transitions['publish']
+ pw = getToolByName(portal, "portal_workflow")
+ workflow = pw["simple_publication_workflow"]
+ transition = workflow.transitions["publish"]
rule = am.create(transition)
- element = getUtility(IRuleAction, name='plone.actions.Copy')
- adding = getMultiAdapter((rule.rule, self.layer['request']),
- name='+action')
- addview = getMultiAdapter((adding, self.layer['request']),
- name=element.addview)
+ element = getUtility(IRuleAction, name="plone.actions.Copy")
+ adding = getMultiAdapter((rule.rule, self.layer["request"]), name="+action")
+ addview = getMultiAdapter((adding, self.layer["request"]), name=element.addview)
try:
createAndAdd = addview.form_instance.createAndAdd
except AttributeError:
createAndAdd = addview.createAndAdd
- createAndAdd(data={'target_folder': '/target'})
+ createAndAdd(data={"target_folder": "/target"})
ra = RuleAdapter(rule, transition)
action = ra.get_action(0)
- self.assertTrue(rule.rule.id in ra.action_url(action) and \
- '++0' in ra.action_url(action))
+ self.assertTrue(
+ rule.rule.id in ra.action_url(action) and "++0" in ra.action_url(action)
+ )
def test_action_manager_available_actions(self):
am = ActionManager()
action_names = [a.title for a in am.available_actions]
- self.assertTrue(action_names == [u'Logger', u'Notify user',
- u'Copy to folder', u'Move to folder', u'Delete object',
- u'Transition workflow state', u'Send email'])
+ self.assertTrue(
+ action_names
+ == [
+ u"Logger",
+ u"Notify user",
+ u"Copy to folder",
+ u"Move to folder",
+ u"Delete object",
+ u"Transition workflow state",
+ u"Send email",
+ ]
+ )
def test_action_manager_delete_rule(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
am = ActionManager()
- pw = getToolByName(portal, 'portal_workflow')
- workflow = pw['simple_publication_workflow']
- transition = workflow.transitions['publish']
+ pw = getToolByName(portal, "portal_workflow")
+ workflow = pw["simple_publication_workflow"]
+ transition = workflow.transitions["publish"]
am.create(transition)
am.delete_rule_for(transition)
diff --git a/src/plone/app/workflowmanager/tests/test_controlpanel.py b/src/plone/app/workflowmanager/tests/test_controlpanel.py
index 97f48b2..5f0beef 100644
--- a/src/plone/app/workflowmanager/tests/test_controlpanel.py
+++ b/src/plone/app/workflowmanager/tests/test_controlpanel.py
@@ -1,10 +1,9 @@
-import unittest2 as unittest
-
from AccessControl import Unauthorized
-
-from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
-from plone.app.workflowmanager.testing import BaseTest
from plone.app.workflowmanager.browser.controlpanel import Base
+from plone.app.workflowmanager.testing import BaseTest
+from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
+
+import unittest
class TestControlPanel(BaseTest):
@@ -12,45 +11,64 @@ class TestControlPanel(BaseTest):
layer = INTEGRATION_MANAGER_TESTING
def test_base_defaults_to_first_workflow_if_list(self):
- view = Base(self.layer['portal'],
- self.getRequest(
- {'selected-workflow': ['simple_publication_workflow']}))
+ view = Base(
+ self.layer["portal"],
+ self.getRequest({"selected-workflow": ["simple_publication_workflow"]}),
+ )
self.assertTrue(view.selected_workflow is not None)
def test_base_defaults_to_first_state_if_list(self):
- view = Base(self.layer['portal'], self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']}))
+ view = Base(
+ self.layer["portal"],
+ self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ ),
+ )
self.assertTrue(view.selected_state is not None)
def test_base_defaults_to_first_transition_if_list(self):
- view = Base(self.layer['portal'], self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-transition': ['publish']}))
+ view = Base(
+ self.layer["portal"],
+ self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-transition": ["publish"],
+ }
+ ),
+ )
self.assertTrue(view.selected_transition is not None)
def test_base_available_transitions_always_returns_a_list(self):
- view = Base(self.layer['portal'], self.getRequest({
- 'selected-workflow': ['one_state_workflow']}))
+ view = Base(
+ self.layer["portal"],
+ self.getRequest({"selected-workflow": ["one_state_workflow"]}),
+ )
self.assertEquals(type(view.available_transitions), list)
def test_base_available_states_always_returns_a_list(self):
- view = Base(self.layer['portal'], self.getRequest({}))
+ view = Base(self.layer["portal"], self.getRequest({}))
self.assertEquals(type(view.available_states), list)
def test_authorize_raises_unauthorized(self):
- view = Base(self.layer['portal'], self.getRequest({}))
+ view = Base(self.layer["portal"], self.getRequest({}))
self.assertRaises(Unauthorized, view.authorize)
def test_get_transition(self):
- view = Base(self.layer['portal'], self.getRequest({
- 'selected-workflow': ['simple_publication_workflow']}))
- self.assertTrue(view.get_transition('publish') is not None)
+ view = Base(
+ self.layer["portal"],
+ self.getRequest({"selected-workflow": ["simple_publication_workflow"]}),
+ )
+ self.assertTrue(view.get_transition("publish") is not None)
def test_get_transition_is_none_if_not_found(self):
- view = Base(self.layer['portal'], self.getRequest({
- 'selected-workflow' : ['simple_publication_workflow']}))
- self.assertTrue(view.get_transition('foobar') is None)
+ view = Base(
+ self.layer["portal"],
+ self.getRequest({"selected-workflow": ["simple_publication_workflow"]}),
+ )
+ self.assertTrue(view.get_transition("foobar") is None)
def test_suite():
diff --git a/src/plone/app/workflowmanager/tests/test_docs.py b/src/plone/app/workflowmanager/tests/test_docs.py
index 3737969..2dcd41c 100644
--- a/src/plone/app/workflowmanager/tests/test_docs.py
+++ b/src/plone/app/workflowmanager/tests/test_docs.py
@@ -1,27 +1,34 @@
-import doctest
-from plone.testing import layered
-import unittest2 as unittest
from plone.app.workflowmanager.testing import FUNCTIONAL_MANAGER_TESTING
-import pprint
+from plone.testing import layered
+
+import doctest
import interlude
+import pprint
+import unittest
+
-optionflags = (doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE)
+optionflags = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE
normal_testfiles = [
- '../standardtiles.txt',
- '../head.txt',
+ "../standardtiles.txt",
+ "../head.txt",
]
testtype_testfiles = [
- '../field.txt',
+ "../field.txt",
]
def test_suite():
suite = unittest.TestSuite()
- suite.addTests([
- layered(doctest.DocFileSuite('../browser.txt',
- optionflags=optionflags,
- globs={'interact': interlude.interact,
- 'pprint': pprint.pprint},
- ),
- layer=FUNCTIONAL_MANAGER_TESTING)])
+ suite.addTests(
+ [
+ layered(
+ doctest.DocFileSuite(
+ "../browser.txt",
+ optionflags=optionflags,
+ globs={"interact": interlude.interact, "pprint": pprint.pprint},
+ ),
+ layer=FUNCTIONAL_MANAGER_TESTING,
+ )
+ ]
+ )
return suite
diff --git a/src/plone/app/workflowmanager/tests/test_layouts.py b/src/plone/app/workflowmanager/tests/test_layouts.py
index 26ed530..4e92031 100644
--- a/src/plone/app/workflowmanager/tests/test_layouts.py
+++ b/src/plone/app/workflowmanager/tests/test_layouts.py
@@ -1,22 +1,18 @@
-import unittest2 as unittest
-
-from zope.component import getUtility, getMultiAdapter
-
-from Products.CMFCore.utils import getToolByName
-
-from plone.app.testing import TEST_USER_NAME
from plone.app.testing import login
-
-from plone.contentrules.rule.interfaces import IRuleAction
-
-from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
-from plone.app.workflowmanager.testing import BaseTest
-from plone.app.workflowmanager.browser.actions import AddActionView
-from plone.app.workflowmanager.browser.actions import DeleteActionView
+from plone.app.testing import TEST_USER_NAME
from plone.app.workflowmanager.actionmanager import ActionManager
from plone.app.workflowmanager.actionmanager import RuleAdapter
-
+from plone.app.workflowmanager.browser.actions import AddActionView
+from plone.app.workflowmanager.browser.actions import DeleteActionView
from plone.app.workflowmanager.browser.layout import GraphLayout
+from plone.app.workflowmanager.testing import BaseTest
+from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
+from plone.contentrules.rule.interfaces import IRuleAction
+from Products.CMFCore.utils import getToolByName
+from zope.component import getMultiAdapter
+from zope.component import getUtility
+
+import unittest
class TestActions(BaseTest):
@@ -24,14 +20,17 @@ class TestActions(BaseTest):
layer = INTEGRATION_MANAGER_TESTING
def test_prop_sheet_exists(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
sheetName = gl.getPropSheetName()
props.addPropertySheet(sheetName)
@@ -40,16 +39,19 @@ def test_prop_sheet_exists(self):
self.assertTrue(exists)
def test_create_prop_sheet(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
sheetName = gl.getPropSheetName()
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
exists = gl.propSheetExists(sheetName)
self.assertFalse(exists)
@@ -60,91 +62,108 @@ def test_create_prop_sheet(self):
self.assertTrue(exists)
def test_layout_exists(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
sheetName = gl.getPropSheetName()
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
props.addPropertySheet(sheetName)
- gl.setWorkflow('simple_publication_workflow')
+ gl.setWorkflow("simple_publication_workflow")
- props[sheetName].manage_addProperty('simple_publication_workflow', '','text')
+ props[sheetName].manage_addProperty("simple_publication_workflow", "", "text")
exists = gl.layoutExists()
- self.assertEqual( exists, 1 )
+ self.assertEqual(exists, 1)
def test_create_layout(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
sheetName = gl.getPropSheetName()
- gl.setWorkflow('simple_publication_workflow')
+ gl.setWorkflow("simple_publication_workflow")
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
props.addPropertySheet(sheetName)
-
+
gl.createLayout()
- exists = props[sheetName].hasProperty('simple_publication_workflow')
- self.assertEqual( exists, 1 )
+ exists = props[sheetName].hasProperty("simple_publication_workflow")
+ self.assertEqual(exists, 1)
def test_get_layout(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
sheetName = gl.getPropSheetName()
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
props.addPropertySheet(sheetName)
sheetName = gl.getPropSheetName()
- props[sheetName].manage_addProperty('simple_publication_workflow', 'test', 'text')
+ props[sheetName].manage_addProperty(
+ "simple_publication_workflow", "test", "text"
+ )
output = gl.getLayout()
- self.assertEqual( output, 'test' )
+ self.assertEqual(output, "test")
def test_get_layout(self):
- portal = self.layer['portal']
+ portal = self.layer["portal"]
login(portal, TEST_USER_NAME)
- req = self.getRequest({
- 'selected-workflow': ['simple_publication_workflow'],
- 'selected-state': ['published']})
+ req = self.getRequest(
+ {
+ "selected-workflow": ["simple_publication_workflow"],
+ "selected-state": ["published"],
+ }
+ )
gl = GraphLayout(portal, req)
sheetName = gl.getPropSheetName()
- gl.setWorkflow('simple_publication_workflow')
+ gl.setWorkflow("simple_publication_workflow")
- props = getToolByName(portal, 'portal_properties')
+ props = getToolByName(portal, "portal_properties")
props.addPropertySheet(sheetName)
sheetName = gl.getPropSheetName()
- props[sheetName].manage_addProperty('simple_publication_workflow', 'test', 'text')
+ props[sheetName].manage_addProperty(
+ "simple_publication_workflow", "test", "text"
+ )
output = gl.getLayout()
gl.editLayout("words words words")
output2 = gl.getLayout()
-
- self.assertNotEqual( output, output2 )
+
+ self.assertNotEqual(output, output2)
+
def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)
diff --git a/src/plone/app/workflowmanager/tests/test_utils.py b/src/plone/app/workflowmanager/tests/test_utils.py
index 826a51f..fa8bb7c 100644
--- a/src/plone/app/workflowmanager/tests/test_utils.py
+++ b/src/plone/app/workflowmanager/tests/test_utils.py
@@ -1,10 +1,9 @@
-import unittest2 as unittest
-
-from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
from plone.app.workflowmanager.testing import BaseTest
-
+from plone.app.workflowmanager.testing import INTEGRATION_MANAGER_TESTING
from plone.app.workflowmanager.utils import generate_id
+import unittest
+
class TestUtils(BaseTest):
@@ -17,14 +16,14 @@ def test_generate_id(self):
self.assertEquals(title, new_id)
def test_generate_id_with_ids(self):
- title = '1'
- ids = ['1', '2', '3']
+ title = "1"
+ ids = ["1", "2", "3"]
new_id = generate_id(title, ids)
- self.assertEquals(title + '-1', new_id)
+ self.assertEquals(title + "-1", new_id)
ids.append(new_id)
new_id = generate_id(title, ids)
- self.assertEquals(title + '-2', new_id)
+ self.assertEquals(title + "-2", new_id)
def test_suite():
diff --git a/src/plone/app/workflowmanager/utils.py b/src/plone/app/workflowmanager/utils.py
index a34738d..d147c2d 100644
--- a/src/plone/app/workflowmanager/utils.py
+++ b/src/plone/app/workflowmanager/utils.py
@@ -5,7 +5,7 @@ def generate_id(org_id, ids):
count = 1
new_id = org_id
while new_id in ids:
- new_id = org_id + '-' + str(count)
+ new_id = org_id + "-" + str(count)
count += 1
return new_id
@@ -33,18 +33,17 @@ def clone_transition(transition, clone):
def clone_state(state, clone):
state.transitions = clone.transitions[:]
- state.permission_roles = clone.permission_roles and \
- clone.permission_roles.copy() or None
+ state.permission_roles = (
+ clone.permission_roles and clone.permission_roles.copy() or None
+ )
state.group_roles = clone.group_roles and clone.group_roles.copy() or None
state.var_values = clone.var_values and clone.var_values.copy() or None
state.description = clone.description
def generateRuleName(transition):
- return '--workflowmanager--%s--%s' % (
- transition.getWorkflow().id,
- transition.id)
+ return "--workflowmanager--%s--%s" % (transition.getWorkflow().id, transition.id)
+
def generateRuleNameOld(transition):
- return '--workflowmanager--%s' % (
- transition.id)
+ return "--workflowmanager--%s" % (transition.id)