class WorkflowActionCreatePartitionsAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'copy_to_new' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): url = "{}/partition_magic?uids={}".format(self.back_url, ",".join(uids)) return self.redirect(redirect_url=url)
class WorkflowActionCopyToNewAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'copy_to_new' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): url = "{}/ar_add?ar_count={}©_from={}".format( self.back_url, len(uids), ",".join(uids)) return self.redirect(redirect_url=url)
class WorkflowActionPrintStickersAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'print_stickers' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): url = "{}/sticker?template={}&items={}".format(self.back_url, self.context.bika_setup.getAutoStickerTemplate(), ",".join(uids)) return self.redirect(redirect_url=url)
class WorkflowActionPublishAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'publish'-like actions """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): purl = self.context.portal_url() uids = ",".join(uids) url = "{}/analysisrequests/publish?items={}".format(purl, uids) return self.redirect(redirect_url=url)
class WorkflowActionStoreAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'store' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): """Redirects the user to the Storage container selector view """ url = "{}/storage_store_samples?uids={}".format(self.back_url, ",".join(uids)) return self.redirect(redirect_url=url)
class WorkflowActionSendToPotAdapter(RequestContextAware): """Adapter in charge of Analysis Request "send_to_pot" action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): """Redirects the user to the point of testing shipment view """ uids = ",".join(uids) url = "{}/pot_shipment?uids={}".format(self.back_url, uids) return self.redirect(redirect_url=url)
class WorkflowActionProcessAdapter(RequestContextAware): """Adapter in charge of Analysis Requests 'process' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): """Redirects the user to the partition magic view """ url = "{}/partition_magic?uids={}".format(self.back_url, ",".join(uids)) return self.redirect(redirect_url=url)
class WorkflowActionRemoveAdapter(RequestContextAware): """Adapter in charge of queue tasks' remove action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): """Removes the selected tasks and redirects to the previous URL """ queue = qapi.get_queue() map(queue.delete, uids) url = api.get_url(api.get_portal()) url = "{}/queue_tasks".format(url) return self.redirect(url)
class WorkflowActionPublishSamplesAdapter(RequestContextAware): """Adapter in charge of the client 'publish_samples' action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): published = [] # get the selected ARReport objects reports = map(api.get_object_by_uid, uids) # get all the contained sample UIDs of the generated PDFs sample_uids = map(self.get_sample_uids_in_report, reports) # uniquify the UIDs of the contained samples unique_sample_uids = set( list(itertools.chain.from_iterable(sample_uids))) # publish all the contained samples of the selected reports for uid in unique_sample_uids: sample = api.get_object_by_uid(uid) if self.publish_sample(sample): published.append(sample) # generate a status message of the published sample IDs message = _("No items published") if published: message = _("Published {}".format(", ".join( map(api.get_id, published)))) # add the status message for the response self.add_status_message(message, "info") # redirect back referer = self.request.get_header("referer") return self.redirect(redirect_url=referer) def get_sample_uids_in_report(self, report): """Return a list of contained sample UIDs """ metadata = report.getMetadata() or {} return metadata.get("contained_requests", []) def publish_sample(self, sample): """Set status to prepublished/published/republished """ status = api.get_workflow_status_of(sample) transitions = {"verified": "publish", "published": "republish"} transition = transitions.get(status, "prepublish") succeed, message = doActionFor(sample, transition) return succeed
class RevisionsRemoved(ScannerEvent): """Revisions have been removed from the branch.""" implements(IRevisionsRemoved) def __init__(self, db_branch, bzr_branch, removed_history): """Construct a `RevisionsRemoved` event. :param db_branch: The database branch. :param bzr_branch: The Bazaar branch. :param removed_history: The mainline database `IRevision` objects that are no longer present in the mainline of the Bazaar branch. """ ScannerEvent.__init__(self, db_branch, bzr_branch) self.removed_history = removed_history
class NewMainlineRevisions(ScannerEvent): """A new revision has been found in the branch.""" implements(INewMainlineRevisions) def __init__(self, db_branch, bzr_branch, bzr_revisions): """Construct a `NewRevisions` event. :param db_branch: The database branch. :param bzr_branch: The Bazaar branch. :param db_revision: An `IRevision` for the new revision. :param bzr_revision: The new Bazaar revision. :param revno: The revision number of the new revision, None if not mainline. """ ScannerEvent.__init__(self, db_branch, bzr_branch) self.bzr_revisions = bzr_revisions
class WorkflowActionRequeueAdapter(RequestContextAware): """Adapter in charge of queue tasks' requeue action """ implements(IWorkflowActionUIDsAdapter) def __call__(self, action, uids): """Re-queues the selected tasks and redirects to the previous URL """ queue = qapi.get_queue() for uid in uids: task = queue.get_task(uid) task.retries = get_max_retries() queue.delete(uid) queue.add(task) url = api.get_url(api.get_portal()) url = "{}/queue_tasks".format(url) return self.redirect(url)
class ScanCompleted(ScannerEvent): """The scan has been completed and the database is up-to-date.""" implements(IScanCompleted) def __init__(self, db_branch, bzr_branch, logger, new_ancestry): """Construct a `ScanCompleted` event. :param db_branch: The database branch. :param bzr_branch: The Bazaar branch. :param bzr_ancestry: A set of all the revisions -- mainline or otherwise -- in the Bazaar branch. :param logger: A Python logger object that's used to report incidental information, such as merges that we find. """ ScannerEvent.__init__(self, db_branch, bzr_branch) self.new_ancestry = new_ancestry # This is kind of ick. In a strict Zope sense, the logger should # probably be a registered utility. self.logger = logger
class TipChanged(ScannerEvent): """The tip of the branch has changed.""" implements(ITipChanged) def __init__(self, db_branch, bzr_branch, initial_scan): """Construct a `TipChanged` event. :param db_branch: The database branch. :param bzr_branch: The Bazaar branch. :param initial_scan: Is this the first scan of the branch? """ ScannerEvent.__init__(self, db_branch, bzr_branch) self.initial_scan = initial_scan @property def old_tip_revision_id(self): """The tip revision id from the last scan.""" return self.db_branch.last_scanned_id @property def new_tip_revision_id(self): """The new tip revision id from this scan.""" return self.bzr_branch.last_revision()
class WorkflowActionGenericAdapter(RequestContextAware): """General purpose adapter for processing workflow action requests """ implements(IWorkflowActionAdapter) def __call__(self, action, objects): """Performs the given action to the objects passed in """ transitioned = self.do_action(action, objects) if not transitioned: return self.redirect(message=_("No changes made."), level="warning") # TODO Here we could handle subscriber adapters here? # Redirect the user to success page return self.success(transitioned) def do_action(self, action, objects): """Performs the workflow transition passed in and returns the list of objects that have been successfully transitioned """ transitioned = [] ActionHandlerPool.get_instance().queue_pool() for obj in objects: obj = api.get_object(obj) success, message = do_action_for(obj, action) if success: transitioned.append(obj) ActionHandlerPool.get_instance().resume() return transitioned def is_context_only(self, objects): """Returns whether the action applies to the current context only """ if len(objects) > 1: return False return self.context in objects def success(self, objects, message=None): """Redirects the user to success page with informative message """ if self.is_context_only(objects): return self.redirect(message=_("Changes saved.")) ids = map(api.get_id, objects) if not message: message = _("Saved items: {}").format(", ".join(ids)) return self.redirect(message=message) def get_form_value(self, form_key, object_brain_uid, default=None): """Returns a value from the request's form for the given uid, if any """ if form_key not in self.request.form: return default uid = object_brain_uid if not api.is_uid(uid): uid = api.get_uid(object_brain_uid) values = self.request.form.get(form_key) if isinstance(values, list): if len(values) == 0: return default if len(values) > 1: logger.warn("Multiple set of values for {}".format(form_key)) values = values[0] return values.get(uid, default)
class AdminClientDisconnected(object): implements(IAdminClientConnected) def __init__(self, obj): self.object = obj