Exemple #1
0
    def __get__(self, instance, owner):
        if instance is None:
            return self
        order = ListOption.__get__(self, instance, owner)
        components = []
        implementing_classes = []
        for impl in self.xtnpt.extensions(instance):
            implementing_classes.append(impl.__class__.__name__)
            if self.include_missing or impl.__class__.__name__ in order:
                components.append(impl)
        not_found = sorted(set(order) - set(implementing_classes))
        if not_found:
            raise ConfigurationError(
                tag_("Cannot find implementation(s) of the %(interface)s "
                     "interface named %(implementation)s. Please check "
                     "that the Component is enabled or update the option "
                     "%(option)s in trac.ini.",
                     interface=tag.code(self.xtnpt.interface.__name__),
                     implementation=tag(
                         (', ' if idx != 0 else None, tag.code(impl))
                         for idx, impl in enumerate(not_found)),
                     option=tag.code("[%s] %s" % (self.section, self.name))))

        def compare(x, y):
            x, y = x.__class__.__name__, y.__class__.__name__
            if x not in order:
                return int(y in order)
            if y not in order:
                return -int(x in order)
            return cmp(order.index(x), order.index(y))
        components.sort(compare)
        return components
Exemple #2
0
    def expand_macro(self, formatter, name, content):
        from trac.mimeview.api import Mimeview
        mime_map = Mimeview(self.env).mime_map
        mime_type_filter = ''
        args, kw = parse_args(content)
        if args:
            mime_type_filter = args.pop(0).strip().rstrip('*')

        mime_types = {}
        for key, mime_type in mime_map.iteritems():
            if (not mime_type_filter or
                mime_type.startswith(mime_type_filter)) and key != mime_type:
                mime_types.setdefault(mime_type, []).append(key)

        return tag.div(class_='mimetypes')(
            tag.table(class_='wiki')(
                tag.thead(tag.tr(
                    tag.th(_("MIME Types")),  # always use plural
                    tag.th(tag.a("WikiProcessors",
                                 href=formatter.context.href.wiki(
                                     'WikiProcessors'))))),
                tag.tbody(
                    tag.tr(tag.th(tag.code(mime_type),
                                  style="text-align: left"),
                           tag.td(tag.code(
                               ' '.join(sorted(mime_types[mime_type])))))
                    for mime_type in sorted(mime_types.keys()))))
Exemple #3
0
    def send(self, from_addr, recipients, message):
        # Ensure the message complies with RFC2822: use CRLF line endings
        message = fix_eol(message, CRLF)

        self.log.info("Sending notification through SMTP at %s:%d to %s",
                      self.smtp_server, self.smtp_port, recipients)
        try:
            server = smtplib.SMTP(self.smtp_server, self.smtp_port)
        except smtplib.socket.error as e:
            raise ConfigurationError(
                tag_("SMTP server connection error (%(error)s). Please "
                     "modify %(option1)s or %(option2)s in your "
                     "configuration.",
                     error=to_unicode(e),
                     option1=tag.code("[notification] smtp_server"),
                     option2=tag.code("[notification] smtp_port")))
        # server.set_debuglevel(True)
        if self.use_tls:
            server.ehlo()
            if 'starttls' not in server.esmtp_features:
                raise TracError(_("TLS enabled but server does not support"
                                  " TLS"))
            server.starttls()
            server.ehlo()
        if self.smtp_user:
            server.login(self.smtp_user.encode('utf-8'),
                         self.smtp_password.encode('utf-8'))
        start = time.time()
        resp = sendmail(server, from_addr, recipients, message)
        t = time.time() - start
        if t > 5:
            self.log.warning("Slow mail submission (%.2f s), "
                             "check your mail setup", t)
        if self.use_tls:
            # avoid false failure detection when the server closes
            # the SMTP connection with TLS enabled
            import socket
            try:
                server.quit()
            except socket.sslerror:
                pass
        else:
            server.quit()

        msg = email.message_from_string(message)
        ticket_id = int(msg['x-trac-ticket-id'])
        msgid = msg['message-id']
        aws_re = r'^email-smtp\.([a-z0-9-]+)\.amazonaws\.com$'
        m = re.match(aws_re, self.smtp_server)
        if m:
            parts = resp.split()
            if len(parts) == 2 and parts[0] == 'Ok':
                region = m.group(1)
                msgid = '<%s@%s.amazonses.com>' % (parts[1], region)
        with self.env.db_transaction as db:
            cursor = db.cursor()
            cursor.execute("""
                INSERT OR IGNORE INTO messageid (ticket,messageid)
                VALUES (%s, %s)
                """, (ticket_id, msgid))
Exemple #4
0
    def __get__(self, instance, owner):
        if instance is None:
            return self
        order = ListOption.__get__(self, instance, owner)
        components = []
        implementing_classes = []
        for impl in self.xtnpt.extensions(instance):
            implementing_classes.append(impl.__class__.__name__)
            if self.include_missing or impl.__class__.__name__ in order:
                components.append(impl)
        not_found = sorted(set(order) - set(implementing_classes))
        if not_found:
            raise ConfigurationError(
                tag_(
                    "Cannot find implementation(s) of the %(interface)s "
                    "interface named %(implementation)s. Please check "
                    "that the Component is enabled or update the option "
                    "%(option)s in trac.ini.",
                    interface=tag.code(self.xtnpt.interface.__name__),
                    implementation=tag(
                        (', ' if idx != 0 else None, tag.code(impl))
                        for idx, impl in enumerate(not_found)),
                    option=tag.code("[%s] %s" % (self.section, self.name))))

        def compare(x, y):
            x, y = x.__class__.__name__, y.__class__.__name__
            if x not in order:
                return int(y in order)
            if y not in order:
                return -int(x in order)
            return cmp(order.index(x), order.index(y))

        components.sort(compare)
        return components
