def test_exec_import(self): tmpl = NewTextTemplate("""{% python from datetime import timedelta %} ${timedelta(days=2)} """) self.assertEqual(""" 2 days, 0:00:00 """, tmpl.generate().render(encoding=None))
def _format_subj(self, event): is_newticket = event.category == 'created' ticket = event.target summary = ticket['summary'] if event.changes and 'summary' in event.changes['fields']: change = event.changes['fields']['summary'] summary = "%s (was: %s)" % (change['new'], change['old']) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.env.project_name data = { 'prefix': prefix, 'summary': summary, 'ticket': ticket, 'changes': event.changes, 'env': self.env, } template = self.config.get('notification', 'ticket_subject_template') template = NewTextTemplate(template.encode('utf8')) subj = template.generate(**data).render('text', encoding=None).strip() if not is_newticket: subj = "Re: " + subj return subj
def test_exec_import(self): tmpl = NewTextTemplate(u"""{% python from datetime import timedelta %} ${timedelta(days=2)} """) self.assertEqual(""" 2 days, 0:00:00 """, str(tmpl.generate()))
def notify(self, req, ticket, name): ctx = self.build_template_context(req, ticket, name) section = self.config['ticket-workflow-notifications'] condition = section.get('%s.condition' % name, None) if condition is not None: condition_value = TextTemplate(condition.replace( "\\n", "\n")).generate(**ctx).render(encoding=None).strip() if condition_value != 'True': self.log.debug( "Skipping notification %s for ticket %s " "because condition '%s' did not evaluate to True (it evaluated to %s)" % (name, ticket.id if ticket.exists else "(new ticket)", condition, condition_value)) return False else: self.log.debug( "Sending notification %s for ticket %s " "because condition '%s' did evaluate to True" % (name, ticket.id if ticket.exists else "(new ticket)", condition)) else: self.log.debug( "Sending notification %s for ticket %s " "because there was no condition" % (name, ticket.id if ticket.exists else "(new ticket)")) body = TextTemplate( section.get('%s.body' % name).replace( "\\n", "\n")).generate(**ctx).render(encoding=None) subject = TextTemplate( section.get('%s.subject' % name).replace( "\\n", "\n")).generate(**ctx).render(encoding=None) subject = ' '.join(subject.splitlines()) recipients = TextTemplate( section.get('%s.recipients' % name).replace( "\\n", "\n")).generate(**ctx).render(encoding=None) recipients = [r.strip() for r in recipients.split(",")] notifier = WorkflowNotifyEmail( self.env, template_name='ticket_notify_workflow_email.txt', recipients=recipients, data={'body': body}) vars = inspect.getargspec(notifier.notify)[0] if len(vars) == 3: # Trac 0.12 and below args = [ticket.id, subject] elif len( vars ) == 4: # Trac 0.13 and up have an additional `author` argument to trac.notification:NotifyEmail.notify args = [ticket.id, subject, req.authname] else: self.log.error( "Cannot send notification %s for ticket %s " "because this trac version has an unknown NotifyEmail.notify signature " "%s" % (name, ticket.id if ticket.exists else "(new ticket)", condition, vars)) return False notifier.notify(*args)
def __init__(self, template, outfile, encoding='utf-8', ignore_undefined_variables=False): """ :param template: a genshi text template. For more information you can refer to the Genshi documentation: http://genshi.edgewall.org/wiki/ApiDocs/genshi.template.text :type template: a string representing the full path name to a template file. :param outfile: the desired file name for the resulting text document :type outfile: a string representing the full filename for output :param encoding: By default the text encoding of the output will be UTF8. If you want another encoding you must specify it. :type encoding: a string representin the desired output encoding :param ignore_undefined_variables: Not defined variables are replaced with an empty string during template rendering if True :type ignore_undefined_variables: boolean. Default is False """ self.outputfilename = outfile self.encoding = encoding content = codecs.open(template, 'rb', encoding='utf-8').read() if ignore_undefined_variables: self.template = GenshiTextTemplate(content, lookup='lenient') else: self.template = GenshiTextTemplate(content)
def test_end_with_args(self): tmpl = NewTextTemplate( """ {% if foo %} bar {% end 'if foo' %}""" ) self.assertEqual("\n", tmpl.generate(foo=False).render(encoding=None))
def test_exec_def(self): tmpl = NewTextTemplate("""{% python def foo(): return 42 %} ${foo()} """) self.assertEqual(""" 42 """, tmpl.generate().render(encoding=None))
def test_exec_def(self): tmpl = NewTextTemplate(u"""{% python def foo(): return 42 %} ${foo()} """) self.assertEqual(u""" 42 """, str(tmpl.generate()))
def _notify_admins(self, permission, email_path, debug='false'): is_debug = debug.lower() in ('true', 'yes') if permission != 'TRAC_ADMIN': raise AdminCommandError('Only TRAC_ADMIN permission is supported') # A standard thing to do in IAdminCommandProviders (otherwise, # accessing project_identifier would give errors) if not hasattr(self.env, 'project_identifier'): MultiProjectEnvironmentInit(self.env).environment_needs_upgrade(None) env_name = self.env.project_identifier if env_name == self.env.config.get('multiproject', 'sys_home_project_name'): raise AdminCommandError('Command does not support home project') if not os.path.exists(email_path): raise AdminCommandError(_("Email template was not found!")) project = Project.get(self.env) email_template = '' try: with open(email_path) as fd: email_template = fd.read() except OSError as e: raise AdminCommandError(_("Error with opening file %(path)s: %(error_msg)s", path=email_path, error_msg=e)) except Exception as e: raise AdminCommandError(_("Unknown error when parsing file %(path)s: %(error_msg)s", path=email_path, error_msg=e)) email_template = [i.strip() for i in email_template.split('\n', 1) if i] if not len(email_template) > 1 or not all(email_template): raise AdminCommandError(_("Email template %(path)s was invalid.", path=email_path)) subject, body = email_template text_template = NewTextTemplate(body) admins = project.get_admin_email_addresses() data = {'env_name': env_name} if is_debug: printout('## DEBUG MODE - NOT SENDING EMAILS ##') printout("project: {0}".format(env_name)) printout("to: {0}".format(','.join(admins))) printout("subject: {0}".format(subject)) printout("----------------------------") printout(text_template.generate(**data)) printout("----------------------------") if not is_debug: notifier = EmailNotifier(self.env, subject=subject, data=data) notifier.template = text_template notifier.notify(admins) printout('Emails sent')
def _notify_admins(self, permission, email_path, debug="false"): is_debug = debug.lower() in ("true", "yes") if permission != "TRAC_ADMIN": raise AdminCommandError("Only TRAC_ADMIN permission is supported") # A standard thing to do in IAdminCommandProviders (otherwise, # accessing project_identifier would give errors) if not hasattr(self.env, "project_identifier"): MultiProjectEnvironmentInit(self.env).environment_needs_upgrade(None) env_name = self.env.project_identifier if env_name == self.env.config.get("multiproject", "sys_home_project_name"): raise AdminCommandError("Command does not support home project") if not os.path.exists(email_path): raise AdminCommandError(_("Email template was not found!")) project = Project.get(self.env) email_template = "" try: with open(email_path) as fd: email_template = fd.read() except OSError as e: raise AdminCommandError(_("Error with opening file %(path)s: %(error_msg)s", path=email_path, error_msg=e)) except Exception as e: raise AdminCommandError( _("Unknown error when parsing file %(path)s: %(error_msg)s", path=email_path, error_msg=e) ) email_template = [i.strip() for i in email_template.split("\n", 1) if i] if not len(email_template) > 1 or not all(email_template): raise AdminCommandError(_("Email template %(path)s was invalid.", path=email_path)) subject, body = email_template text_template = NewTextTemplate(body) admins = project.get_admin_email_addresses() data = {"env_name": env_name} if is_debug: printout("## DEBUG MODE - NOT SENDING EMAILS ##") printout("project: {0}".format(env_name)) printout("to: {0}".format(",".join(admins))) printout("subject: {0}".format(subject)) printout("----------------------------") printout(text_template.generate(**data)) printout("----------------------------") if not is_debug: notifier = EmailNotifier(self.env, subject=subject, data=data) notifier.template = text_template notifier.notify(admins) printout("Emails sent")
def format_subj(self, summary): template = self.config.get("notification", "ticket_subject_template") template = NewTextTemplate(template.encode("utf8")) prefix = self.config.get("notification", "smtp_subject_prefix") if prefix == "__default__": prefix = "[%s]" % self.env.project_name data = {"prefix": prefix, "summary": summary, "ticket": self.ticket, "env": self.env} return template.generate(**data).render("text", encoding=None).strip()
def test_empty_lines1_with_crlf(self): tmpl = NewTextTemplate('Your items:\r\n' '\r\n' '{% for item in items %}\\\r\n' ' * ${item}\r\n' '{% end %}') self.assertEqual('Your items:\r\n' '\r\n' ' * 0\r\n' ' * 1\r\n' ' * 2\r\n', tmpl.generate(items=range(3)).render(encoding=None))
def format_subject(self): template = self.config.get('fullblog-notification', 'subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.config.get('project', 'name') action = self.action.strip('post_').replace('_', ' ') data = {'blog': self.blog, 'prefix': prefix, 'action': action} return template.generate(**data).render('text', encoding=None).strip()
def test_empty_lines1(self): tmpl = NewTextTemplate("""Your items: {% for item in items %}\ * ${item} {% end %}""") self.assertEqual("""Your items: * 0 * 1 * 2 """, tmpl.generate(items=range(3)).render())
def test_empty_lines1_with_crlf(self): tmpl = NewTextTemplate('Your items:\r\n' '\r\n' '{% for item in items %}\\\r\n' ' * ${item}\r\n' '{% end %}') self.assertEqual( 'Your items:\r\n' '\r\n' ' * 0\r\n' ' * 1\r\n' ' * 2\r\n', tmpl.generate(items=range(3)).render(encoding=None))
def format_subj(self, tickets_descr): template = self.config.get('notification', 'batch_subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.env.project_name data = { 'prefix': prefix, 'tickets_descr': tickets_descr, 'env': self.env, } subj = template.generate(**data).render('text', encoding=None).strip() return shorten_line(subj)
def format_subject(self, action): template = self.config.get('wiki-notification', 'subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.config.get('project', 'name') data = { 'pagename': self.old_name or self.page.name, 'prefix': prefix, 'action': action, 'env': self.env, } return template.generate(**data).render('text', encoding=None).strip()
def format_subj(self, tickets_descr): template = self.config.get('notification','batch_subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.env.project_name data = { 'prefix': prefix, 'tickets_descr': tickets_descr, 'env': self.env, } return template.generate(**data).render('text', encoding=None).strip()
def render_ticket_action_control(self, req, ticket, action): section = self.config['ticket-workflow-notifications'] hints = [] for name in self.notifications_for_action(action): ctx = self.build_template_context(req, ticket, name) subject = TextTemplate(section.get('%s.subject' % name).replace("\\n", "\n") ).generate(**ctx).render(encoding=None) subject = ' '.join(subject.splitlines()) recipients = TextTemplate(section.get('%s.recipients' % name).replace("\\n", "\n") ).generate(**ctx).render(encoding=None) hints.append(_('An email titled "%(subject)s" will be sent to the following recipients: %(recipients)s', subject=subject, recipients=recipients)) return None, None, '. '.join(hints) + '.' if hints else None
def notify(self, req, ticket, name): ctx = self.build_template_context(req, ticket, name) section = self.config['ticket-workflow-notifications'] condition = section.get('%s.condition' % name, None) if condition is not None: condition_value = TextTemplate(condition.replace("\\n", "\n") ).generate(**ctx).render(encoding=None).strip() if condition_value != 'True': self.log.debug("Skipping notification %s for ticket %s " "because condition '%s' did not evaluate to True (it evaluated to %s)" % ( name, ticket.id if ticket.exists else "(new ticket)", condition, condition_value)) return False else: self.log.debug("Sending notification %s for ticket %s " "because condition '%s' did evaluate to True" % ( name, ticket.id if ticket.exists else "(new ticket)", condition)) else: self.log.debug("Sending notification %s for ticket %s " "because there was no condition" % ( name, ticket.id if ticket.exists else "(new ticket)")) body = TextTemplate(section.get('%s.body' % name).replace("\\n", "\n") ).generate(**ctx).render(encoding=None) subject = TextTemplate(section.get('%s.subject' % name).replace("\\n", "\n") ).generate(**ctx).render(encoding=None) subject = ' '.join(subject.splitlines()) recipients = TextTemplate(section.get('%s.recipients' % name).replace("\\n", "\n") ).generate(**ctx).render(encoding=None) recipients = [r.strip() for r in recipients.split(",")] notifier = WorkflowNotifyEmail( self.env, template_name='ticket_notify_workflow_email.txt', recipients=recipients, data={'body': body}) vars = inspect.getargspec(notifier.notify)[0] if len(vars) == 3: # Trac 0.12 and below args = [ticket.id, subject] elif len(vars) == 4: # Trac 0.13 and up have an additional `author` argument to trac.notification:NotifyEmail.notify args = [ticket.id, subject, req.authname] else: self.log.error("Cannot send notification %s for ticket %s " "because this trac version has an unknown NotifyEmail.notify signature " "%s" % (name, ticket.id if ticket.exists else "(new ticket)", condition, vars)) return False notifier.notify(*args)
def format_subj(self, summary): template = self.config.get('notification', 'ticket_subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.env.project_name data = { 'prefix': prefix, 'summary': summary, 'ticket': self.ticket, 'env': self.env, } return template.generate(**data).render('text', encoding=None).strip()
def federador(self): log.debug('Leyendo catalog') data_dict = { 'page': toolkit.request.params.get('page'), 'modified_since': toolkit.request.params.get('modified_since'), } try: log.debug('Obteniendo datasets para el federador') dataset_dict = toolkit.get_action('iaest_federador')({}, data_dict) log.debug('Creando extra_vars') c = {'c': {'pkg': dataset_dict}} log.debug('Creando c %s', c) toolkit.response.headers[ 'Content-Type'] = 'application/rdf+xml;charset=UTF-8' loader_render = NewTextTemplate( "application/rdf+xml; charset=utf-8", True, 'rdf') return render('package/federador.rdf', extra_vars=c, loader=loader_render) except toolkit.ValidationError, e: toolkit.abort(409, str(e))
def notify(self, to, cc=None, subject=None, body=None): """ Provide a direct way to send an email :param list to: Email addresses where to send email to :param list cc: CC email addresses :param str subject: Email subject if not set in init (or want to override it) :param str subject: Email body if not set in init (or want to override it) :raises: TracError if email sending fails """ self.to = [to] if isinstance(to, basestring) else to self.cc = cc or [] self.subject = subject or self.subject # If body msg is set, use it as-is if body: self.data = {'body':body} self.template = NewTextTemplate('${body}') # Load non-default template elif self.template_name != 'notify.txt': # Reload template so that it can be set after for the instance self.template = Chrome(self.env).load_template(self.template_name, method='text') # Raise possible exceptions (connection, smtp) as unified TracError try: return super(EmailNotifier, self).notify(None, self.subject) except (socket.error, smtplib.SMTPException), e: self.env.log.exception('Failed to send email to: %s' % self.to) raise TracError(e)
def build_clone_form(self, req, ticket, data): fields = {} for derivation in self.derived_fields: template, new_field = derivation.split('->') if new_field in self.excluded_fields: continue template = NewTextTemplate(template.replace("\\n", "\n").encode('utf8')) fields[new_field] = template.generate(ticket=ticket).render('text', encoding=None).strip() for f in data.get('fields', []): name = f['name'] if name in fields: continue if name not in self.excluded_fields: fields[name] = ticket[name] return fields
def build_clone_form(self, req, ticket, data): fields = {} for derivation in self.derived_fields: template, new_field = derivation.split('->') if new_field in self.excluded_fields: continue template = NewTextTemplate( template.replace("\\n", "\n").encode('utf8')) fields[new_field] = template.generate(ticket=ticket).render( 'text', encoding=None).strip() for f in data.get('fields', []): name = f['name'] if name in fields: continue if name not in self.excluded_fields: fields[name] = ticket[name] return fields
def test_exec_with_trailing_space(self): """ Verify that a code block with trailing space does not cause a syntax error (see ticket #127). """ NewTextTemplate(u""" {% python bar = 42 $} """)
def format_subj(self, summary, newticket=True): template = self.config.get('notification', 'ticket_subject_template') template = NewTextTemplate(template.encode('utf8')) prefix = self.config.get('notification', 'smtp_subject_prefix') if prefix == '__default__': prefix = '[%s]' % self.env.project_name data = { 'prefix': prefix, 'summary': summary, 'ticket': self.ticket, 'env': self.env, } subj = template.generate(**data).render('text', encoding=None).strip() if not newticket: subj = "Re: " + subj return subj
class TextTemplate(object): """A specific template that can be used to output textual content. It works as the ODT or ODS templates, minus the fact that is does not support images. """ def __init__(self, template, outfile, encoding='utf-8', ignore_undefined_variables=False): """ :param template: a genshi text template. For more information you can refer to the Genshi documentation: http://genshi.edgewall.org/wiki/ApiDocs/genshi.template.text :type template: a string representing the full path name to a template file. :param outfile: the desired file name for the resulting text document :type outfile: a string representing the full filename for output :param encoding: By default the text encoding of the output will be UTF8. If you want another encoding you must specify it. :type encoding: a string representin the desired output encoding :param ignore_undefined_variables: Not defined variables are replaced with an empty string during template rendering if True :type ignore_undefined_variables: boolean. Default is False """ self.outputfilename = outfile self.encoding = encoding content = codecs.open(template, 'rb', encoding='utf-8').read() if ignore_undefined_variables: self.template = GenshiTextTemplate(content, lookup='lenient') else: self.template = GenshiTextTemplate(content) def render(self, data): """Render the template with the provided data. :param data: a dictionnary containing your data (preferably a iterators) :return: Nothing """ with codecs.open(self.outputfilename, 'wb+', encoding=self.encoding) as outfile: for kind, data, pos in self.template.generate(**data): outfile.write(data)
def test_empty_lines2(self): tmpl = NewTextTemplate( """Your items: {% for item in items %}\ * ${item} {% end %}""" ) self.assertEqual( """Your items: * 0 * 1 * 2 """, tmpl.generate(items=list(range(3))).render(encoding=None), )
def test_escaping(self): tmpl = NewTextTemplate('\\{% escaped %}') self.assertEqual('{% escaped %}', str(tmpl.generate()))
("factoryMate.py", "%s-factoryMate.py" % name), ("panel-applet.template", "org.gnome.applets.%s.panel-applet" % name), ] for root,dirs,files in walk("templates/debian"): for f in files: fullpath = join(root,f)[len("templates/"):] templates.append((fullpath, fullpath)) for (src, dest) in templates: src = join("templates", src) dest = join(opts.folder, dest) destdir = dirname(dest) if destdir != "" and not exists(destdir): makedirs(destdir) tmpl = NewTextTemplate(open(src).read()) stream = tmpl.generate( name = opts.name, scriptRoot = scriptRoot, description = opts.description, icon = opts.icon, category = opts.category, lowerName = opts.name.lower(), maintainer = opts.maintainer, email = opts.email, now = now) open(dest, "wb").write(stream.render()) bits = stat(src).st_mode chmod(dest, bits)
def test_comment_escaping(self): tmpl = NewTextTemplate('\\{# escaped comment #}') self.assertEqual('{# escaped comment #}', tmpl.generate().render(encoding=None))
def test_latin1_encoded(self): text = "$foo\xf6$bar".encode("iso-8859-1") tmpl = NewTextTemplate(text, encoding="iso-8859-1") self.assertEqual("x\xf6y", tmpl.generate(foo="x", bar="y").render(encoding=None))
def test_comment(self): tmpl = NewTextTemplate('{# a comment #}') self.assertEqual('', tmpl.generate().render(encoding=None))
def test_unicode_input(self): text = u'$foo\xf6$bar' tmpl = NewTextTemplate(text) self.assertEqual(u'x\xf6y', unicode(tmpl.generate(foo='x', bar='y')))
def test_end_with_args(self): tmpl = NewTextTemplate(""" {% if foo %} bar {% end 'if foo' %}""") self.assertEqual('\n', str(tmpl.generate(foo=False)))
def genshiText(indented_string): t = NewTextTemplate(trim(indented_string)) return lambda **kw: t.generate(**kw).render()
def test_comment_escaping(self): tmpl = NewTextTemplate('\\{# escaped comment #}') self.assertEqual('{# escaped comment #}', str(tmpl.generate()))
def test_comment(self): tmpl = NewTextTemplate('{# a comment #}') self.assertEqual('', str(tmpl.generate()))
def test_unicode_input(self): text = "$foo\xf6$bar" tmpl = NewTextTemplate(text) self.assertEqual("x\xf6y", tmpl.generate(foo="x", bar="y").render(encoding=None))
def test_unicode_input(self): text = u'$foo\xf6$bar' tmpl = NewTextTemplate(text) self.assertEqual(u'x\xf6y', tmpl.generate(foo='x', bar='y').render(encoding=None))
def test_latin1_encoded(self): text = u'$foo\xf6$bar'.encode('iso-8859-1') tmpl = NewTextTemplate(text, encoding='iso-8859-1') self.assertEqual(u'x\xf6y', unicode(tmpl.generate(foo='x', bar='y')))
def test_escaping(self): tmpl = NewTextTemplate("\\{% escaped %}") self.assertEqual("{% escaped %}", tmpl.generate().render(encoding=None))
def test_end_with_args(self): tmpl = NewTextTemplate(""" {% if foo %} bar {% end 'if foo' %}""") self.assertEqual('\n', tmpl.generate(foo=False).render(encoding=None))