def load_global_actions(self): # get the global pipeline actions from the config files. action_config = PTaskArea.current().config( GLOBAL_ACTIONS_CONFIG, composite_ancestors=True, ) for (target_type, actions) in action_config.items(): for (action_name, settings) in actions.items(): # try to import the module specified in the config. # then get the class from the imported module action_module_name = settings.get('module', None) action_class_name = settings.get('class', None) doc = settings.get( 'help', "{t} {a} Action.".format(t=target_type, a=action_name)) try: action_module = import_module(action_module_name) action_class = getattr(action_module, action_class_name) except Exception as e: log.error(str(e)) continue # if the action and target specified in the config matches # those in the action class itself, go ahead and register it. if (action_class.name == action_name and action_class.target_type == target_type): self.register_action(action_class) # if not, then the config has overridden the action and/or # target. We will create a dynamic subclass with the new # specification which will allow for the creation of instances # with the new action/target. an optional docstring an be # specified in the config as well. else: # build a unique name for the subclass. alias_subclass_name = \ target_type.title() + action_name.title() + \ action_class.__name__ # create a dynamic subclass of the action with the new # action name and/or target type action_subclass = type( alias_subclass_name, # name of the subclass (action_class,), # base class tuple { # class attributes to set 'name': action_name, 'target_type': target_type, '__doc__': doc, }, ) # now register the dynamic subclass self.register_action(action_subclass)
def config(self): if not hasattr(self, '_config'): self._config = PTaskArea.current().config( OPEN_ACTION_CONFIG, composite_ancestors=True, composite_method="override", ) return self._config
def validate(self): if not self._message: raise ActionError("Message can not be empty.") try: self._sender = User.current() except UserError: raise ActionError("Could not identify current user.") # get ooto notification recipients from the configs ptask_area = PTaskArea.current() ooto_config = ptask_area.config( OOTO_CONFIG_PATH, composite_ancestors=True, composite_method="append", ) ooto_notify = ooto_config.get('notify', []) self._to.extend(ooto_notify) # for all usernames specified, make sure they're a valid user, # get their email addresses. recipients = set() for recipient in self._to: # assume already a valid email address if "@" in recipient: recipients.add(recipient) else: try: recipient = User.get(recipient) except UserError: raise ActionError( "Could not identify user: "******"\n\nCurrent ptask: {p}".format(p=ptask_area.spec) self._message += "\n\n- {s}".format(s=self._sender.full_name) self._subject = "OOTO: {fn} ({un})".format( fn=self.sender.full_name, un=self.sender.username, )
def validate(self): if not self._subject: raise ActionError("Subject can't be empty.") self._subject = "FAIL: " + self._subject if not self._message: raise ActionError("Message can't be empty.") try: self._sender = User.current() except UserError: raise ActionError("Could not identify current user.") # get fail notification recipients from the configs ptask_area = PTaskArea.current() fail_config = ptask_area.config( FAIL_CONFIG_PATH, composite_ancestors=True, composite_method="append", ) fail_notify = fail_config.get('notify', []) self._to.extend(fail_notify) # for all usernames specified, make sure they're a valid user, # get their email addresses. recipients = set() for recipient in self._to: # assume already a valid email address if "@" in recipient: recipients.add(recipient) else: try: recipient = User.get(recipient) except UserError: raise ActionError( "Could not identify user: "******"\n\nCurrent ptask: {p}".format(p=ptask_area.spec) self._message += "\n\n- {s}".format(s=self._sender.full_name)