Exemple #5
0
def _arg_as_int(val, key=None, min=None, max=None):
    int_val = as_int(val, None, min=min, max=max)
    if int_val is None:
        raise MacroError(tag_("Invalid macro argument %(expr)s",
                              expr=tag.code("%s=%s" % (key, val))
                                   if key else tag.code(val)))
    return int_val
 def serializeNode(self, node, indent):
     rv = tag(" "*indent+"|")
     if node.type == simpletree.TextNode.type:
         text = node.value.split("\n")
         rv.append(tag(tag.code("#text: ", class_=tagClasses["text_marker"]),
                   tag.code(text[0], class_=tagClasses["text"])))
         for line in text[1:]:
             rv.append(tag(tag("\n" + " "*indent+"|"),
                           tag.code(line, class_=tagClasses["text"])))
     elif node.type == simpletree.Element.type:
         rv.append(tag.code(node.name, class_=tagClasses["element"]))
         if node.attributes:
             for key, value in node.attributes.iteritems():
                 rv.append(tag(" ", tag.code(key,
                                             class_=tagClasses["attr_name"]),
                           "=", tag.code("\""+value+"\"",
                                         class_=tagClasses["attr_value"])))
     elif node.type == simpletree.CommentNode.type:
         rv.append(tag(tag.code("#comment: ", class_=tagClasses["comment_marker"]),
                   tag.code(node.data, class_=tagClasses["comment"])))
     elif node.type == simpletree.DocumentType.type:
         rv.append(tag(tag.code("DOCTYPE: ", class_=tagClasses["doctype_marker"]),
                       tag.code(node.name, class_=tagClasses["doctype"])))
     rv.append(tag("\n"))
     return rv
Exemple #7
0
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]))
Exemple #8
0
    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]))
Exemple #9
0
    def expand_macro(self, formatter, name, content):
        """Render widget contents by re-using wiki markup implementation
        """
        if self.env[DashboardModule] is None:
            return DashboardModule(self.env).alert_disabled()
        largs, kwargs = parse_args(content, strict=True)
        try:
            (widget_name, ) = largs
        except ValueError:
            template = 'widget_alert.html'
            data = {
                    'msgtype' : 'error',
                    'msglabel' : 'Error',
                    'msgbody' : tag('Expected ', tag.code(1),
                            ' positional argument (i.e. widget name), but got ',
                            tag.code(len(largs)), ' instead'),
                    'msgdetails' : [
                            ('Macro name', tag.code('WidgetMacro')),
                            ('Arguments', ', '.join(largs) if largs \
                                    else tag.span('None', class_='label')),
                        ],
                }
        else:
            widget_name = widget_name.strip()
            wopts = {}
            wargs = {}

            def parse_literal(value):
                try:
                    return literal_eval(value)
                except (SyntaxError, ValueError):
                    return value

            for argnm, value in kwargs.iteritems():
                if argnm.startswith('wo_'):
                    wopts[argnm[3:]] = value
                else:
                    wargs[argnm] = parse_literal(value)
            template = 'widget.html'
            data = {
                'args': wargs,
                'bhdb': DashboardChrome(self.env),
                'id': None,
                'opts': wopts,
                'widget': widget_name
            }
        return Chrome(self.env).render_template(formatter.req,
                                                template,
                                                data,
                                                fragment=True)
Exemple #10
0
    def expand_macro(self, formatter, name, content):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(content)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is not None and default != '':
                return tag.td(tag.code(option.dumps(default)),
                              class_='default')
            else:
                return tag.td(_("(no default)"), class_='nodefault')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.code(option.name)),
                        tag.td(
                            format_to_oneliner(self.env, formatter.context,
                                               getdoc(option))),
                        default_cell(option),
                        class_='odd' if idx % 2 else 'even')
                 for idx, option in enumerate(
                     sorted(options.get(section, {}).itervalues(),
                            key=lambda o: o.name))
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Exemple #11
0
    def send(self, from_addr, recipients, message):
        global local_hostname
        # Ensure the message complies with RFC2822: use CRLF line endings
        message = fix_eol(message, CRLF)

        self.log.info("Sending notification through SMTP at %s:%d to %s",
                      self.smtp_server, self.smtp_port, recipients)
        try:
            server = smtplib.SMTP(self.smtp_server, self.smtp_port,
                                  local_hostname)
            local_hostname = server.local_hostname
        except smtplib.socket.error as e:
            raise ConfigurationError(
                tag_(
                    "SMTP server connection error (%(error)s). Please "
                    "modify %(option1)s or %(option2)s in your "
                    "configuration.",
                    error=to_unicode(e),
                    option1=tag.code("[notification] smtp_server"),
                    option2=tag.code("[notification] smtp_port")))
        # server.set_debuglevel(True)
        if self.use_tls:
            server.ehlo()
            if 'starttls' not in server.esmtp_features:
                raise TracError(
                    _("TLS enabled but server does not support"
                      " TLS"))
            server.starttls()
            server.ehlo()
        if self.smtp_user:
            server.login(self.smtp_user.encode('utf-8'),
                         self.smtp_password.encode('utf-8'))
        start = time_now()
        server.sendmail(from_addr, recipients, message)
        t = time_now() - start
        if t > 5:
            self.log.warning(
                "Slow mail submission (%.2f s), "
                "check your mail setup", t)
        if self.use_tls:
            # avoid false failure detection when the server closes
            # the SMTP connection with TLS enabled
            import socket
            try:
                server.quit()
            except socket.sslerror:
                pass
        else:
            server.quit()
Exemple #12
0
 def __get__(self, instance, owner):
     if instance is None:
         return self
     value = Option.__get__(self, instance, owner)
     for impl in self.xtnpt.extensions(instance):
         if impl.__class__.__name__ == value:
             return impl
     raise ConfigurationError(
         tag_("Cannot find an implementation of the %(interface)s "
              "interface named %(implementation)s. Please check "
              "that the Component is enabled or update the option "
              "%(option)s in trac.ini.",
              interface=tag.code(self.xtnpt.interface.__name__),
              implementation=tag.code(value),
              option=tag.code("[%s] %s" % (self.section, self.name))))
Exemple #13
0
 def __get__(self, instance, owner):
     if instance is None:
         return self
     value = Option.__get__(self, instance, owner)
     for impl in self.xtnpt.extensions(instance):
         if impl.__class__.__name__ == value:
             return impl
     raise ConfigurationError(
         tag_("Cannot find an implementation of the %(interface)s "
              "interface named %(implementation)s. Please check "
              "that the Component is enabled or update the option "
              "%(option)s in trac.ini.",
              interface=tag.code(self.xtnpt.interface.__name__),
              implementation=tag.code(value),
              option=tag.code("[%s] %s" % (self.section, self.name))))
