Execute multi-actions in the background #33748

This commit is contained in:
Nicolas Demonte 2019-10-25 14:29:32 +02:00
parent 789d8f1e0b
commit 9be18c4b00
5 changed files with 138 additions and 85 deletions

View File

@ -53,6 +53,7 @@ setup(
'collective.onlogin',
'collective.solr',
'collective.task',
'collective.taskqueue',
'five.grok',
'pfwbged.basecontent',
'pfwbged.collection',

View File

@ -1,8 +1,14 @@
import pickle
from copy import deepcopy
from Products.Five.browser import BrowserView
import z3c.form
from collective.taskqueue import taskqueue
from z3c.form import button
import zope.event
from zope.component import getUtility
from zope.i18nmessageid.message import MessageFactory
from plone import api
@ -13,33 +19,14 @@ from plone.stringinterp.adapters import _recursiveGetMembersFromIds
from collective.task import _
class AddInformation(DefaultAddForm):
"""Custom add information view"""
portal_type = "information"
@property
def action(self):
return self.request.getURL() + '?documents=' + self.request.documents
@button.buttonAndHandler(_('Add'), name='add')
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
for document_id in self.request.documents.split(','):
base_document = api.content.get(str(document_id))
self.add_info(base_document, data)
self._finishedAdd = True
return
def add_info(self, base_document, data):
class BackgroundAddInformationView(BrowserView):
def __call__(self):
base_document = self.context
data = pickle.load(self.request.stdin)
portal = api.portal.get()
objs = []
seen = {}
for responsible in data['responsible']:
group = api.group.get(responsible)
if group is not None:
@ -63,4 +50,28 @@ class AddInformation(DefaultAddForm):
createContentInContainer(base_document, 'information', **_data)
seen[responsible] = True
print 'seen:', seen
class AddInformation(DefaultAddForm):
"""Custom add information view"""
portal_type = "information"
@property
def action(self):
return self.request.getURL() + '?documents=' + self.request.documents
@button.buttonAndHandler(_('Add'), name='add')
def handleAdd(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorsMessage
return
for document_id in self.request.documents.split(','):
taskqueue.add(
'{}/background_add_information'.format(document_id),
payload=pickle.dumps(data),
)
self._finishedAdd = True
return

View File

@ -1,19 +1,53 @@
import pickle
from Products.Five.browser import BrowserView
from zope.i18n import translate
from collective.taskqueue import taskqueue
from copy import deepcopy
from plone import api
from plone.dexterity.browser.add import DefaultAddForm
from plone.dexterity.utils import addContentToContainer, getAdditionalSchemata
from plone.dexterity.utils import createContent
from z3c.form.interfaces import HIDDEN_MODE
from zope.annotation.interfaces import IAnnotations
import zope.event
import zope.lifecycleevent
from z3c.form import button
from pfwbged.policy import _
class BackgroundAskValidationView(BrowserView):
def __call__(self):
base_document = self.context
data = pickle.load(self.request.stdin)
for child in reversed(base_document.values()):
if child.portal_type == 'dmsmainfile':
last_version = child
break
_data = deepcopy(data)
_data['title'] = translate(
_(u"Validation application for version ${version}",
mapping={'version': last_version.Title()}),
context=self.request)
_data['ITarget.target'] = last_version
new_validation = createContent('validation', **_data)
addContentToContainer(base_document, new_validation)
# annotate the validation task with the related version, it can later
# be used to match the task against the correct version.
annotations = IAnnotations(new_validation)
annotations['related_version_id'] = last_version.id
# execute transition on version
api.content.transition(last_version, transition='submit')
last_version.reindexObject(idxs=['review_state'])
class AskValidations(DefaultAddForm):
"""Ask validation custom add form
"""
@ -49,34 +83,10 @@ class AskValidations(DefaultAddForm):
return
for document_id in self.request.documents.split(','):
base_document = api.content.get(str(document_id))
self.ask_validation(base_document, data)
taskqueue.add(
'{}/background_ask_validation'.format(document_id),
payload=pickle.dumps(data),
)
self._finishedAdd = True
return
def ask_validation(self, base_document, data):
for child in reversed(base_document.values()):
if child.portal_type == 'dmsmainfile':
last_version = child
break
_data = deepcopy(data)
_data['title'] = translate(
_(u"Validation application for version ${version}",
mapping={'version': last_version.Title()}),
context=self.request)
_data['ITarget.target'] = last_version
new_validation = self.create(_data)
zope.event.notify(zope.lifecycleevent.ObjectCreatedEvent(new_validation))
addContentToContainer(base_document, new_validation)
# annotate the validation task with the related version, it can later
# be used to match the task against the correct version.
annotations = IAnnotations(new_validation)
annotations['related_version_id'] = last_version.id
# execute transition on version
api.content.transition(last_version, transition='submit')
last_version.reindexObject(idxs=['review_state'])

View File

@ -64,6 +64,14 @@
permission="cmf.AddPortalContent"
/>
<browser:page
name="background_add_information"
class=".add_multi_information.BackgroundAddInformationView"
for="*"
permission="cmf.AddPortalContent"
layer="collective.taskqueue.interfaces.ITaskQueueLayer"
/>
<browser:page
name="multi_attribute_task"
for="*"
@ -71,6 +79,14 @@
permission="cmf.AddPortalContent"
/>
<browser:page
name="background_attribute_task"
class=".multi_attribute_task.BackgroundAttributeTaskView"
for="*"
permission="cmf.AddPortalContent"
layer="collective.taskqueue.interfaces.ITaskQueueLayer"
/>
<browser:page
name="ask_multi_validation"
for="*"
@ -78,6 +94,16 @@
permission="cmf.AddPortalContent"
/>
<browser:page
name="background_ask_validation"
class=".ask_multi_validation.BackgroundAskValidationView"
for="*"
permission="cmf.AddPortalContent"
layer="collective.taskqueue.interfaces.ITaskQueueLayer"
/>
<!-- Custom comments viewlet for IBaseTask -->
<browser:viewlet
name="plone.comments"

View File

@ -1,21 +1,46 @@
# -*- coding: utf-8 -*-
import pickle
from copy import deepcopy
import z3c.form
from z3c.form import button
import zope.event
from zope.i18nmessageid.message import MessageFactory
from Products.CMFCore.utils import getToolByName
from Products.Five.browser import BrowserView
from plone import api
from plone.dexterity.browser.add import DefaultAddForm
from plone.dexterity.utils import createContentInContainer
from plone.stringinterp.adapters import _recursiveGetMembersFromIds
from collective.task import _
from collective.task.content.task import ITask
from collective.task.browser.attribute_task import find_nontask
from collective.taskqueue import taskqueue
class BackgroundAttributeTaskView(BrowserView):
def __call__(self):
base_task = self.context
data = pickle.load(self.request.stdin)
seen = {}
nontask = find_nontask(base_task)
portal_workflow = getToolByName(nontask, 'portal_workflow')
transitions = portal_workflow.getTransitionsFor(nontask)
transition_ids = [t['id'] for t in transitions]
for responsible in data['responsible']:
if responsible in seen:
continue
_data = deepcopy(data)
_data['responsible'] = [responsible]
new_task = createContentInContainer(base_task, 'task', **_data)
seen[responsible] = True
for responsible in data['responsible']:
nontask.manage_addLocalRoles(responsible, ['Editor',])
if 'attribute' in transition_ids:
portal_workflow.doActionFor(nontask, 'attribute')
nontask.reindexObjectSecurity()
nontask.reindexObject(idxs=['allowedRolesAndUsers'])
class AttributeTasks(DefaultAddForm):
@ -53,31 +78,11 @@ class AttributeTasks(DefaultAddForm):
self.status = self.formErrorsMessage
return
for task_id in self.request.documents.split(','):
base_task = api.content.get(str(task_id))
self.attribute_task(base_task, data)
for document_id in self.request.documents.split(','):
taskqueue.add(
'{}/background_attribute_task'.format(document_id),
payload=pickle.dumps(data),
)
self._finishedAdd = True
return
def attribute_task(self, base_task, data):
seen = {}
nontask = find_nontask(base_task)
portal_workflow = getToolByName(nontask, 'portal_workflow')
transitions = portal_workflow.getTransitionsFor(nontask)
transition_ids = [t['id'] for t in transitions]
for responsible in data['responsible']:
if responsible in seen:
continue
_data = deepcopy(data)
_data['responsible'] = [responsible]
new_task = createContentInContainer(base_task, 'task', **_data)
seen[responsible] = True
for responsible in data['responsible']:
nontask.manage_addLocalRoles(responsible, ['Editor',])
if 'attribute' in transition_ids:
portal_workflow.doActionFor(nontask, 'attribute')
nontask.reindexObjectSecurity()
nontask.reindexObject(idxs=['allowedRolesAndUsers'])