def _provider_failure(self, exc, req, ep, current_filters, all_filters): """Raise a TracError exception explaining the failure of a provider. At the same time, the message will contain a link to the timeline without the filters corresponding to the guilty event provider `ep`. """ ep_name, exc_name = [i.__class__.__name__ for i in (ep, exc)] self.log.error("Timeline event provider failed: %s", exception_to_unicode(exc, traceback=True)) guilty_filters = [f[0] for f in ep.get_timeline_filters(req)] guilty_kinds = [f[1] for f in ep.get_timeline_filters(req)] other_filters = [f for f in current_filters if not f in guilty_filters] if not other_filters: other_filters = [f for f in all_filters if not f in guilty_filters] args = [(a, req.args.get(a)) for a in ("from", "format", "max", "daysback")] href = req.href.timeline(args + [(f, "on") for f in other_filters]) raise TracError( tag( tag.p( ", ".join(guilty_kinds), " event provider (", tag.tt(ep_name), ") failed:", tag.br(), exc_name, ": ", to_unicode(exc), class_="message", ), tag.p("You may want to see the other kind of events from the ", tag.a("Timeline", href=href)), ) )
def render_registration_fields(self, req, data): """Add an email address text input field to the registration form.""" # Preserve last input for editing on failure instead of typing # everything again. old_value = req.args.get('email', '').strip() insert = tag.label(_("Email:"), tag.input(type='text', name='email', size=20, class_='textwidget', value=old_value) ) # Deferred import required to aviod circular import dependencies. from acct_mgr.web_ui import AccountModule reset_password = AccountModule(self.env).reset_password_enabled verify_account = is_enabled(self.env, EmailVerificationModule) and \ EmailVerificationModule(self.env).verify_email if verify_account: # TRANSLATOR: Registration form hints for a mandatory input field. hint = tag.p(_("""The email address is required for Trac to send you a verification token."""), class_='hint') if reset_password: hint = tag(hint, tag.p(_( """Entering your email address will also enable you to reset your password if you ever forget it."""), class_='hint') ) return tag(insert, hint), data elif reset_password: # TRANSLATOR: Registration form hint, if email input is optional. hint = tag.p(_("""Entering your email address will enable you to reset your password if you ever forget it."""), class_='hint') return dict(optional=tag(insert, hint)), data else: # Always return the email text input itself as optional field. return dict(optional=insert), data
def _provider_failure(self, exc, req, ep, current_filters, all_filters): """Raise a TracError exception explaining the failure of a provider. At the same time, the message will contain a link to the timeline without the filters corresponding to the guilty event provider `ep`. """ self.log.error('Timeline event provider failed: %s', exception_to_unicode(exc, traceback=True)) ep_kinds = dict((f[0], f[1]) for f in ep.get_timeline_filters(req) or []) ep_filters = set(ep_kinds.keys()) current_filters = set(current_filters) other_filters = set(current_filters) - ep_filters if not other_filters: other_filters = set(all_filters) - ep_filters args = [(a, req.args.get(a)) for a in ('from', 'format', 'max', 'daysback')] href = req.href.timeline(args + [(f, 'on') for f in other_filters]) # TRANSLATOR: ...want to see the 'other kinds of events' from... (link) other_events = tag.a(_('other kinds of events'), href=href) raise TracError(tag( tag.p(tag_("Event provider %(name)s failed for filters " "%(kinds)s: ", name=tag.tt(ep.__class__.__name__), kinds=', '.join('"%s"' % ep_kinds[f] for f in current_filters & ep_filters)), tag.b(exception_to_unicode(exc)), class_='message'), tag.p(tag_("You may want to see the %(other_events)s from the " "Timeline or notify your Trac administrator about the " "error (detailed information was written to the log).", other_events=other_events))))
def notify(self, resid, subject, author=None): self.subject = subject config = self.config['notification'] if not config.getbool('smtp_enabled'): return from_email, from_name = '', '' if author and config.getbool('smtp_from_author'): from_email = self.get_smtp_address(author) if from_email: from_name = self.name_map.get(author, '') if not from_name: mo = self.longaddr_re.search(author) if mo: from_name = mo.group(1) if not from_email: from_email = config.get('smtp_from') from_name = config.get('smtp_from_name') or self.env.project_name self.replyto_email = config.get('smtp_replyto') self.from_email = from_email or self.replyto_email self.from_name = from_name if not self.from_email and not self.replyto_email: raise TracError( tag( tag.p(_('Unable to send email due to identity crisis.')), tag.p( _( 'Neither %(from_)s nor %(reply_to)s are specified ' 'in the configuration.', from_=tag.b('notification.from'), reply_to=tag.b('notification.reply_to')))), _('SMTP Notification Error')) Notify.notify(self, resid)
def notify(self, resid, subject, author=None): self.subject = subject config = self.config['notification'] if not config.getbool('smtp_enabled'): return from_email, from_name = '', '' if author and config.getbool('smtp_from_author'): from_email = self.get_smtp_address(author) if from_email: from_name = self.name_map.get(author, '') if not from_name: mo = self.longaddr_re.search(author) if mo: from_name = mo.group(1) if not from_email: from_email = config.get('smtp_from') from_name = config.get('smtp_from_name') or self.env.project_name self.replyto_email = config.get('smtp_replyto') self.from_email = from_email or self.replyto_email self.from_name = from_name if not self.from_email and not self.replyto_email: message = tag( tag.p(_('Unable to send email due to identity crisis.')), # convert explicitly to `Fragment` to avoid breaking message # when passing `LazyProxy` object to `Fragment` tag.p(to_fragment(tag_( "Neither %(from_)s nor %(reply_to)s are specified in the " "configuration.", from_=tag.strong("[notification] smtp_from"), reply_to=tag.strong("[notification] smtp_replyto"))))) raise TracError(message, _("SMTP Notification Error")) Notify.notify(self, resid)
def notify(self, resid, subject, author=None): self.subject = subject config = self.config['notification'] if not config.getbool('smtp_enabled'): return from_email, from_name = '', '' if author and config.getbool('smtp_from_author'): from_email = self.get_smtp_address(author) if from_email: from_name = self.name_map.get(author, '') if not from_name: mo = self.longaddr_re.search(author) if mo: from_name = mo.group(1) if not from_email: from_email = config.get('smtp_from') from_name = config.get('smtp_from_name') or self.env.project_name self.replyto_email = config.get('smtp_replyto') self.from_email = from_email or self.replyto_email self.from_name = from_name if not self.from_email and not self.replyto_email: raise TracError(tag( tag.p(_('Unable to send email due to identity crisis.')), tag.p(_('Neither %(from_)s nor %(reply_to)s are specified ' 'in the configuration.', from_=tag.b('notification.from'), reply_to=tag.b('notification.reply_to')))), _('SMTP Notification Error')) Notify.notify(self, resid)
def get_existing_node(req, repos, path, rev): try: return repos.get_node(path, rev) except NoSuchNode, e: raise ResourceNotFound(tag( tag.p(e.message, class_="message"), tag.p("You can ", tag.a("search", href=req.href.log(path, rev=rev, mode='path_history')), " in the repository history to see if that path existed but" " was later removed")))
def get_existing_node(req, repos, path, rev): try: return repos.get_node(path, rev) except NoSuchNode, e: # TRANSLATOR: You can 'search' in the repository history... (link) search_a = tag.a(_("search"), href=req.href.log(path, rev=rev, mode='path_history')) raise ResourceNotFound(tag( tag.p(e.message, class_="message"), tag.p(tag_("You can %(search)s in the repository history to see " "if that path existed but was later removed", search=search_a))))
def render_inline_content(self, _env, _context, _content,mode): #Sceneheaders must start with INT, EXT, or EST sceneheader_re = re.compile('\n(INT|EXT|[^a-zA-Z0-9]EST)([\.\-\s]+?)(.+?)([A-Za-z0-9\)\s\.])\n') #Transitions transitions_re = re.compile('\n([^<>\na-z]*?:|FADE TO BLACK\.|FADE OUT\.|CUT TO BLACK\.)[\s]??\n') #action blocks actions_re = re.compile('\n{2}(([^a-z\n\:]+?[\.\?\,\s\!]*?)\n{2}){1,2}') #character cues characters_re = re.compile('\n{1}(\w+[\.-]*[\s]*\w+?[^\!\)\?\.\s])\n{1}') # characters_re = re.compile('\n([^<>a-z\s][^a-z:\!\?]*?[^a-z\(\!\?:,][\s]??)\n{1}') #parentheticals parentheticals_re = re.compile('(\([^<>]*?\)[\s]??)\n') #dialog dialog_re = re.compile('(<p class="character">.*<\/p>|<p class="parenthetical">.*<\/p>)\n{0,1}(.+?)\n') #default default_re = re.compile('([^<>]*?)\n') #clean up cleanup_re = re.compile('<p class="action">[\n\s]*?<\/p>') #styling # bold_re = re.compile('(\*{2}|\[b\])(.*?)(\*{2}|\[\/b\])') # italic_re = re.compile('(\*{1}|\[i\])(.*?)(\*{1}|\[\/i\])') # underline_re = re.compile('(_|\[u\])(.*?)(_|\[\/u\])') theoutput = tag.div(class_="scrippet"+mode) # self.log.debug("BEFORE SCENE: %s" % _content) _content = sceneheader_re.sub(r'<p class="sceneheader">\1\2\3\4</p>' + "\n",_content) # self.log.debug("BEFORE TRANSITIONS: %s" % _content) _content = transitions_re.sub(r'<p class="transition">\1</p>' + "\n",_content) # self.log.debug("BEFORE ACTIONS: %s" % _content) _content = actions_re.sub("\n" + r'<p class="action">\2</p>' + "\n",_content) # self.log.debug("BEFORE CHARACTERS: %s" % _content) # self.log.debug(_content); _content = characters_re.sub(r'<p class="character">\1</p>',_content) # self.log.debug(characters_re.sub(r'<p class="character">\1</p>',_content)); _content = parentheticals_re.sub(r'<p class="parenthetical">\1</p>',_content); #format_to_oneliner(_env, _context, _content)) _content = dialog_re.sub(r'\1' + "\n" + r'<p class="dialogue">\2</p>' + "\n",_content); #format_to_oneliner(_env, _context, _content)) _content = default_re.sub(r'<p class="action">\1</p>' + "\n",_content) _content = cleanup_re.sub("",_content) # _content = bold_re.sub(r'<b>\2</b>',_content) # _content = italic_re.sub(r'<i>\2</i>',_content) # _content = underline_re.sub(r'<u>\2</u>',_content) para_re = re.compile(r'<p class="(?P<_class>.*?)">(?P<_body>.*?)</p>') for line in _content.splitlines(): # self.log.debug("LINE: %s" % line) m = para_re.search(line) if m != None: # self.log.debug("BODY: %s" % m.group('_body')) # self.log.debug("CLASS: %s" % m.group('_class')) if "FADE IN" in m.group('_body') and m.group('_class') == "transition": theoutput.append(tag.p(format_to_oneliner(_env, _context,m.group('_body')),class_="action"+mode)) else: theoutput.append(tag.p(format_to_oneliner(_env, _context,m.group('_body')),class_=m.group('_class')+mode)) return theoutput
def get_existing_node(req, repos, path, rev): try: return repos.get_node(path, rev) except NoSuchNode, e: # TRANSLATOR: You can 'search' in the repository history... (link) search_a = tag.a(_("search"), href=req.href.log(repos.reponame or None, path, rev=rev, mode='path_history')) raise ResourceNotFound(tag( tag.p(e.message, class_="message"), tag.p(tag_("You can %(search)s in the repository history to see " "if that path existed but was later removed", search=search_a))))
def test_tracerror_with_tracerror_with_element(self): message = tag.p('Powered by ', tag.a('Trac', href='http://trac.edgewall.org/')) rv = to_fragment(TracError(TracError(message))) self.assertEqual(Element, type(rv)) self.assertEqual('<p>Powered by <a href="http://trac.edgewall.org/">' 'Trac</a></p>', unicode(rv))
def render_registration_fields(self, req, data): """Add a hidden text input field to the registration form, and a visible one with mandatory input as well, if token is configured. """ if self.reg_basic_token: # Preserve last input for editing on failure instead of typing # everything again. old_value = req.args.get('basic_token', '') # TRANSLATOR: Hint for visible bot trap registration input field. hint = tag.p(Markup(_( """Apologies for the inconvenience, but please use the Sugarlabs Wiki, find the page referring to find the gold in the pot, and insert here the four words on the second line, or send mail to systems mailing list.""", token=tag.b(self.reg_basic_token))), class_='hint') insert = tag( tag.label(_("Parole:"), tag.input(type='text', name='basic_token', size=20, class_='textwidget', value=old_value)), hint ) else: insert = None # TRANSLATOR: Registration form hint for hidden bot trap input field. insert = tag(insert, tag.input(type='hidden', name='sentinel', title=_("Better do not fill this field.")) ) return insert, data
def process_request(self, req): match = re.match(r'^/l10nhelp/(.*)$', req.path_info) template = 'l10nhelp/%s.html' % match.group(1) data = {} data['ajax_request'] = ajax_request = \ req.get_header('X-Requested-With') == 'XMLHttpRequest' and \ req.args.get('ajax_request') == '1' last_modified = self.template_available(template) # Include cache headers to ease on server requests since this data does # not change besides the locale to render it req.check_modified(last_modified, extra=req.locale) if not last_modified: if ajax_request: req.write(tag(tag.h2(_('Error')), tag.p(_("Help Not Found")))) raise RequestDone raise ResourceNotFound(_("Help Not Found")) if not ajax_request: data.update( {'template': template} ) return 'l10n_help_base.html', data, None output = self.rendered_templates.get((req.locale, template)) if output is None: output = WeakReferenceRenderer(self.env, template, data) self.rendered_templates[(req.locale, template)] = output req.write(output.render(req)) raise RequestDone
def render_registration_fields(self, req, data): """Add a hidden text input field to the registration form, and a visible one with mandatory input as well, if token is configured. """ if self.reg_basic_token: # Preserve last input for editing on failure instead of typing # everything again. old_value = req.args.get('basic_token', '') # TRANSLATOR: Hint for visible bot trap registration input field. hint = tag.p(Markup( _("""Please type [%(token)s] as verification token, exactly replicating everything within the braces.""", token=tag.b(self.reg_basic_token))), class_='hint') insert = tag( tag.label( _("Parole:"), tag.input(type='text', name='basic_token', size=20, class_='textwidget', value=old_value)), hint) else: insert = None # TRANSLATOR: Registration form hint for hidden bot trap input field. insert = tag( insert, tag.input(type='hidden', name='sentinel', title=_("Better do not fill this field."))) return insert, data
def render_registration_fields(self, req, data): """Add a hidden text input field to the registration form, and a visible one with mandatory input as well, if token is configured. """ if self.reg_basic_token: # Preserve last input for editing on failure instead of typing # everything again. old_value = req.args.get('basic_token', '') # TRANSLATOR: Hint for visible bot trap registration input field. hint = tag.p(Markup(_( """Please type [%(token)s] as verification token, exactly replicating everything within the braces.""", token=tag.b(self.reg_basic_token))), class_='hint') insert = tag( tag.label(_("Parole:"), tag.input(type='text', name='basic_token', size=20, class_='textwidget', value=old_value)), hint ) else: insert = None # TRANSLATOR: Registration form hint for hidden bot trap input field. insert = tag(insert, tag.input(type='hidden', name='sentinel', title=_("Better do not fill this field.")) ) return insert, data
def _render(self, formatter, cols, name_pat, size, header, limit): #noinspection PyArgumentList icon = Icons(self.env) icon_dir = icon.icon_location(size)[1] files = fnmatch.filter(os.listdir(icon_dir), name_pat + '.png') icon_names = [os.path.splitext(p)[0] for p in files] if limit: displayed_icon_names = reduce_names(icon_names, limit) else: displayed_icon_names = icon_names icon_table = render_table(displayed_icon_names, cols, lambda name: icon._render_icon(formatter, name, size)) if not len(icon_names): message = 'No %s icon matches %s' % (SIZE_DESCR[size], name_pat) elif len(icon_names) == 1: message = 'Showing the only %s icon matching %s' % \ (SIZE_DESCR[size], name_pat) elif len(displayed_icon_names) == len(icon_names): message = 'Showing all %d %s icons matching %s' % \ (len(icon_names), SIZE_DESCR[size], name_pat) else: message = 'Showing %d of %d %s icons matching %s' % \ (len(displayed_icon_names), len(icon_names), SIZE_DESCR[size], name_pat) return tag.div(tag.p(tag.small(message)) if header else '', icon_table)
def expand_macro(self, formatter, name, content, args=None): args = args or {} reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource('repository', reponame) if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any(int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p(_("(The changeset message doesn't reference this " "ticket)"), class_='hint') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context.child('changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def expand_macro(self, formatter, name, content, args={}): reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource('repository', reponame) if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any( int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p( "(The changeset message doesn't reference this " "ticket)", class_='hint') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context.child( 'changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def expand_macro(self, formatter, name, content, args={}): reponame = args.get("repository") or "" rev = args.get("revision") repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev resource = repos.resource except Exception: message = content resource = Resource("repository", reponame) if formatter.context.resource.realm == "ticket": ticket_re = CommitTicketUpdater.ticket_re if not any(int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p("(The changeset message doesn't reference this " "ticket)", class_="hint") if ChangesetModule(self.env).wiki_format_messages: return tag.div( format_to_html( self.env, formatter.context.child("changeset", rev, parent=resource), message, escape_newlines=True ), class_="message", ) else: return tag.pre(message, class_="message")
def _launch(self, encoded_input, *args): """Launch a process (cmd), and returns exitcode, stdout + stderr""" # Note: subprocess.Popen doesn't support unicode options arguments # (http://bugs.python.org/issue1759845) so we have to encode them. # Anyway, dot expects utf-8 or the encoding specified with -Gcharset. encoded_cmd = [] for arg in args: if isinstance(arg, unicode): arg = arg.encode(self.encoding, 'replace') encoded_cmd.append(arg) p = subprocess.Popen(encoded_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if input: p.stdin.write(encoded_input) p.stdin.close() out = p.stdout.read() err = p.stderr.read() reason = None if p.wait() != 0: reason = _("failed with the following output:") if err or out: reason = _("succeeded but emitted the following output:") if reason: return tag.p(tag.br(), _("The command:"), tag.pre(repr(' '.join(encoded_cmd))), reason, out and tag.pre(repr(out)), err and tag.pre(repr(err)))
def _launch(self, encoded_input, *args): """Launch a process (cmd), and returns exitcode, stdout + stderr""" # Note: subprocess.Popen doesn't support unicode options arguments # (http://bugs.python.org/issue1759845) so we have to encode them. # Anyway, dot expects utf-8 or the encoding specified with -Gcharset. encoded_cmd = [] for arg in args: if isinstance(arg, unicode): arg = arg.encode(self.encoding, 'replace') encoded_cmd.append(arg) p = subprocess.Popen(encoded_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if encoded_input: p.stdin.write(encoded_input) p.stdin.close() out = p.stdout.read() err = p.stderr.read() failure = p.wait() != 0 if failure or err or out: return (failure, tag.p(tag.br(), _("The command:"), tag.pre(repr(' '.join(encoded_cmd))), (_("succeeded but emitted the following output:"), _("failed with the following output:"))[failure], out and tag.pre(repr(out)), err and tag.pre(repr(err)))) else: return (False, None)
def _render(self, formatter, cols, name_pat, size, header, limit): #noinspection PyArgumentList icon = Icons(self.env) icon_dir = icon.icon_location(size)[1] files = fnmatch.filter(os.listdir(icon_dir), '%s.png' % name_pat) icon_names = [os.path.splitext(p)[0] for p in files] if limit: displayed_icon_names = reduce_names(icon_names, limit) else: displayed_icon_names = icon_names icon_table = render_table(displayed_icon_names, cols, lambda name: icon._render_icon(formatter, name, size)) if not len(icon_names): message = 'No %s icon matches %s' % (SIZE_DESCR[size], name_pat) elif len(icon_names) == 1: message = 'Showing the only %s icon matching %s' % \ (SIZE_DESCR[size], name_pat) elif len(displayed_icon_names) == len(icon_names): message = 'Showing all %d %s icons matching %s' % \ (len(icon_names), SIZE_DESCR[size], name_pat) else: message = 'Showing %d of %d %s icons matching %s' % \ (len(displayed_icon_names), len(icon_names), SIZE_DESCR[size], name_pat) return tag.div(tag.p(tag.small(message)) if header else '', icon_table)
class MacroListMacro(WikiMacroBase): _domain = 'messages' _description = cleandoc_( """Display a list of all installed Wiki macros, including documentation if available. Optionally, the name of a specific macro can be provided as an argument. In that case, only the documentation for that macro will be rendered. Note that this macro will not be able to display the documentation of macros if the `PythonOptimize` option is enabled for mod_python! """) def expand_macro(self, formatter, name, content): from trac.wiki.formatter import system_message content = content.strip() if content else '' name_filter = content.strip('*') def get_macro_descr(): for macro_provider in formatter.wiki.macro_providers: names = list(macro_provider.get_macros() or []) if name_filter and not any(name.startswith(name_filter) for name in names): continue try: name_descriptions = [ (name, macro_provider.get_macro_description(name)) for name in names] except Exception, e: yield system_message( _("Error: Can't get description for macro %(name)s", name=names[0]), e), names else: for descr, pairs in groupby(name_descriptions, key=lambda p: p[1]): if descr: if isinstance(descr, (tuple, list)): descr = dgettext(descr[0], descr[1]) else: descr = to_unicode(descr) or '' if content == '*': descr = format_to_oneliner( self.env, formatter.context, descr, shorten=True) else: descr = format_to_html( self.env, formatter.context, descr) yield descr, [name for name, descr in pairs] return tag.div(class_='trac-macrolist')( (tag.h3(tag.code('[[', names[0], ']]'), id='%s-macro' % names[0]), len(names) > 1 and tag.p(tag.strong(_("Aliases:")), [tag.code(' [[', alias, ']]') for alias in names[1:]]) or None, description or tag.em(_("Sorry, no documentation found"))) for description, names in sorted(get_macro_descr(), key=lambda item: item[1][0]))
def filter_stream(self, req, method, filename, stream, data): if req.path_info.startswith('/browser') and not data.get('tortoise-svn-message'): # add a hidden dialog div for the tortoisve svn message message = tag.p("TortoiseSVN is a Windows explorer client you can use to browse your Subversion repository.", tag.p("If you have not installed TortoiseSVN, you can download it now from the ", tag.a("TortoiseSVN website.", href="http://tortoisesvn.net/downloads.html", target="_blank" ), ), tag.p("If you have installed TortoiseSVN, please select continue.", ), tag.p("If your local network requires a proxy to access the Internet, note that ", tag.a("TortoiseSVN has proxy settings ", href="http://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-dug-settings.html#tsvn-dug-settings-network" ), "which are configured separately to your normal Windows browser proxy.", class_="info-light" ), tag.p("This message will not appear again if you click continue.", class_="info-light" ), ) form = tag.form( tag.div( tag.input( type="hidden", name="__FORM_TOKEN", value=req.form_token ), ), tag.input( name="tortoise-svn-message", value="True", ), id_="tortoise-svn-message-form", class_="hidden" ) stream = stream | Transformer("//*[@id='dirlist']").after(tag.div(message, form, id_='tortoise-svn-message-dialog', class_='hidden' ) ) return stream
def test_find_element_with_tag(self): frag = tag(tag.p('Paragraph with a ', tag.a('link', href='http://www.edgewall.org'), ' and some ', tag.strong('strong text'))) self.assertIsNotNone(find_element(frag, tag='p')) self.assertIsNotNone(find_element(frag, tag='a')) self.assertIsNotNone(find_element(frag, tag='strong')) self.assertIsNone(find_element(frag, tag='input')) self.assertIsNone(find_element(frag, tag='textarea'))
def expand_macro(self, formatter, name, content): if self.ACCESS_KEY is None: return tag.p("[EC2 access key is missing from trac.ini]") if self.SECRET_KEY is None: return tag.p("[EC2 secret key is missing from trac.ini]") ec2 = EC2Connection(self.ACCESS_KEY, self.SECRET_KEY) headings = ("Instance", "AMI", "Key", "IP", "State", "Monitored") table = tag.table(tag.thead(tag.tr([tag.th(title) for title in headings])), class_="listing") tbody = tag.tbody() try: instance_data = ec2.get_all_instances() except UnicodeDecodeError, e: self.log.exception("Failed to ec2.get_all_instances() for AWSInstanceTableMacro") return tag.div("AWSInstanceTable macro failed.")
def expand_macro(self, formatter, name, content): def wikify(text): return format_to_oneliner(self.env, formatter.context, text) return tag.div( tag.p(wikify(_(""" The following tokens can be used in the `PageTemplates/MyPage` or `PageTemplates/MyPage/<user>` wiki pages: """))), tag.dl([(tag.dt(tag.tt(token)), tag.dd(wikify(gettext(description)))) for token, description in sorted(MyPageModule(self.env).tokens.values())]), tag.p(wikify(_(""" Note that you can also use the `[[MyPageNav]]` wiki macro for creating dynamic links to other ''MyPage'' pages (use `[[MyPageNav?]]` to get help on this macro). """))) )
def get_powered_by_sign(): return tag.p("Powered by ", tag.a(tag.strong("IttecoTracPlugin %s" % __version__), href="http://tracplugin.itteco.com/"), tag.br(), tag( "By ", tag.a("Itteco Software", href="http://www.itteco.com"), ), class_="left")
def notify(self, resid, subject): self.subject = subject if not self.config.getbool('notification', 'smtp_enabled'): return self.from_email = self.config['notification'].get('smtp_from') self.from_name = self.config['notification'].get('smtp_from_name') self.replyto_email = self.config['notification'].get('smtp_replyto') self.from_email = self.from_email or self.replyto_email if not self.from_email and not self.replyto_email: raise TracError(tag( tag.p(_('Unable to send email due to identity crisis.')), tag.p(_('Neither %(from_)s nor %(reply_to)s are specified ' 'in the configuration.', from_=tag.b('notification.from'), reply_to=tag.b('notification.reply_to')))), _('SMTP Notification Error')) Notify.notify(self, resid)
def filter_stream(self, req, method, filename, stream, data): if 'modifiedfiles' in data: numconflictingtickets = self.__process_ticket_request(req, True) #Display a warning message if there are conflicting tickets if numconflictingtickets > 0: if numconflictingtickets == 1: text = " There is one ticket in conflict!" else: text = " There are %s tickets in conflict!" % str(numconflictingtickets) stream |= Transformer("//div[@id='changelog']").before(tag.p(tag.strong("Warning:"), text, style='background: #def; border: 2px solid #00d; padding: 3px;')) #Display the link to this ticket's modifiedfiles page stream |= Transformer("//div[@id='changelog']").before( tag.p( 'Have a look at the ', tag.a("list of modified files", href="../modifiedfiles/" + str(data["modifiedfiles"])), ' related to this ticket.' ) ) return stream
class ParseArgsTestMacro(Component): """Test macro for `tracadvparseargs.parse_args` function. This macro is intended to be used by the developers of the above function to simplify the testing process and has no real value for normal Trac users. == Macro usage == {{{ [[ParseArgsTest(parser_options|||arguments_to_parse)]] }}} will call {{{ #!python parse_args(arguments_to_parse, **parser_options) }}} and will display its return value. See below for the list of parser options. == Example == {{{ [[ParseArgsTest(strict=True,delquotes=True|||key1=val1,key2="val2a,val2b")]] }}} will call {{{ parse_args('key1=val1,key2="val2a,val2b"', strict=True, delquotes=True) }}} """ implements ( IWikiMacroProvider ) ### methods for IWikiMacroProvider def expand_macro(self, formatter, name, content): args, rcontent = content.split('|||',2) try: ldummy, pa = parse_args (args) largs, kwargs = parse_args (rcontent, **pa) except EndQuoteError, e: raise TracError( unicode(e) ) return tag.div( tag.p("largs = ", largs.__repr__()), tag.p("kwargs = ", kwargs.__repr__()), class_='advparseargs' )
def format(self, transport, style, event): if transport != 'email': return text = event.target.text if style == 'text/plain': if 'raise-text-plain' in text: raise ValueError() return unicode(text) if style == 'text/html': if 'raise-text-html' in text: raise ValueError() return unicode(tag.p(text))
class CommitTicketReferenceMacro(WikiMacroBase): """This is intended to replace the builtin macro by providing additional code review status info for the changeset. To use, disable the builtin macro as follows: [components] tracopt.ticket.commit_updater.committicketreferencemacro = disabled """ def expand_macro(self, formatter, name, content, args={}): reponame = args.get('repository') or '' rev = args.get('revision') repos = RepositoryManager(self.env).get_repository(reponame) try: changeset = repos.get_changeset(rev) message = changeset.message # add review status to commit message ( review = CodeReview(self.env, reponame, rev) status = review.encode(review.status) message += '\n\n{{{#!html \n' message += '<div class="codereviewstatus">' message += ' <div class="system-message %s">' % status.lower() message += ' <p>Code review status: ' message += ' <span>%s</span>' % review.status message += ' </p>' message += ' </div>' message += '</div>' message += '\n}}}' rev = changeset.rev resource = repos.resource except Exception, e: message = content resource = Resource('repository', reponame) if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any( int(tkt_id) == int(formatter.context.resource.id) for tkt_id in ticket_re.findall(message)): return tag.p( "(The changeset message doesn't reference this " "ticket)", class_='hint') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context('changeset', rev, parent=resource), message, escape_newlines=True), class_='message') else: return tag.pre(message, class_='message')
def notify(self, resid, subject): self.subject = subject if not self.config.getbool('notification', 'smtp_enabled'): return self.from_email = self.config['notification'].get('smtp_from') self.from_name = self.config['notification'].get('smtp_from_name') self.replyto_email = self.config['notification'].get('smtp_replyto') self.from_email = self.from_email or self.replyto_email if not self.from_email and not self.replyto_email: raise TracError( tag( tag.p(_('Unable to send email due to identity crisis.')), tag.p( _( 'Neither %(from_)s nor %(reply_to)s are specified ' 'in the configuration.', from_=tag.b('notification.from'), reply_to=tag.b('notification.reply_to')))), _('SMTP Notification Error')) Notify.notify(self, resid)
def include(self, name, parse=True, raw=False, context="block", data=None): if name in self.storage: text = self.storage.page_text(name) if parse: return self.parser.generate(text, context=context, environ=(self, data)) else: if raw: return Markup(text) else: return tag.pre(text) else: return tag.div(tag.p(u"Page %s Not Found" % name), class_="error")
def expand_macro(self, formatter, name, content): from trac.wiki.formatter import system_message content = content.strip() if content else '' name_filter = content.strip('*') def get_macro_descr(): for macro_provider in formatter.wiki.macro_providers: names = list(macro_provider.get_macros() or []) if name_filter and not any( name.startswith(name_filter) for name in names): continue try: name_descriptions = [ (name, macro_provider.get_macro_description(name)) for name in names ] except Exception as e: yield system_message( _("Error: Can't get description for macro %(name)s", name=names[0]), e), names else: for descr, pairs in groupby(name_descriptions, key=lambda p: p[1]): if descr: if isinstance(descr, (tuple, list)): descr = dgettext(descr[0], to_unicode(descr[1])) \ if descr[1] else '' else: descr = to_unicode(descr) or '' if content == '*': descr = format_to_oneliner(self.env, formatter.context, descr, shorten=True) else: descr = format_to_html(self.env, formatter.context, descr) yield descr, [name for name, descr in pairs] return tag.div(class_='trac-macrolist')( (tag.h3(tag.code('[[', names[0], ']]'), id='%s-macro' % names[0]), len(names) > 1 and tag.p( tag.strong(_("Aliases:")), [tag.code(' [[', alias, ']]') for alias in names[1:]]) or None, description or tag.em(_("Sorry, no documentation found"))) for description, names in sorted(get_macro_descr(), key=lambda item: item[1][0]))
def notify(self, resid, subject): self.subject = subject if not self.config.getbool('notification', 'smtp_enabled'): return self.smtp_server = self.config['notification'].get('smtp_server') self.smtp_port = self.config['notification'].getint('smtp_port') self.from_email = self.config['notification'].get('smtp_from') self.from_name = self.config['notification'].get('smtp_from_name') self.replyto_email = self.config['notification'].get('smtp_replyto') self.from_email = self.from_email or self.replyto_email if not self.from_email and not self.replyto_email: raise TracError(tag(tag.p('Unable to send email due to identity ' 'crisis.'), tag.p('Neither ', tag.b('notification.from'), ' nor ', tag.b('notification.reply_to'), 'are specified in the configuration.')), 'SMTP Notification Error') # Authentication info (optional) self.user_name = self.config['notification'].get('smtp_user') self.password = self.config['notification'].get('smtp_password') Notify.notify(self, resid)
def expand_macro(self, formatter, name, content): largs, kwargs = parse_args(content) largs.append('') wlink = largs[0] raw = True if 'raw' in kwargs and kwargs['raw'].lower() == 'false': raw = False url = extract_url (self.env, formatter.context, wlink, raw) return tag.p( tag.code ("'%s'" % wlink), tag.span (' => '), tag.a ("'%s'" % url, href=url), class_='extracturl', )
def getSortableTableCell( f ): field = t.getfielddef( f, '' ) cssclass,style = self.getcsscolstyle(f, field ) if f == 'id': if t.getfielddef( 'status', '' )=='closed': cssclass ="ticket closed" else: cssclass ="ticket " text = tag.p(tag.a( '#'+str(t.getfielddef( f, '' )), href=t.getfielddef( 'href', '' ), class_ = cssclass ) ) elif f == 'priority' : # special case # two-digit integer representation of priority sorting (as definend in trac admin panel) text = tag.span(str(99-int(t.getfielddef( 'priority_value', '0' ))), class_ = 'invisible')+self.wiki2html(field) elif f in customdatefields : # special case: date string text = tag.span(self.getNormalizedDateStringOfSegment(field), class_='invisible')+self.wiki2html(field) else : text = self.wiki2html(field) return (text,cssclass,style)
def p(macro, environ, data, *args, **kwargs): """Displays text in a HTML <p> This macro allows you to display text in a custom HTML <p> element and contrib various attributes such as style, class, id, etc. **Arguments:** * id=None (//the id attribute//) * class=None (//the class attribute//) * style=None (//the style attribute//) **Example(s):** {{{ <<p "Hello World!">> }}} <<p "Hello World!">> """ text = macro.body or (args and args[0]) or None if not text: return None id = kwargs.get("id", None) cls = str(kwargs.get("class", None)) style = kwargs.get("style", None) if style: style = ";".join(sanitizer.sanitize_css(style)) contents = environ.parser.generate(text, context="inline", environ=(environ, data)) attrs = {} if id: attrs["id"] = id if cls: attrs["class_"] = cls if style: attrs["style"] = style return tag.p(contents, **attrs)
def require_secret(macro, environ, *secrets): """Macro for hiding text that can be shown by submitting a secret. You can provide several secrets as arguments. If ANY of the secret was submitted by the user, the content is shown. Requires the following keys in the environ: ``submitted_secrets`` A set of secrets for this scenario which were submitted by the user. """ show_content = any(x in environ['submitted_secrets'] for x in secrets) if show_content: return macro.parsed_body() else: dragons = tag.strong(_('Here be dragons.')) text = _('This content is hidden, ' 'you need to submit a specific secret in order to show it.') return tag.div(tag.p(dragons, ' ', text), class_='require_secret')
def expand_macro(self, formatter, name, content): evs = EarnValueSystem(self.env) kwargs = self._parse_arg(content) users = evs.get_users(formatter.req, kwargs.get('users', 'authenticated')) format = kwargs.get('format', 'table') start_time = self._parse_date(kwargs.get('start'), 0) end_time = self._parse_date(kwargs.get('end'), None) if format == 'plain': ev = dict([(u, evs.get_user_ev(u, start_time, end_time)) for u in users]) tags = [] for k, v in ev.items(): tags.append(tag.span(k + ': ' + str(v))) tags.append(tag.br) return tag.p(*tags) elif format == 'table': evc = evs.get_users_ev_detail(users, start_time, end_time) rows = [tag.tr( tag.td(ev['action_name']), tag.td(ev['value']), tag.td(ev['fullname']), tag.td(ev['time']), tag.td(ev['summary']) ) for evcs in evc.values() for ev in evcs ] return tag.div( tag.table(tag.thead( tag.tr( tag.th('Action'), tag.th('Value'), tag.th('User'), tag.th('Date'), tag.th('Summary'), class_='trac-columns') ), tag.tbody( *rows ), class_='listing tickets') ) return None
def getSortableTableCell(f): field = t.getfielddef(f, '') cssclass, style = self.getcsscolstyle(f, field) if f == 'id': if t.getfielddef('status', '') == 'closed': cssclass = "ticket closed" else: cssclass = "ticket " #text = tag.p(tag.a( '#'+str(t.getfielddef( f, '' )), href=t.getfielddef( 'href', '' ), class_ = cssclass ) ) text = tag.p(self.createTicketLink( t, False)) # no markup using colors and images here elif f == 'priority': # special case # two-digit integer representation of priority sorting (as definend in trac admin panel) text = tag.span( str(99 - int(t.getfielddef('priority_value', '0'))), class_='invisible') + self.wiki2html(field) elif f in customdatefields: # special case: date string text = tag.span(self.getNormalizedDateStringOfSegment(field), class_='invisible') + self.wiki2html(field) else: text = self.wiki2html(field) return (text, cssclass, style)
def _customize_View(self, stream): filter = Transformer('.//div [@id="banner"]') stream = stream | filter.wrap(self.css_banner_top2) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="banner"]').copy(buffer) \ .end().select('.//div [@id="top2"]') \ .after(tag.div(id_='top1')(buffer)) filter = Transformer('.//div [@id="mainnav"]') stream = stream | filter.wrap(self.css_banner_top4) buffer = StreamBuffer() stream = stream | Transformer('.//div [@id="mainnav"]').copy(buffer) \ .end().select('.//div [@id="top4"]') \ .after(tag.div(id_='top3')(buffer)) filter = Transformer('.//div [@id="top3"]') stream = stream | filter.after(tag.div(id_='right')(tag.p())) filter = Transformer('.//div [@id="right"]') stream = stream | filter. \ append(tag.div(class_='wiki-toc')(tag.h4(_('Table of Contents')))) # just for the menu / TOC filter = Transformer('.//div [@class="wiki-toc"]') if self.anchors and self.keylist: for key in self.keylist: stream = stream | filter.append( tag.a(key, href='#' + self.anchors.get(key), onclick="scrollup();") + tag.br()) filter = Transformer('.//div [@id="main"]') stream = stream | filter.wrap(self.css_left) return stream
def expand_macro(self, formatter, name, args): """Returns an image that will be displayed in the Wiki content. `name` is the actual name of the macro, `args` is the text enclosed in parenthesis at the call of the macro. """ params = {} args_list, args_dict = parse_args(args) img_url = args_list[0] params['height'] = args_dict.get('height', '') params['width'] = args_dict.get('width', '') params['align'] = args_dict.get('align', 'left') image = tag.image(src=img_url, width=params['width'], eight=params['height'], align=params['align']) link = tag.a(image, href=img_url) return tag.p(link, style="text-align:%s;" % params['align'])
def expand_macro(self, formatter, name, content, args={}): if args: reponame = args.get('repository', '') rev = args.get('revision') else: if ',' in content: reponame = '' rev = 0 for c in [x.strip() for x in content.split(',')]: if c.isnumeric(): rev = c else: reponame = c else: rev = content.strip() reponame = '' repos = RepositoryManager(self.env).get_repository(reponame) if repos: changeset = repos.get_changeset(rev) message = changeset.message rev = changeset.rev else: message = content if formatter.context.resource.realm == 'ticket': ticket_re = CommitTicketUpdater.ticket_re if not any(int(tkt_id) == formatter.context.resource.id for tkt_id in ticket_re.findall(message)): return tag.div(tag.p(_("(The changeset message doesn't " "reference this ticket)"), class_='hint'), class_='commitmessage') if ChangesetModule(self.env).wiki_format_messages: return tag.div(format_to_html(self.env, formatter.context('changeset', rev, parent=repos.resource), message, escape_newlines=True), class_='commitmessage') else: return tag.pre(message, class_='commitmessage')
def test_translation_function_tag(self): from customfieldadmin.api import tag_ from genshi.builder import tag self.assertEquals('<p>foo bar</p>', str(tag_(tag.p('foo bar')))) self.assertEquals('<p>foo bar</p>', str(tag_(tag.p('foo %(bar)s' % {'bar': 'bar'}))))
def test_element(self): rv = to_fragment(tag.p('blah')) self.assertEqual(Element, type(rv)) self.assertEqual('<p>blah</p>', unicode(rv))