Exemple #14
0
 def _render_widget(self, wp, name, ctx, options):
     """Render widget without failing.
     """
     try :
         if wp is None :
             raise InvalidIdentifier("Unknown widget ID")
         return wp.render_widget(name, ctx, options)
     except Exception, exc:
         log_entry = str(uuid4())
         exccls = exc.__class__
         self.log.exception("- %s - Error rendering widget %s with options %s",
                 log_entry, name, options)
         data = {
                 'msgtype' : 'error',
                 'msglabel' : 'Error',
                 'msgbody' : _('Exception raised while rendering widget. '
                     'Contact your administrator for further details.'),
                 'msgdetails' : [
                         ('Widget name', name),
                         ('Exception type', tag.code(exccls.__name__)),
                         ('Log entry ID', log_entry),
                     ],
             }
         return 'widget_alert.html', \
                 { 'title' : _('Widget error'), 'data' : data}, \
                 ctx
Exemple #15
0
    def send(self, from_addr, recipients, message):
        # Use native line endings in message
        message = fix_eol(message, os.linesep)

        self.log.info("Sending notification through sendmail at %s to %s",
                      self.sendmail_path, recipients)
        cmdline = [self.sendmail_path, '-i', '-f', from_addr] + recipients
        self.log.debug("Sendmail command line: %s", cmdline)
        try:
            child = Popen(cmdline,
                          bufsize=-1,
                          stdin=PIPE,
                          stdout=PIPE,
                          stderr=PIPE,
                          close_fds=close_fds)
        except OSError as e:
            raise ConfigurationError(
                tag_(
                    "Sendmail error (%(error)s). Please modify %(option)s "
                    "in your configuration.",
                    error=to_unicode(e),
                    option=tag.code("[notification] sendmail_path")))
        out, err = child.communicate(message)
        if child.returncode or err:
            raise Exception("Sendmail failed with (%s, %s), command: '%s'" %
                            (child.returncode, err.strip(), cmdline))
Exemple #16
0
 def _prepare_doc_metadata(self, spec):
     """Transform widget metadata into a format suitable to render
     documentation.
     """
     return {
             'id' : "%s-widget" % (spec['urn'],),
             'title' : tag.code(spec['urn']),
             'desc' : '\n'.join(l.strip() 
                                for l in spec['desc'].splitlines()),
             'sections' : [
                     {
                         'title' : _('Parameters'),
                         'entries' : [
                                 {
                                     'caption' : pnm,
                                     'summary' : '\n'.join(
                                             l.strip() for l in \
                                             p.get('desc').splitlines()),
                                     'details' : [
                                             ('Type', p.get('type', str)),
                                             ('Required', p.get('required',
                                                                False)),
                                             ('Default', p.get('default')),
                                         ]
                                 }
                             for pnm, p in spec['params'].iteritems()]
                     }
                 ]
         }
Exemple #17
0
def _invalid_db_str(db_str):
    return ConfigurationError(
        tag_(
            "Invalid format %(db_str)s for the database connection string. "
            "Please refer to the %(doc)s for help.",
            db_str=tag.code(db_str),
            doc=_doc_db_str()))
Exemple #18
0
    def expand_macro(self, formatter, name, content):
        from trac.mimeview.api import Mimeview
        mime_map = Mimeview(self.env).mime_map
        mime_type_filter = ''
        args, kw = parse_args(content)
        if args:
            mime_type_filter = args.pop(0).strip().rstrip('*')

        mime_types = {}
        for key, mime_type in mime_map.iteritems():
            if (not mime_type_filter or
                mime_type.startswith(mime_type_filter)) and key != mime_type:
                mime_types.setdefault(mime_type, []).append(key)

        return tag.div(class_='mimetypes')(
            tag.table(class_='wiki')(
                tag.thead(tag.tr(
                    tag.th(_("MIME Types")),  # always use plural
                    tag.th(tag.a("WikiProcessors",
                                 href=formatter.context.href.wiki(
                                     'WikiProcessors'))))),
                tag.tbody(
                    tag.tr(tag.th(tag.tt(mime_type),
                                  style="text-align: left"),
                           tag.td(tag.code(
                               ' '.join(sorted(mime_types[mime_type])))))
                    for mime_type in sorted(mime_types.keys()))))
Exemple #19
0
 def default_cell(option):
     default = option.default
     if default is not None and default != '':
         return tag.td(tag.code(option.dumps(default)),
                       class_='default')
     else:
         return tag.td(_("(no default)"), class_='nodefault')
Exemple #20
0
    def process_request(self, req):
        parent_id = None
        parent_realm = req.args.get('realm')
        path = req.args.get('path')
        filename = None

        if not parent_realm or not path:
            raise HTTPBadRequest(_('Bad request'))
        if parent_realm == 'attachment':
            raise TracError(tag_("%(realm)s is not a valid parent realm",
                                 realm=tag.code(parent_realm)))

        parent_realm = Resource(parent_realm)
        action = req.args.get('action', 'view')
        if action == 'new':
            parent_id = path.rstrip('/')
        else:
            last_slash = path.rfind('/')
            if last_slash == -1:
                parent_id, filename = path, ''
            else:
                parent_id, filename = path[:last_slash], path[last_slash + 1:]

        parent = parent_realm(id=parent_id)
        if not resource_exists(self.env, parent):
            raise ResourceNotFound(
                _("Parent resource %(parent)s doesn't exist",
                  parent=get_resource_name(self.env, parent)))

        # Link the attachment page to parent resource
        parent_name = get_resource_name(self.env, parent)
        parent_url = get_resource_url(self.env, parent, req.href)
        add_link(req, 'up', parent_url, parent_name)
        add_ctxtnav(req, _('Back to %(parent)s', parent=parent_name),
                    parent_url)

        if not filename: # there's a trailing '/'
            if req.args.get('format') == 'zip':
                self._download_as_zip(req, parent)
            elif action != 'new':
                return self._render_list(req, parent)

        attachment = Attachment(self.env, parent.child(self.realm, filename))

        if req.method == 'POST':
            if action == 'new':
                data = self._do_save(req, attachment)
            elif action == 'delete':
                self._do_delete(req, attachment)
            else:
                raise HTTPBadRequest(_("Invalid request arguments."))
        elif action == 'delete':
            data = self._render_confirm_delete(req, attachment)
        elif action == 'new':
            data = self._render_form(req, attachment)
        else:
            data = self._render_view(req, attachment)

        add_stylesheet(req, 'common/css/code.css')
        return 'attachment.html', data, None
