def on_task_output(self, task, config): config = self.prepare_config(config) if 'entries' in config: entries = list(itertools.chain(*(getattr(task, what) for what in config['entries']['what']))) if not entries: log.debug('No entries to notify about.') return # If a file template is defined, it overrides message if config['entries'].get('template'): try: message = get_template(config['entries']['template'], scope='entry') except ValueError: raise plugin.PluginError('Cannot locate template on disk: %s' % config['entries']['template']) else: message = config['entries']['message'] for entry in entries: self.send_notification(config['entries']['title'], message, config['entries']['via'], template_renderer=entry.render) if 'task' in config: if not (task.accepted or task.failed) and not config['task']['always_send']: log.verbose('No accepted or failed entries, not sending a notification.') return if config['task'].get('message'): template = config['task']['message'] else: try: template = get_template(config['task']['template'], scope='task') except ValueError: raise plugin.PluginError('Cannot locate template on disk: %s' % config['task']['template']) self.send_notification(config['task']['title'], template, config['task']['via'], template_renderer=task.render)
def list_file_templates(manager, options): header = ['Name', 'Use with', 'Full Path', 'Contents'] table_data = [header] console('Fetching all file templates, stand by...') for template_name in list_templates(extensions=['template']): if options.name and not options.name in template_name: continue template = get_template(template_name) if 'entries' in template_name: plugin = 'notify_entries' elif 'task' in template_name: plugin = 'notify_task' else: plugin = '-' name = template_name.replace('.template', '').split('/') if len(name) == 2: name = name[1] with open(template.filename) as contents: table_data.append( [name, plugin, template.filename, contents.read()]) try: table = TerminalTable(options.table_type, table_data, wrap_columns=[2, 3], drop_columns=[2, 3]) except TerminalTableError as e: console('ERROR: %s' % str(e)) else: console(table.output)
def list_file_templates(manager, options): header = [ 'Name', 'Use with', TerminalTable.Column('Full Path', overflow='fold'), TerminalTable.Column('Contents', overflow='ignore'), ] table = TerminalTable(*header, table_type=options.table_type, show_lines=True) console('Fetching all file templates, stand by...') for template_name in list_templates(extensions=['template']): if options.name and not options.name in template_name: continue template = get_template(template_name) if 'entries' in template_name: plugin = 'notify_entries' elif 'task' in template_name: plugin = 'notify_task' else: plugin = '-' name = template_name.replace('.template', '').split('/')[-1] with open(template.filename) as contents: table.add_row(name, plugin, template.filename, contents.read().strip()) console(table)
def on_task_exit(self, task): """Store finished / downloaded entries at exit""" if not rss2gen: raise PluginWarning('plugin make_rss requires PyRSS2Gen library.') config = self.get_config(task) # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely usefull) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config['title']) for field in config['link']: if field in entry: rss.link = entry[field] break try: template = get_template(config['template'], 'rss') except ValueError as e: raise PluginError('Invalid template specified: %s' % e) try: rss.description = render_from_entry(template, entry) except RenderError as e: log.error('Error while rendering entry %s, falling back to plain title: %s' % (entry, e)) rss.description = entry['title'] + ' - (Render Error)' rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss)
def on_task_exit(self, task): """Store finished / downloaded entries at exit""" if not rss2gen: raise PluginWarning('plugin make_rss requires PyRSS2Gen library.') config = self.get_config(task) # don't run with --test if task.manager.options.test: return # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely usefull) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter( RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config['title']) for field in config['link']: if field in entry: rss.link = entry[field] break rss.description = render_from_entry( get_template(config['template'], 'rss'), entry) rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss)
def list_file_templates(manager, options): header = ['Name', 'Use with', 'Full Path', 'Contents'] table_data = [header] console('Fetching all file templates, stand by...') for template_name in list_templates(extensions=['template']): if options.name and not options.name in template_name: continue template = get_template(template_name) if 'entries' in template_name: plugin = 'notify_entries' elif 'task' in template_name: plugin = 'notify_task' else: plugin = '-' name = template_name.replace('.template', '').split('/') if len(name) == 2: name = name[1] with io.open(template.filename) as contents: table_data.append([name, plugin, template.filename, contents.read()]) try: table = TerminalTable(options.table_type, table_data, wrap_columns=[2, 3], drop_columns=[2, 3]) except TerminalTableError as e: console('ERROR: %s' % str(e)) else: console(table.output)
def on_task_output(self, task, config): log.info('Starting fadbs_series_nfo') filename = os.path.expanduser('tvshow.nfo.template') for entry in task.entries: log.debug('Starting nfo generation for %s', entry['title']) # Load stuff entry['fadbs_nfo'] = {} entry_titles = entry.get('anidb_titles') if entry_titles: entry['fadbs_nfo'].update( title=self.__main_title(config, entry_titles)) else: log.warning('We were not given any titles, skipping...') continue entry_tags = entry.get('anidb_tags') entry['fadbs_nfo']['genres'] = [] entry['fadbs_nfo']['tags'] = [] if entry_tags: fadbs_nfo = self.__genres( entry.get('anidb_tags').items(), config['genre_weight']) entry['fadbs_nfo'].update(genres=fadbs_nfo[0]) entry['fadbs_nfo'].update(tags=fadbs_nfo[1]) template_ = template.render_from_entry( template.get_template(filename), entry) nfo_path = os.path.join(entry['location'], 'tvshow.nfo') with open(nfo_path, 'wb') as nfo: nfo.write(template_.encode('utf-8')) nfo.close()
def on_task_exit(self, task): """Store finished / downloaded entries at exit""" if not rss2gen: raise PluginWarning('plugin make_rss requires PyRSS2Gen library.') config = self.get_config(task) # don't run with --test if task.manager.options.test: return # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely usefull) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config['title']) for field in config['link']: if field in entry: rss.link = entry[field] break rss.description = render_from_entry(get_template(config['template'], 'rss'), entry) rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss)
def on_task_output(self, task, config): config = self.prepare_config(config) if 'entries' in config: entries = list( itertools.chain(*(getattr(task, what) for what in config['entries']['what'])) ) if not entries: log.debug('No entries to notify about.') else: # If a file template is defined, it overrides message if config['entries'].get('template'): try: message = get_template(config['entries']['template'], scope='entry') except ValueError: raise plugin.PluginError( 'Cannot locate template on disk: %s' % config['entries']['template'] ) else: message = config['entries']['message'] for entry in entries: self.send_notification( config['entries']['title'], message, config['entries']['via'], template_renderer=entry.render, ) if 'task' in config: if not (task.accepted or task.failed) and not config['task']['always_send']: log.verbose('No accepted or failed entries, not sending a notification.') return if config['task'].get('message'): template = config['task']['message'] else: try: template = get_template(config['task']['template'], scope='task') except ValueError: raise plugin.PluginError( 'Cannot locate template on disk: %s' % config['task']['template'] ) self.send_notification( config['task']['title'], template, config['task']['via'], template_renderer=task.render, )
def on_task_output(self, task, config): # Use the default template if none is specified if not config.get('template'): config['template'] = 'default.template' filename = os.path.expanduser(config['template']) output = os.path.expanduser(config['file']) # Output to config directory if absolute path has not been specified if not os.path.isabs(output): output = os.path.join(task.manager.config_base, output) # create the template template = render_from_task(get_template(filename, PLUGIN_NAME), task) log.verbose('Writing output html to %s' % output) with open(output, 'w') as f: f.write(template.encode('utf-8'))
def on_task_exit(self, task, config): """Send email at exit.""" config = prepare_config(config) if not config['active']: return # don't send mail when learning if task.options.learn: return # generate email content if config.get('subject'): subject = config['subject'] else: subject = '[FlexGet] {{task.name}}: ' if task.aborted: subject += 'Aborted' elif task.failed: subject += '{{task.failed|length}} failed entries' else: subject += '{{task.accepted|length}} new entries downloaded' try: subject = render_from_task(subject, task) except RenderError as e: log.error('Error rendering email subject: %s' % e) 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)
def on_task_output(self, task, config): # Use the default template if none is specified if not config.get('template'): config['template'] = 'default.template' filename = os.path.expanduser(config['template']) output = os.path.expanduser(config['file']) # Output to config directory if absolute path has not been specified if not os.path.isabs(output): output = os.path.join(task.manager.config_base, output) # create the template template = render_from_task(get_template(filename, PLUGIN_NAME), task) log.verbose('Writing output html to %s' % output) with open(output, 'w') as f: f.write(template.encode('utf-8'))
def on_task_output(self, task, config): # Use the default template if none is specified if not config.get("template"): config["template"] = "default.template" filename = os.path.expanduser(config["template"]) output = os.path.expanduser(config["file"]) # Output to config directory if absolute path has not been specified if not os.path.isabs(output): output = os.path.join(task.manager.config_base, output) # create the template template = render_from_task(get_template(filename, PLUGIN_NAME), task) log.verbose("Writing output html to %s" % output) f = open(output, "w") f.write(template.encode("utf-8")) f.close()
def on_task_exit(self, task, config): """Send email at exit.""" config = prepare_config(config) if not config['active']: return # don't send mail when learning if task.manager.options.learn: return # generate email content if config.get('subject'): subject = config['subject'] else: subject = '[FlexGet] {{task.name}}: ' if task.aborted: subject += 'Aborted' elif task.failed: subject += '{{task.failed|length}} failed entries' else: subject += '{{task.accepted|length}} new entries downloaded' try: subject = render_from_task(subject, task) except RenderError as e: log.error('Error rendering email subject: %s' % e) 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)
def on_task_exit(self, task): """Store finished / downloaded entries at exit""" if not rss2gen: raise PluginWarning('plugin make_rss requires PyRSS2Gen library.') config = self.get_config(task) # don't run with --test if task.manager.options.test: return # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely usefull) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config['title']) for field in config['link']: if field in entry: rss.link = entry[field] break # description = """{% if series_name is defined %}{% if series_banner_url is defined %}<img src="{{series_banner_url}}" />{% endif %} # {{series_name_tvdb|d(series_name)}} {{series_id}} {{ep_name|d('')}} # <b>Cast:</b> {{series_actors|d('')}} # <b>Guest Starring:</b> {{ep_guest_stars|d('')}} # <b>Overview:</b> {{ep_overview|d('')}} # {% elif imdb_name is defined %}{{imdb_name}} {{imdb_year}} # <b>Score:</b> {{imdb_score|d('N/A')}} ({{imdb_votes|d('0')}} votes) # <b>Genres:</b> {{imdb_genres|d('N/A')}} # <b>Plot:</b> {{imdb_plot_outline|d('N/A')}} # {% else %}{{title}}{% endif %}""" #rss.description = entry.render(description) rss.description = render_from_entry(get_template(config['template'], 'rss'), entry) rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss)
def on_task_output(self, task, config): # Use the default template if none is specified if not config.get('template'): config['template'] = 'default.template' filename = os.path.expanduser(config['template']) output = os.path.expanduser(config['file']) # Output to config directory if absolute path has not been specified if not os.path.isabs(output): output = os.path.join(task.manager.config_base, output) # create the template try: template = render_from_task(get_template(filename, PLUGIN_NAME), task) log.verbose('Writing output html to %s' % output) with open(output, 'w') as f: f.write(template.encode('utf-8')) except RenderError as e: log.error('Error while rendering task %s, Error: %s' % (task, e)) raise plugin.PluginError('There was an error rendering the specified template')
def on_task_output(self, task, config): # Use the default template if none is specified if not config.get('template'): config['template'] = 'default.template' filename = os.path.expanduser(config['template']) output = os.path.expanduser(config['file']) # Output to config directory if absolute path has not been specified if not os.path.isabs(output): output = os.path.join(task.manager.config_base, output) # create the template try: template = render_from_task(get_template(filename, PLUGIN_NAME), task) log.verbose('Writing output html to %s' % output) with open(output, 'w') as f: f.write(template.encode('utf-8')) except RenderError as e: log.error('Error while rendering task %s, Error: %s' % (task, e)) raise plugin.PluginError('There was an error rendering the specified template')
def on_task_output(self, task, config): config = prepare_config(config) if not config["active"]: return # don't send mail when learning if task.options.learn: return # generate email content if config.get("subject"): subject = config["subject"] else: subject = "[FlexGet] {{task.name}}: " if task.aborted: subject += "Aborted" elif task.failed: subject += "{{task.failed|length}} failed entries" else: subject += "{{task.accepted|length}} new entries downloaded" try: subject = render_from_task(subject, task) except RenderError as e: log.error("Error rendering email subject: %s" % e) 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)
def render_value(entity, data, attribute, default_dict, scope=None): """ Tries to render a template, fallback to default template and just value if unsuccessful :param entity: The entity to operate on, either `Entry` or `Task` :param data: The text to be rendered :param attribute: Attribute name to be fetched from the defaults :param default_dict: The default dict, depending on entity type :return: A rendered value or original value """ result = data # Handles file templates if attribute == 'file_template': try: data = get_template(data, scope) except ValueError as e: log.warning(e.args[0]) return try: result = entity.render(data) except (RenderError, ValueError) as e: log.debug('cannot render: `%s: %s`, error: %s', attribute, data, e.args[0]) if attribute in default_dict: try: log.debug('trying to render default value for `%s`', attribute) result = entity.render(default_dict[attribute]) # Render error on defaults should not happen except RenderError as e: log.warning('default dict failed to render: `%s: %s`. Error: %s. Reverting to original value.', attribute, data, e.args[0]) else: # Even in debug level, showing contents of rendered file templates is super spammy if attribute == 'file_template': message = 'successfully rendered file_template %s', data else: message = 'successfully rendered `%s` to %s', attribute, result log.debug(*message) return result
def render_value(entity, data, attribute, default_dict, plugin_name=None): """ Tries to render a template, fallback to default template and just value if unsuccessful :param entity: The entity to operate on, either `Entry` or `Task` :param data: The text to be rendered :param attribute: Attribute name to be fetched from the defaults :param default_dict: The default dict, depending on entity type :return: A rendered value or original value """ result = data # Handles file templates if attribute == 'file_template': try: data = get_template(data, plugin_name) except ValueError as e: log.warning(e.args[0]) return try: result = entity.render(data) except (RenderError, ValueError) as e: log.debug('failed to render: %s. Trying to fall back to default', e.args[0]) try: if attribute in default_dict: result = entity.render(default_dict[attribute]) # Render error on defaults should not happen except RenderError as e: log.warning( 'default dict failed to render: %s. Reverting to original value.', e.args[0]) else: log.debug('successfully rendered `%s` to %s', attribute, result) return result
def on_task_exit(self, task): """Store finished / downloaded entries at exit""" if not rss2gen: raise PluginWarning("plugin make_rss requires PyRSS2Gen library.") config = self.get_config(task) # don't run with --test if task.manager.options.test: return # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely usefull) if not config["history"]: log.debug("disabling history") for item in task.session.query(RSSEntry).filter(RSSEntry.file == config["file"]).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config["title"]) for field in config["link"]: if field in entry: rss.link = entry[field] break # TODO: better exception handling try: rss.description = render_from_entry(get_template(config["template"], "rss"), entry) except: log.error("Error while rendering entry %s, falling back to plain title", entry) rss.description = entry["title"] + " - (Render Error)" rss.file = config["file"] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug("Saving %s into rss database" % entry["title"]) task.session.add(rss)
def on_task_exit(self, task, config): """Store finished / downloaded entries at exit""" if not rss2gen: raise plugin.PluginWarning('plugin make_rss requires PyRSS2Gen library.') config = self.prepare_config(config) # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely useful) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() rss.title = entry.render(config['title']) for field in config['link']: if field in entry: rss.link = entry[field] break try: template = get_template(config['template'], 'rss') except ValueError as e: raise plugin.PluginError('Invalid template specified: %s' % e) try: rss.description = render_from_entry(template, entry) except RenderError as e: log.error('Error while rendering entry %s, falling back to plain title: %s' % (entry, e)) rss.description = entry['title'] + ' - (Render Error)' rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss) if not rss2gen: return # don't generate rss when learning if task.options.learn: return db_items = task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).\ order_by(RSSEntry.published.desc()).all() # make items rss_items = [] for db_item in db_items: add = True if config['items'] != -1: if len(rss_items) > config['items']: add = False if config['days'] != -1: if datetime.datetime.today() - datetime.timedelta(days=config['days']) > db_item.published: add = False if add: # add into generated feed hasher = hashlib.sha1() hasher.update(db_item.title.encode('utf8')) hasher.update(db_item.description.encode('utf8')) hasher.update(db_item.link.encode('utf8')) guid = base64.urlsafe_b64encode(hasher.digest()) gen = {'title': db_item.title, 'description': db_item.description, 'link': db_item.link, 'pubDate': db_item.published, 'guid': guid} log.trace('Adding %s into rss %s' % (gen['title'], config['file'])) rss_items.append(PyRSS2Gen.RSSItem(**gen)) else: # no longer needed task.session.delete(db_item) # make rss rss = PyRSS2Gen.RSS2(title='FlexGet', link=config.get('rsslink', 'http://flexget.com'), description='FlexGet generated RSS feed', lastBuildDate=datetime.datetime.utcnow(), items=rss_items) # don't run with --test if task.options.test: log.info('Would write rss file with %d entries.', len(rss_items)) return # write rss fn = os.path.expanduser(config['file']) with open(fn, 'w') as file: try: log.verbose('Writing output rss to %s' % fn) rss.write_xml(file, encoding=config['encoding']) except LookupError: log.critical('Unknown encoding %s' % config['encoding']) return except IOError: # TODO: plugins cannot raise PluginWarnings in terminate event .. log.critical('Unable to write %s' % fn) return
def on_task_exit(self, task, config): """Store finished / downloaded entries at exit""" if not rss2gen: raise plugin.PluginWarning( 'plugin make_rss requires PyRSS2Gen library.') config = self.prepare_config(config) # when history is disabled, remove everything from backlog on every run (a bit hackish, rarely useful) if not config['history']: log.debug('disabling history') for item in task.session.query(RSSEntry).filter( RSSEntry.file == config['file']).all(): task.session.delete(item) # save entries into db for RSS generation for entry in task.accepted: rss = RSSEntry() try: rss.title = entry.render(config['title']) except RenderError as e: log.error( 'Error rendering jinja title for `%s` falling back to entry title: %s' % (entry['title'], e)) rss.title = entry['title'] for field in config['link']: if field in entry: rss.link = entry[field] break try: template = get_template(config['template'], 'rss') except ValueError as e: raise plugin.PluginError('Invalid template specified: %s' % e) try: rss.description = render_from_entry(template, entry) except RenderError as e: log.error( 'Error while rendering entry %s, falling back to plain title: %s' % (entry, e)) rss.description = entry['title'] + ' - (Render Error)' rss.file = config['file'] # TODO: check if this exists and suggest disabling history if it does since it shouldn't happen normally ... log.debug('Saving %s into rss database' % entry['title']) task.session.add(rss) if not rss2gen: return # don't generate rss when learning if task.options.learn: return db_items = task.session.query(RSSEntry).filter(RSSEntry.file == config['file']).\ order_by(RSSEntry.published.desc()).all() # make items rss_items = [] for db_item in db_items: add = True if config['items'] != -1: if len(rss_items) > config['items']: add = False if config['days'] != -1: if datetime.datetime.today() - datetime.timedelta( days=config['days']) > db_item.published: add = False if add: # add into generated feed hasher = hashlib.sha1() hasher.update(db_item.title.encode('utf8')) hasher.update(db_item.description.encode('utf8')) hasher.update(db_item.link.encode('utf8')) guid = base64.urlsafe_b64encode(hasher.digest()) guid = PyRSS2Gen.Guid(guid, isPermaLink=False) gen = { 'title': db_item.title, 'description': db_item.description, 'link': db_item.link, 'pubDate': db_item.published, 'guid': guid } log.trace('Adding %s into rss %s' % (gen['title'], config['file'])) rss_items.append(PyRSS2Gen.RSSItem(**gen)) else: # no longer needed task.session.delete(db_item) # make rss rss = PyRSS2Gen.RSS2(title='FlexGet', link=config.get('rsslink', 'http://flexget.com'), description='FlexGet generated RSS feed', lastBuildDate=datetime.datetime.utcnow(), items=rss_items) # don't run with --test if task.options.test: log.info('Would write rss file with %d entries.', len(rss_items)) return # write rss fn = os.path.expanduser(config['file']) with open(fn, 'w') as file: try: log.verbose('Writing output rss to %s' % fn) rss.write_xml(file, encoding=config['encoding']) except LookupError: log.critical('Unknown encoding %s' % config['encoding']) return except IOError: # TODO: plugins cannot raise PluginWarnings in terminate event .. log.critical('Unable to write %s' % fn) return
class OutputEmail(object): """ Send an e-mail with the list of all succeeded (downloaded) entries. Configuration options =============== =================================================================== Option Description =============== =================================================================== from The email address from which the email will be sent (required) to The email address of the recipient (required) smtp_host The host of the smtp server smtp_port The port of the smtp server smtp_username The username to use to connect to the smtp server smtp_password The password to use to connect to the smtp server smtp_tls Should we use TLS to connect to the smtp server smtp_ssl Should we use SSL to connect to the smtp server Due to a bug in python, this only works in python 2.6.3 and up active Is this plugin active or not =============== =================================================================== Config basic example:: email: from: [email protected] to: [email protected] smtp_host: smtp.host.com Config example with smtp login:: email: from: [email protected] to: [email protected] smtp_host: smtp.host.com smtp_port: 25 smtp_login: true smtp_username: my_smtp_login smtp_password: my_smtp_password smtp_tls: true Config multi-task example:: global: email: from: [email protected] to: [email protected] smtp_host: smtp.host.com tasks: task1: rss: http://xxx task2: rss: http://yyy email: active: False task3: rss: http://zzz email: to: [email protected] GMAIL example:: from: [email protected] to: [email protected] smtp_host: smtp.gmail.com smtp_port: 587 smtp_login: true smtp_username: gmailUser smtp_password: gmailPassword smtp_tls: true Default values for the config elements:: email: active: True smtp_host: localhost smtp_port: 25 smtp_login: False smtp_username: smtp_password: smtp_tls: False smtp_ssl: False """ def validator(self): v = options_validator() v.accept('boolean', key='global') return v def on_task_output(self, task, config): """Count the email as an output""" def on_task_exit(self, task, config): """Send email at exit.""" config = prepare_config(config) if not config['active']: return # don't send mail when learning if task.manager.options.learn: return # generate email content if config.get('subject'): subject = config['subject'] else: subject = '[FlexGet] {{task.name}}: ' if task.aborted: subject += 'Aborted' elif task.failed: subject += '{{task.failed|length}} failed entries' else: subject += '{{task.accepted|length}} new entries downloaded' try: subject = render_from_task(subject, task) except RenderError, e: log.error('Error rendering email subject: %s' % e) return try: content = render_from_task(get_template(config['template'], 'email'), task) except RenderError, e: log.error('Error rendering email body: %s' % e) return
def is_valid_template(instance) -> bool: if not isinstance(instance, str): return True return get_template(instance) is not None
def is_valid_template(instance): if not isinstance(instance, str_types): return True return get_template(instance) is not None
def is_valid_template(instance): if not isinstance(instance, str_types): return True return get_template(instance) is not None