return try: content = render_from_task(get_template(config['template'], 'email'), task) except RenderError as e: log.error('Error rendering email body: %s' % e) return if not content.strip(): log.verbose('No content generated from template, not sending email.') return if config.get('global'): # Email plugin was configured at root, save the email output log.debug('Saving email content for task %s' % task.name) task_content[task.name] = content else: send_email(subject, content, config) # Also send the email on abort def on_task_abort(self, task, config): # The config may not be correct if the task is aborting try: self.on_task_exit(task, config) except Exception as e: log.info('Could not send abort email because email config is invalid.') # Log the exception to debug, in case something different is going wrong. log.debug('Email error:', exc_info=True) register_plugin(OutputEmail, 'email', api_ver=2) manager.register_config_key('email', options_validator)
def validator(self): root = validator.factory() root.accept('text') presets = root.accept('list') presets.accept('text') return root @priority(250) def on_task_start(self, task, config): if isinstance(config, basestring): config = [config] # let's disable them for disable in config: if disable in task.config: log.debug('disabling %s' % disable) del(task.config[disable]) root_config_schema = { 'type': 'object', 'additionalProperties': {} } register_config_key('presets', root_config_schema) register_plugin(PluginPreset, 'preset', builtin=True, api_ver=2) register_plugin(DisablePlugin, 'disable_plugin', api_ver=2) register_parser_option('--preset', action='store', dest='preset', default=False, metavar='NAME', help='Execute tasks with given preset.')
presets.accept('text') return root @priority(250) def on_task_start(self, task, config): if isinstance(config, basestring): config = [config] # let's disable them for disable in config: if disable in task.config: log.debug('disabling %s' % disable) del (task.config[disable]) root_config_schema = { 'type': 'object', 'additionalProperties': {} # TODO: Reject keys that are plugin names } register_config_key('presets', root_config_schema) register_plugin(PluginPreset, 'preset', builtin=True, api_ver=2) register_plugin(DisablePlugin, 'disable_plugin', api_ver=2) register_parser_option('--preset', action='store', dest='preset', default=False, metavar='NAME', help='Execute tasks with given preset.')
except TypeError as e: log.critical('Invalid validator method in plugin %s' % keyword) log.exception(e) continue if not validator.name == 'root': # if validator is not root type, add root validator as it's parent validator = validator.add_root_parent() if not validator.validate(config[keyword]): for msg in validator.errors.messages: validate_errors.append('%s %s' % (keyword, msg)) else: log.warning('Used plugin %s does not support validating. Please notify author!' % keyword) return validate_errors def root_config_validator(): """Returns a validator for the 'tasks' key of config.""" # TODO: better error messages valid_plugins = [p for p in all_plugins if hasattr(all_plugins[p].instance, 'validator')] root = validator.factory('dict') root.reject_keys(valid_plugins, message='plugins should go under a specific task. ' '(and tasks are not allowed to be named the same as any plugins)') root.accept_any_key('dict').accept_any_key('any') return root register_config_key('tasks', root_config_validator) # Backwards compatibility with feeds key register_config_key('feeds', root_config_validator)
if disable in task.config: log.debug('disabling %s' % disable) del (task.config[disable]) def root_config_validator(): """Returns a validator for the 'presets' key of config.""" # TODO: better error messages valid_plugins = [ p for p in all_plugins if hasattr(all_plugins[p].instance, 'validator') ] root = validator.factory('dict') root.reject_keys( valid_plugins, message='plugins should go under a specific preset. ' '(and presets are not allowed to be named the same as any plugins)') root.accept_any_key('dict').accept_any_key('any') return root register_config_key('presets', root_config_validator) register_plugin(PluginPreset, 'preset', builtin=True, api_ver=2) register_plugin(DisablePlugin, 'disable_plugin', api_ver=2) register_parser_option('--preset', action='store', dest='preset', default=False, metavar='NAME', help='Execute tasks with given preset.')
def validate(self): """Called during task execution. Validates config, prints errors and aborts task if invalid.""" errors = self.validate_config(self.config) # log errors and abort if errors: log.critical('Task \'%s\' has configuration errors:' % self.name) for error in errors: log.error(error.error_with_path) # task has errors, abort it self.abort('\n'.join(e.error_with_path for e in errors)) return errors @staticmethod def validate_config(config): schema = plugin_schemas(context='task') # Don't validate commented out plugins schema['patternProperties'] = {'^_': {}} validator = config_schema.SchemaValidator(schema) return validator.process_config(config) task_config_schema = { 'type': 'object', 'additionalProperties': {'type': 'object'} # TODO: reject keys that are plugin names } register_config_key('tasks', task_config_schema, required=True) # Backwards compatibility with feeds key register_config_key('feeds', task_config_schema)
return root @priority(250) def on_task_start(self, task, config): if isinstance(config, basestring): config = [config] # let's disable them for disable in config: if disable in task.config: log.debug('disabling %s' % disable) del(task.config[disable]) def root_config_validator(): """Returns a validator for the 'presets' key of config.""" # TODO: better error messages valid_plugins = [p for p in all_plugins if hasattr(all_plugins[p].instance, 'validator')] root = validator.factory('dict') root.reject_keys(valid_plugins, message='plugins should go under a specific preset. ' '(and presets are not allowed to be named the same as any plugins)') root.accept_any_key('dict').accept_any_key('any') return root register_config_key('presets', root_config_validator) register_plugin(PluginPreset, 'preset', builtin=True, api_ver=2) register_plugin(DisablePlugin, 'disable_plugin', api_ver=2) register_parser_option('--preset', action='store', dest='preset', default=False, metavar='NAME', help='Execute tasks with given preset.')
validator = validator.add_root_parent() if not validator.validate(config[keyword]): for msg in validator.errors.messages: validate_errors.append('%s %s' % (keyword, msg)) else: log.warning( 'Used plugin %s does not support validating. Please notify author!' % keyword) return validate_errors def root_config_validator(): """Returns a validator for the 'tasks' key of config.""" # TODO: better error messages valid_plugins = [ p for p in all_plugins if hasattr(all_plugins[p].instance, 'validator') ] root = validator.factory('dict') root.reject_keys( valid_plugins, message='plugins should go under a specific task. ' '(and tasks are not allowed to be named the same as any plugins)') root.accept_any_key('dict').accept_any_key('any') return root register_config_key('tasks', root_config_validator) # Backwards compatibility with feeds key register_config_key('feeds', root_config_validator)
except RenderError as e: log.error('Error rendering email body: %s' % e) return if not content.strip(): log.verbose( 'No content generated from template, not sending email.') return if config.get('global'): # Email plugin was configured at root, save the email output log.debug('Saving email content for task %s' % task.name) task_content[task.name] = content else: send_email(subject, content, config) # Also send the email on abort def on_task_abort(self, task, config): # The config may not be correct if the task is aborting try: self.on_task_exit(task, config) except Exception as e: log.info( 'Could not send abort email because email config is invalid.') # Log the exception to debug, in case something different is going wrong. log.debug('Email error:', exc_info=True) register_plugin(OutputEmail, 'email', api_ver=2) manager.register_config_key('email', options_validator)
except RenderError as e: log.error('Error rendering email body: %s' % e) return if not content.strip(): log.verbose( 'No content generated from template, not sending email.') return if config.get('global'): # Email plugin was configured at root, save the email output log.debug('Saving email content for task %s' % task.name) task_content[task.name] = content else: send_email(subject, content, config) # Also send the email on abort def on_task_abort(self, task, config): # The config may not be correct if the task is aborting try: self.on_task_exit(task, config) except Exception as e: log.info( 'Could not send abort email because email config is invalid.') # Log the exception to debug, in case something different is going wrong. log.debug('Email error:', exc_info=True) register_plugin(OutputEmail, 'email', api_ver=2) manager.register_config_key('email', options_validator().schema())
return try: content = render_from_task(get_template(config['template'], 'email'), task) except RenderError as e: log.error('Error rendering email body: %s' % e) return if not content.strip(): log.verbose('No content generated from template, not sending email.') return if config.get('global'): # Email plugin was configured at root, save the email output log.debug('Saving email content for task %s' % task.name) task_content[task.name] = content else: send_email(subject, content, config) # Also send the email on abort def on_task_abort(self, task, config): # The config may not be correct if the task is aborting try: self.on_task_exit(task, config) except Exception as e: log.info('Could not send abort email because email config is invalid.') # Log the exception to debug, in case something different is going wrong. log.debug('Email error:', exc_info=True) register_plugin(OutputEmail, 'email', api_ver=2) manager.register_config_key('email', options_validator().schema())
class OutputTwitter(object): def on_task_output(self, task, config): # Initialize twitter client import tweepy auth = tweepy.OAuthHandler(config['consumerkey'], config['consumersecret']) auth.set_access_token(config['accesskey'], config['accesssecret']) api = tweepy.API(auth) for entry in task.accepted: try: content = entry.render(config['template']) except RenderError, e: log.error('Error rendering message: %s' % e) return if task.manager.options.test: log.info('Would update twitter with: %s' % content) continue try: api.update_status(content) except Exception, e: log.warning('Unable to post tweet: %s' % e) register_plugin(OutputTwitter, 'twitter', api_ver=2) manager.register_config_key('twitter', schema)