Exemple #21
0
    def expand_macro(self, formatter, name, args):
        from trac.config import Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = Option.get_registry(self.compmgr)
        sections = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                sections.setdefault(section, {})[key] = option

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             tag.table(class_='wiki')(
                 tag.tbody(tag.tr(tag.td(tag.tt(option.name)),
                                  tag.td(format_to_oneliner(
                                      self.env, formatter.context,
                                      to_unicode(option.__doc__))))
                           for option in sorted(sections[section].itervalues(),
                                                key=lambda o: o.name)
                           if option.name.startswith(key_filter))))
            for section in sorted(sections))
Exemple #22
0
 def short_value(self):
     if self.is_scalar:
         if isinstance(self.value, basestring):
             value = self.value
             if not isinstance(self.value, unicode):
                 value = unicode(self.value, 'utf-8', 'replace')
             return tag.q(shorten_line(value, 60)).generate()
         else:
             return shorten_line(repr(self.value), 60)
     elif self.is_collection:
         if isinstance(self.value, (dict, DictMixin)):
             return u'{…}'
         elif isinstance(self.value, list):
             return u'[…]'
         elif isinstance(self.value, tuple):
             return u'(…)'
         elif isinstance(self.value, set):
             return u'set([…])'
         elif isinstance(self.value, frozenset):
             return u'frozenset([…])'
     else:
         try:
             return tag.code(shorten_line(str(self.value), 60))
         except:
             return '?'
Exemple #23
0
 def default_cell(option):
     default = option.default
     if default is not None and default != '':
         return tag.td(tag.code(option.dumps(default)),
                       class_='default')
     else:
         return tag.td(_("(no default)"), class_='nodefault')
Exemple #24
0
    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.code(ep.__class__.__name__),
                       kinds=', '.join('"%s"' % ep_kinds[f] for f in
                                       current_filters & ep_filters)),
                  tag.strong(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))))
Exemple #25
0
    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.code(ep.__class__.__name__),
                       kinds=', '.join('"%s"' % ep_kinds[f] for f in
                                       current_filters & ep_filters)),
                  tag.strong(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))))
Exemple #26
0
    def _render_widget(self, wp, name, ctx, options):
        """Render widget without failing.
        """
        if wp is None:
            data = {'msglabel': _('Warning'),
                    'msgbody': _('Unknown widget %(name)s', name=name)}
            return 'widget_alert.html', {'title': '', 'data': data}, ctx

        try:
            return wp.render_widget(name, ctx, options)
        except Exception, exc:
            log_entry = str(uuid4())
            exccls = exc.__class__
            self.log.exception(
                "- %s - Error rendering widget %s with options %s",
                log_entry, name, options)
            data = {
                'msgtype': 'error',
                'msglabel': 'Error',
                'msgbody': _('Exception raised while rendering widget. '
                             'Contact your administrator for further details.'),
                'msgdetails': [
                    ('Widget name', name),
                    ('Exception type', tag.code(exccls.__name__)),
                    ('Log entry ID', log_entry),
                ],
            }
            return 'widget_alert.html', {
                'title': _('Widget error'),
                'data': data
            }, ctx
Exemple #27
0
    def expand_macro(self, formatter, name, content):
        """Render widget contents by re-using wiki markup implementation
        """
        if self.env[DashboardModule] is None:
            return DashboardModule(self.env).alert_disabled()
        largs, kwargs = parse_args(content, strict=True)
        try:
            (widget_name ,) = largs
        except ValueError:
            template = 'widget_alert.html'
            data = {
                    'msgtype' : 'error',
                    'msglabel' : 'Error',
                    'msgbody' : tag('Expected ', tag.code(1),
                            ' positional argument (i.e. widget name), but got ',
                            tag.code(len(largs)), ' instead'),
                    'msgdetails' : [
                            ('Macro name', tag.code('WidgetMacro')),
                            ('Arguments', ', '.join(largs) if largs \
                                    else tag.span('None', class_='label')),
                        ],
                }
        else:
            widget_name = widget_name.strip()
            wopts = {} ; wargs = {}

            def parse_literal(value):
                try:
                    return literal_eval(value)
                except (SyntaxError, ValueError):
                    return value

            for argnm, value in kwargs.iteritems():
                if argnm.startswith('wo_'):
                    wopts[argnm[3:]] = value
                else :
                    wargs[argnm] = parse_literal(value)
            template = 'widget.html'
            data = {
                    'args' : wargs,
                    'bhdb' : DashboardChrome(self.env),
                    'id' : None,
                    'opts' : wopts,
                    'widget' : widget_name
                }
        return Chrome(self.env).render_template(
                formatter.req, template, data, fragment=True)
 def serializeNode(self, node, indent):
     if node.type == simpletree.TextNode.type:
         if (node.parent.name not in html5lib.constants.rcdataElements
             and node.parent.name != "plaintext"):
             value = cgi.escape(node.value, True)
         else:
             value = node.value
         if node.parent.name in ("pre", "textarea"):
             value = "\n" + value
         rv = tag.code(value, class_="text")
     elif node.type == simpletree.Element.type:
         rv = tag("")
         rv.append(tag.code("<" + node.name, class_=tagClasses["element"]))
         if node.attributes:
             for key, value in node.attributes.iteritems():
                 value = cgi.escape(value, True)
                 rv.append(tag(" ", tag.code(key,
                                             class_=tagClasses["attr_name"]),
                           "=", tag.code("\""+value+"\"",
                                         class_=tagClasses["attr_value"])))
         rv.append(tag.code(">", class_=tagClasses["element"]))    
     elif node.type == simpletree.CommentNode.type:
         rv = tag.code("<!--"+node.data+"-->", class_=tagClasses["comment"])
     elif node.type == simpletree.DocumentType.type:
         rv = tag.code("<!DOCTYPE " + node.name + ">", class_=tagClasses["doctype"])
     return rv
Exemple #29
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is True:
                default = 'true'
            elif default is False:
                default = 'false'
            elif default == 0:
                default = '0.0' if isinstance(default, float) else '0'
            elif default:
                default = ', '.join(to_unicode(val) for val in default) \
                          if isinstance(default, (list, tuple)) \
                          else to_unicode(default)
            else:
                return tag.td(_("(no default)"), class_='nodefault')
            return tag.td(tag.code(default), class_='default')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(
                     tag.td(tag.tt(option.name)),
                     tag.td(
                         format_to_oneliner(self.env, formatter.context,
                                            getdoc(option))),
                     default_cell(option))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
    def __init__(self, path, log=None, params={}):
        self.cnx = None
        if path != ':memory:':
            if not os.access(path, os.F_OK):
                raise ConfigurationError(
                    _('Database "%(path)s" not found.', path=path))

            dbdir = os.path.dirname(path)
            if not os.access(path, os.R_OK + os.W_OK) or \
                    not os.access(dbdir, os.R_OK + os.W_OK):
                raise ConfigurationError(
                    tag_(
                        "The user %(user)s requires read _and_ write permissions "
                        "to the database file %(path)s and the directory it is "
                        "located in.",
                        user=tag.code(getuser()),
                        path=tag.code(path)))

        self._active_cursors = weakref.WeakKeyDictionary()
        timeout = int(params.get('timeout', 10.0))
        self._eager = params.get('cursor', 'eager') == 'eager'
        # eager is default, can be turned off by specifying ?cursor=
        if isinstance(path, unicode):  # needed with 2.4.0
            path = path.encode('utf-8')
        cnx = sqlite.connect(path,
                             detect_types=sqlite.PARSE_DECLTYPES,
                             isolation_level=None,
                             check_same_thread=sqlite_version < (3, 3, 1),
                             timeout=timeout)
        # load extensions
        extensions = params.get('extensions', [])
        if len(extensions) > 0:
            cnx.enable_load_extension(True)
            for ext in extensions:
                cnx.load_extension(ext)
            cnx.enable_load_extension(False)

        cursor = cnx.cursor()
        _set_journal_mode(cursor, params.get('journal_mode'))
        _set_synchronous(cursor, params.get('synchronous'))
        cursor.close()
        cnx.isolation_level = 'DEFERRED'
        ConnectionWrapper.__init__(self, cnx, log)
Exemple #31
0
    def send(self, from_addr, recipients, message):
        # Ensure the message complies with RFC2822: use CRLF line endings
        message = fix_eol(message, CRLF)

        self.log.info("Sending notification through SMTP at %s:%d to %s",
                      self.smtp_server, self.smtp_port, recipients)
        try:
            server = smtplib.SMTP(self.smtp_server, self.smtp_port)
        except smtplib.socket.error as e:
            raise ConfigurationError(
                tag_("SMTP server connection error (%(error)s). Please "
                     "modify %(option1)s or %(option2)s in your "
                     "configuration.",
                     error=to_unicode(e),
                     option1=tag.code("[notification] smtp_server"),
                     option2=tag.code("[notification] smtp_port")))
        # server.set_debuglevel(True)
        if self.use_tls:
            server.ehlo()
            if 'starttls' not in server.esmtp_features:
                raise TracError(_("TLS enabled but server does not support"
                                  " TLS"))
            server.starttls()
            server.ehlo()
        if self.smtp_user:
            server.login(self.smtp_user.encode('utf-8'),
                         self.smtp_password.encode('utf-8'))
        start = time.time()
        server.sendmail(from_addr, recipients, message)
        t = time.time() - start
        if t > 5:
            self.log.warning("Slow mail submission (%.2f s), "
                             "check your mail setup", t)
        if self.use_tls:
            # avoid false failure detection when the server closes
            # the SMTP connection with TLS enabled
            import socket
            try:
                server.quit()
            except socket.sslerror:
                pass
        else:
            server.quit()
Exemple #32
0
 def depart_literal_block(self, node):
     del self.preserve_space
     if 'code' in node['classes']:
         code = node['classes'].index('code')
         node['classes'].pop(code)
         code = tag.code(class_=' '.join(node['classes']))
         self.context.commit_elem(code, indent=False)
         del node['classes']
     self.default_departure(node)
     return
Exemple #33
0
 def depart_literal_block(self, node):
     del self.preserve_space
     if 'code' in node['classes']:
         code = node['classes'].index('code')
         node['classes'].pop(code)
         code = tag.code(class_=' '.join(node['classes']))
         self.context.commit_elem(code, indent=False)
         del node['classes']
     self.default_departure(node)
     return
Exemple #34
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is True:
                default = 'true'
            elif default is False:
                default = 'false'
            elif default == 0:
                default = '0.0' if isinstance(default, float) else '0'
            elif default:
                default = ', '.join(to_unicode(val) for val in default) \
                          if isinstance(default, (list, tuple)) \
                          else to_unicode(default)
            else:
                return tag.td(_("(no default)"), class_='nodefault')
            return tag.td(tag.code(default), class_='default')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context, getdoc(option))),
                        default_cell(option))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Exemple #35
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict(
            (name, dgettext(section.doc_domain, to_unicode(section.__doc__)))
            for name, section in registry.iteritems()
            if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(
                     tag.td(tag.tt(option.name)),
                     tag.td(
                         format_to_oneliner(
                             self.env, formatter.context,
                             dgettext(option.doc_domain,
                                      to_unicode(option.__doc__)))),
                     tag.td(
                         tag.code(option.default or 'false') if option.default
                         or option.default is False else _("(no default)"),
                         class_='default' if option.default
                         or option.default is False else 'nodefault'))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Exemple #36
0
    def _get_valid_default_handler(self, req):
        # Use default_handler from the Session if it is a valid value.
        name = req.session.get('default_handler')
        handler = self._request_handlers.get(name)
        if handler and not is_valid_default_handler(handler):
            handler = None

        if not handler:
            # Use default_handler from project configuration.
            handler = self.default_handler
            if not is_valid_default_handler(handler):
                raise ConfigurationError(
                    tag_("%(handler)s is not a valid default handler. Please "
                         "update %(option)s through the %(page)s page or by "
                         "directly editing trac.ini.",
                         handler=tag.code(handler.__class__.__name__),
                         option=tag.code("[trac] default_handler"),
                         page=tag.a(_("Basic Settings"),
                                    href=req.href.admin('general/basics'))))
        return handler
Exemple #37
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, dgettext(section.doc_domain,
                                        to_unicode(section.__doc__)))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context,
                            dgettext(option.doc_domain,
                                     to_unicode(option.__doc__)))),
                        tag.td(tag.code(option.default or 'false')
                                   if option.default or option.default is False
                                   else _("(no default)"),
                               class_='default' if option.default or 
                                                   option.default is False 
                                                else 'nodefault'))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Exemple #38
0
    def _get_valid_default_handler(self, req):
        # Use default_handler from the Session if it is a valid value.
        name = req.session.get('default_handler')
        handler = self._request_handlers.get(name)
        if handler and not is_valid_default_handler(handler):
            handler = None

        if not handler:
            # Use default_handler from project configuration.
            handler = self.default_handler
            if not is_valid_default_handler(handler):
                raise ConfigurationError(
                    tag_(
                        "%(handler)s is not a valid default handler. Please "
                        "update %(option)s through the %(page)s page or by "
                        "directly editing trac.ini.",
                        handler=tag.code(handler.__class__.__name__),
                        option=tag.code("[trac] default_handler"),
                        page=tag.a(_("Basic Settings"),
                                   href=req.href.admin('general/basics'))))
        return handler
 def makeStream(self, node, indent=-2):
     if node.type == simpletree.Element.type:
         indent+=2
     if node.type not in (simpletree.Document.type,
                          simpletree.DocumentFragment.type):
         rv = self.serializeNode(node, indent)
     else:
         rv = tag()
     for child in node.childNodes:
         rv.append(self.makeStream(child, indent))
     if node.type == simpletree.Element.type:
         rv.append(tag.code("</" + node.name + ">",
                            class_=tagClasses["element"]))
     return rv
Exemple #40
0
    def __init__(self, path, log=None, params={}):
        self.cnx = None
        if path != ':memory:':
            if not os.access(path, os.F_OK):
                raise ConfigurationError(_('Database "%(path)s" not found.',
                                           path=path))

            dbdir = os.path.dirname(path)
            if not os.access(path, os.R_OK + os.W_OK) or \
                    not os.access(dbdir, os.R_OK + os.W_OK):
                raise ConfigurationError(tag_(
                    "The user %(user)s requires read _and_ write permissions "
                    "to the database file %(path)s and the directory it is "
                    "located in.", user=tag.code(getuser()),
                    path=tag.code(path)))

        self._active_cursors = weakref.WeakKeyDictionary()
        timeout = int(params.get('timeout', 10.0))
        self._eager = params.get('cursor', 'eager') == 'eager'
        # eager is default, can be turned off by specifying ?cursor=
        if isinstance(path, unicode):  # needed with 2.4.0
            path = path.encode('utf-8')
        cnx = sqlite.connect(path, detect_types=sqlite.PARSE_DECLTYPES,
                             check_same_thread=sqlite_version < (3, 3, 1),
                             timeout=timeout)
        # load extensions
        extensions = params.get('extensions', [])
        if len(extensions) > 0:
            cnx.enable_load_extension(True)
            for ext in extensions:
                cnx.load_extension(ext)
            cnx.enable_load_extension(False)

        cursor = cnx.cursor()
        _set_journal_mode(cursor, params.get('journal_mode'))
        _set_synchronous(cursor, params.get('synchronous'))
        ConnectionWrapper.__init__(self, cnx, log)
Exemple #41
0
    def expand_macro(self, formatter, name, content):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(content)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        def getdoc(option_or_section):
            doc = to_unicode(option_or_section.__doc__)
            if doc:
                doc = dgettext(option_or_section.doc_domain, doc)
            return doc

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, getdoc(section))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is not None and default != '':
                return tag.td(tag.code(option.dumps(default)),
                              class_='default')
            else:
                return tag.td(_("(no default)"), class_='nodefault')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context, getdoc(option))),
                        default_cell(option),
                        class_='odd' if idx % 2 else 'even')
                 for idx, option in
                    enumerate(sorted(options.get(section, {}).itervalues(),
                                     key=lambda o: o.name))
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Exemple #42
0
 def options_table(section, options):
     if options:
         return tag.table(class_='wiki')(
             tag.tbody(
                 tag.tr(
                     tag.td(tag.a(tag.code(option.name),
                                  class_='tracini-option',
                                  href='#%s-%s-option' %
                                       (section, option.name))),
                     tag.td(format_to_html(self.env, formatter.context,
                                           option.doc)),
                     default_cell(option),
                     id='%s-%s-option' % (section, option.name),
                     class_='odd' if idx % 2 else 'even')
              for idx, option in enumerate(options)))
Exemple #43
0
    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',
               )
Exemple #44
0
 def default_cell(option):
     default = option.default
     if default is True:
         default = 'true'
     elif default is False:
         default = 'false'
     elif default == 0:
         default = '0.0' if isinstance(default, float) else '0'
     elif default:
         default = ', '.join(to_unicode(val) for val in default) \
                   if isinstance(default, (list, tuple)) \
                   else to_unicode(default)
     else:
         return tag.td(_("(no default)"), class_='nodefault')
     return tag.td(tag.code(default), class_='default')
Exemple #45
0
 def default_cell(option):
     default = option.default
     if default is True:
         default = 'true'
     elif default is False:
         default = 'false'
     elif default == 0:
         default = '0.0' if isinstance(default, float) else '0'
     elif default:
         default = ', '.join(to_unicode(val) for val in default) \
                   if isinstance(default, (list, tuple)) \
                   else to_unicode(default)
     else:
         return tag.td(_("(no default)"), class_='nodefault')
     return tag.td(tag.code(default), class_='default')
Exemple #46
0
    def expand_macro(self, formatter, name, content):
        content = content.strip() if content else ''
        name_filter = content.strip('*')
        items = {}
        for subscriber in NotificationSystem(self.env).subscribers:
            name = subscriber.__class__.__name__
            if not name_filter or name.startswith(name_filter):
                items[name] = subscriber.description()

        return tag.div(class_='trac-subscriberlist')(tag.table(class_='wiki')(
            tag.thead(tag.tr(tag.th(_("Subscriber")),
                             tag.th(_("Description")))),
            tag.tbody(
                tag.tr(tag.td(tag.code(name)),
                       tag.td(items[name]),
                       class_='odd' if idx % 2 else 'even')
                for idx, name in enumerate(sorted(items.keys())))))
Exemple #47
0
    def expand_macro(self, formatter, name, content):
        content = content.strip() if content else ''
        name_filter = content.strip('*')
        items = {}
        for subscriber in NotificationSystem(self.env).subscribers:
            name = subscriber.__class__.__name__
            if not name_filter or name.startswith(name_filter):
                items[name] = subscriber.description()

        return tag.div(class_='trac-subscriberlist')(
            tag.table(class_='wiki')(
                tag.thead(tag.tr(
                    tag.th(_("Subscriber")),
                    tag.th(_("Description")))),
                tag.tbody(
                    tag.tr(tag.td(tag.code(name)),
                           tag.td(items[name]),
                           class_='odd' if idx % 2 else 'even')
                    for idx, name in enumerate(sorted(items.keys())))))
Exemple #48
0
    def send(self, from_addr, recipients, message):
        # Use native line endings in message
        message = fix_eol(message, os.linesep)

        self.log.info("Sending notification through sendmail at %s to %s",
                      self.sendmail_path, recipients)
        cmdline = [self.sendmail_path, '-i', '-f', from_addr] + recipients
        self.log.debug("Sendmail command line: %s", cmdline)
        try:
            child = Popen(cmdline, bufsize=-1, stdin=PIPE, stdout=PIPE,
                          stderr=PIPE, close_fds=close_fds)
        except OSError as e:
            raise ConfigurationError(
                tag_("Sendmail error (%(error)s). Please modify %(option)s "
                     "in your configuration.",
                     error=to_unicode(e),
                     option=tag.code("[notification] sendmail_path")))
        out, err = child.communicate(message)
        if child.returncode or err:
            raise Exception("Sendmail failed with (%s, %s), command: '%s'"
                            % (child.returncode, err.strip(), cmdline))
Exemple #49
0
def parse_connection_uri(db_str):
    """Parse the database connection string.

    The database connection string for an environment is specified through
    the `database` option in the `[trac]` section of trac.ini.

    :return: a tuple containing the scheme and a dictionary of attributes:
             `user`, `password`, `host`, `port`, `path`, `params`.
    :since: 1.1.3
    """
    if not db_str:
        section = tag.a("[trac]",
                        title=_("TracIni documentation"),
                        class_='trac-target-new',
                        href='http://trac.edgewall.org/wiki/TracIni'
                             '#trac-section')
        raise ConfigurationError(
            tag_("Database connection string is empty. Set the %(option)s "
                 "configuration option in the %(section)s section of "
                 "trac.ini. Please refer to the %(doc)s for help.",
                 option=tag.code("database"), section=section,
                 doc=_doc_db_str()))

    try:
        scheme, rest = db_str.split(':', 1)
    except ValueError:
        raise _invalid_db_str(db_str)

    if not rest.startswith('/'):
        if scheme == 'sqlite' and rest:
            # Support for relative and in-memory SQLite connection strings
            host = None
            path = rest
        else:
            raise _invalid_db_str(db_str)
    else:
        if not rest.startswith('//'):
            host = None
            rest = rest[1:]
        elif rest.startswith('///'):
            host = None
            rest = rest[3:]
        else:
            rest = rest[2:]
            if '/' in rest:
                host, rest = rest.split('/', 1)
            else:
                host = rest
                rest = ''
        path = None

    if host and '@' in host:
        user, host = host.split('@', 1)
        if ':' in user:
            user, password = user.split(':', 1)
        else:
            password = None
        if user:
            user = urllib.unquote(user)
        if password:
            password = unicode_passwd(urllib.unquote(password))
    else:
        user = password = None

    if host and ':' in host:
        host, port = host.split(':', 1)
        try:
            port = int(port)
        except ValueError:
            raise _invalid_db_str(db_str)
    else:
        port = None

    if not path:
        path = '/' + rest
    if os.name == 'nt':
        # Support local paths containing drive letters on Win32
        if len(rest) > 1 and rest[1] == '|':
            path = "%s:%s" % (rest[0], rest[2:])

    params = {}
    if '?' in path:
        path, qs = path.split('?', 1)
        qs = qs.split('&')
        for param in qs:
            try:
                name, value = param.split('=', 1)
            except ValueError:
                raise _invalid_db_str(db_str)
            value = urllib.unquote(value)
            params[name] = value

    args = zip(('user', 'password', 'host', 'port', 'path', 'params'),
               (user, password, host, port, path, params))
    return scheme, dict([(key, value) for key, value in args if value])
Exemple #50
0
    def render_admin_panel(self, req, category, page, path_info):
        # Retrieve info for all repositories
        rm = RepositoryManager(self.env)
        all_repos = rm.get_all_repositories()
        db_provider = self.env[DbRepositoryProvider]

        if path_info:
            # Detail view
            reponame = path_info if not is_default(path_info) else ""
            info = all_repos.get(reponame)
            if info is None:
                raise TracError(_("Repository '%(repo)s' not found", repo=path_info))
            if req.method == "POST":
                if req.args.get("cancel"):
                    req.redirect(req.href.admin(category, page))

                elif db_provider and req.args.get("save"):
                    # Modify repository
                    changes = {}
                    valid = True
                    for field in db_provider.repository_attrs:
                        value = normalize_whitespace(req.args.get(field))
                        if (value is not None or field in ("hidden", "sync_per_request")) and value != info.get(field):
                            changes[field] = value
                    if "dir" in changes and not self._check_dir(req, changes["dir"]):
                        valid = False
                    if valid and changes:
                        db_provider.modify_repository(reponame, changes)
                        add_notice(req, _("Your changes have been saved."))
                        name = req.args.get("name")
                        resync = tag.code(
                            "trac-admin %s repository resync " '"%s"' % (self.env.path, name or "(default)")
                        )
                        if "dir" in changes:
                            msg = tag_(
                                "You should now run %(resync)s to " "synchronize Trac with the repository.",
                                resync=resync,
                            )
                            add_notice(req, msg)
                        elif "type" in changes:
                            msg = tag_(
                                "You may have to run %(resync)s to " "synchronize Trac with the repository.",
                                resync=resync,
                            )
                            add_notice(req, msg)
                        if name and name != path_info and not "alias" in info:
                            cset_added = tag.code(
                                "trac-admin %s changeset " 'added "%s" $REV' % (self.env.path, name or "(default)")
                            )
                            msg = tag_(
                                "You will need to update your "
                                "post-commit hook to call "
                                "%(cset_added)s with the new "
                                "repository name.",
                                cset_added=cset_added,
                            )
                            add_notice(req, msg)
                    if valid:
                        req.redirect(req.href.admin(category, page))

            Chrome(self.env).add_wiki_toolbars(req)
            data = {"view": "detail", "reponame": reponame}

        else:
            # List view
            if req.method == "POST":
                # Add a repository
                if db_provider and req.args.get("add_repos"):
                    name = req.args.get("name")
                    type_ = req.args.get("type")
                    # Avoid errors when copy/pasting paths
                    dir = normalize_whitespace(req.args.get("dir", ""))
                    if name is None or type_ is None or not dir:
                        add_warning(req, _("Missing arguments to add a " "repository."))
                    elif self._check_dir(req, dir):
                        try:
                            db_provider.add_repository(name, dir, type_)
                        except self.env.db_exc.IntegrityError:
                            name = name or "(default)"
                            raise TracError(_('The repository "%(name)s" ' "already exists.", name=name))
                        name = name or "(default)"
                        add_notice(req, _('The repository "%(name)s" has been ' "added.", name=name))
                        resync = tag.code("trac-admin %s repository resync " '"%s"' % (self.env.path, name))
                        msg = tag_(
                            "You should now run %(resync)s to " "synchronize Trac with the repository.", resync=resync
                        )
                        add_notice(req, msg)
                        cset_added = tag.code("trac-admin %s changeset " 'added "%s" $REV' % (self.env.path, name))
                        doc = tag.a(_("documentation"), href=req.href.wiki("TracRepositoryAdmin") + "#Synchronization")
                        msg = tag_(
                            "You should also set up a post-commit hook "
                            "on the repository to call %(cset_added)s "
                            "for each committed changeset. See the "
                            "%(doc)s for more information.",
                            cset_added=cset_added,
                            doc=doc,
                        )
                        add_notice(req, msg)
                        req.redirect(req.href.admin(category, page))

                # Add a repository alias
                elif db_provider and req.args.get("add_alias"):
                    name = req.args.get("name")
                    alias = req.args.get("alias")
                    if name is not None and alias is not None:
                        try:
                            db_provider.add_alias(name, alias)
                        except self.env.db_exc.IntegrityError:
                            raise TracError(_('The alias "%(name)s" already ' "exists.", name=name or "(default)"))
                        add_notice(req, _('The alias "%(name)s" has been ' "added.", name=name or "(default)"))
                        req.redirect(req.href.admin(category, page))
                    add_warning(req, _("Missing arguments to add an " "alias."))

                # Refresh the list of repositories
                elif req.args.get("refresh"):
                    req.redirect(req.href.admin(category, page))

                # Remove repositories
                elif db_provider and req.args.get("remove"):
                    sel = req.args.getlist("sel")
                    if sel:
                        for name in sel:
                            db_provider.remove_repository(name)
                        add_notice(req, _("The selected repositories have " "been removed."))
                        req.redirect(req.href.admin(category, page))
                    add_warning(req, _("No repositories were selected."))

            data = {"view": "list"}

        # Find repositories that are editable
        db_repos = {}
        if db_provider is not None:
            db_repos = dict(db_provider.get_repositories())

        # Prepare common rendering data
        repositories = dict(
            (reponame, self._extend_info(reponame, info.copy(), reponame in db_repos))
            for (reponame, info) in all_repos.iteritems()
        )
        types = sorted([""] + rm.get_supported_types())
        data.update({"types": types, "default_type": rm.default_repository_type, "repositories": repositories})

        return "admin_repositories.html", data
Exemple #51
0
 def alert_disabled(self):
     return tag.div(tag.span('Error', class_='label label-important'),
                    ' Could not load dashboard. Is ',
                    tag.code('bhdashboard.web_ui.DashboardModule'),
                    ' component disabled ?',
                    class_='alert alert-error')
Exemple #52
0
    def expand_macro(self, formatter, name, content):
        from trac.config import ConfigSection, Option

        args, kw = parse_args(content)
        filters = {}
        for name, index in (('section', 0), ('option', 1)):
            pattern = kw.get(name, '').strip()
            if pattern:
                filters[name] = fnmatch.translate(pattern)
                continue
            prefix = args[index].strip() if index < len(args) else ''
            if prefix:
                filters[name] = re.escape(prefix)
        has_option_filter = 'option' in filters
        for name in ('section', 'option'):
            filters[name] = re.compile(filters[name], re.IGNORECASE).match \
                            if name in filters \
                            else lambda v: True
        section_filter = filters['section']
        option_filter = filters['option']

        section_registry = ConfigSection.get_registry(self.compmgr)
        option_registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in option_registry.iteritems():
            if section_filter(section) and option_filter(key):
                options.setdefault(section, {})[key] = option
        if not has_option_filter:
            for section in section_registry:
                if section_filter(section):
                    options.setdefault(section, {})
        for section in options:
            options[section] = sorted(options[section].itervalues(),
                                      key=lambda option: option.name)
        sections = [(section, section_registry[section].doc
                              if section in section_registry else '')
                    for section in sorted(options)]

        def default_cell(option):
            default = option.default
            if default is not None and default != '':
                return tag.td(tag.code(option.dumps(default)),
                              class_='default')
            else:
                return tag.td(_("(no default)"), class_='nodefault')

        def options_table(section, options):
            if options:
                return tag.table(class_='wiki')(
                    tag.tbody(
                        tag.tr(
                            tag.td(tag.a(tag.code(option.name),
                                         class_='tracini-option',
                                         href='#%s-%s-option' %
                                              (section, option.name))),
                            tag.td(format_to_html(self.env, formatter.context,
                                                  option.doc)),
                            default_cell(option),
                            id='%s-%s-option' % (section, option.name),
                            class_='odd' if idx % 2 else 'even')
                     for idx, option in enumerate(options)))

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             options_table(section, options.get(section)))
            for section, section_doc in sections)
Exemple #53
0
def _invalid_db_str(db_str):
    return ConfigurationError(
        tag_("Invalid format %(db_str)s for the database connection string. "
             "Please refer to the %(doc)s for help.",
             db_str=tag.code(db_str), doc=_doc_db_str()))
Exemple #54
0
 def alert_disabled(self):
     return tag.div(tag.span('Error', class_='label label-important'),
                    ' Could not load dashboard. Is ',
                    tag.code('bhdashboard.web_ui.DashboardModule'),
                    ' component disabled ?',
                    class_='alert alert-error')