Beispiel #1
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))))
Beispiel #2
0
 def generate_prefix(prefix):
     intertrac = intertracs[prefix]
     if isinstance(intertrac, basestring):
         yield tag.tr(tag.td(tag.strong(prefix)),
                      tag.td(tag_("Alias for %(name)s",
                                  name=tag.strong(intertrac))))
     else:
         url = intertrac.get('url', '')
         if url:
             title = intertrac.get('title', url)
             yield tag.tr(tag.td(tag.a(tag.strong(prefix),
                                       href=url + '/timeline')),
                          tag.td(tag.a(title, href=url)))
Beispiel #3
0
 def make_list(items):
     parts = [item.rsplit('.', 1) for item in items]
     return tag.table(tag.tbody(
         tag.tr(tag.td(c, class_='trac-name'),
                tag.td('(%s.*)' % m, class_='trac-name'))
         for m, c in parts),
                      class_='trac-pluglist')
Beispiel #4
0
    def expand_macro(self, formatter, name, content):
        interwikis = []
        for k in sorted(self.keys()):
            prefix, url, title = self[k]
            interwikis.append({
                'prefix': prefix, 'url': url, 'title': title,
                'rc_url': self._expand_or_append(url, ['RecentChanges']),
                'description': url if title == prefix else title})

        return tag.table(tag.tr(tag.th(tag.em(_("Prefix"))),
                                tag.th(tag.em(_("Site")))),
                         [tag.tr(tag.td(tag.a(w['prefix'], href=w['rc_url'])),
                                 tag.td(tag.a(w['description'],
                                              href=w['url'])))
                          for w in interwikis ],
                         class_="wiki interwiki")
Beispiel #5
0
    def expand_macro(self, formatter, name, content):
        intertracs = {}
        for key, value in self.intertrac_section.options():
            idx = key.rfind('.')
            if idx > 0: # 0 itself doesn't help much: .xxx = ...
                prefix, attribute = key[:idx], key[idx+1:]
                intertrac = intertracs.setdefault(prefix, {})
                intertrac[attribute] = value
            else:
                intertracs[key] = value # alias
        if 'trac' not in intertracs:
            intertracs['trac'] = {'title': _('The Trac Project'),
                                  'url': 'http://trac.edgewall.org'}

        def generate_prefix(prefix):
            intertrac = intertracs[prefix]
            if isinstance(intertrac, basestring):
                yield tag.tr(tag.td(tag.strong(prefix)),
                             tag.td(tag_("Alias for %(name)s",
                                         name=tag.strong(intertrac))))
            else:
                url = intertrac.get('url', '')
                if url:
                    title = intertrac.get('title', url)
                    yield tag.tr(tag.td(tag.a(tag.strong(prefix),
                                              href=url + '/timeline')),
                                 tag.td(tag.a(title, href=url)))

        return tag.table(class_="wiki intertrac")(
            tag.tr(tag.th(tag.em(_("Prefix"))),
                   tag.th(tag.em(_("Trac Site")))),
            [generate_prefix(p) for p in sorted(intertracs)])
Beispiel #6
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)))))
Beispiel #7
0
 def _body_rows():
     for idx, line in enumerate(lines):
         row = tag.tr()
         for annotator, data in annotator_datas:
             if annotator:
                 annotator.annotate_row(context, row, idx + 1, line,
                                        data)
             else:
                 row.append(tag.td())
         row.append(tag.td(line))
         yield row
Beispiel #8
0
 def _render_mergeinfo(self, name, mode, context, props):
     rows = []
     for row in props[name].splitlines():
         try:
             (path, revs) = row.rsplit(':', 1)
             rows.append([tag.td(path),
                          tag.td(revs.replace(',', u',\u200b'))])
         except ValueError:
             rows.append(tag.td(row, colspan=2))
     return tag.table(tag.tbody([tag.tr(row) for row in rows]),
                      class_='props')
Beispiel #9
0
 def expand_macro(self, formatter, name, content, args=None):
     t = [
         render_table(p, '1',
                      lambda s: self._format_phrase(formatter, s, None)) for
         p in [self.fixme_phrases, self.todo_phrases, self.done_phrases]
     ]
     style = 'border:none;text-align:center;vertical-align:top'
     spacer = tag.td(style='width:2em;border:none')
     return tag.table(
         tag.tr(tag.td(t[0], style=style),
                spacer, tag.td(t[1], style=style), spacer,
                tag.td(t[2], style=style)))
Beispiel #10
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)))
Beispiel #11
0
def render_table(items, colspec, render_item, colspace=1):
    try:
        columns = max(int(colspec), 1)
    except Exception:
        columns = 3

    nbsp = Markup(' ')
    # hdr = [tag.th(nbsp, 'Display'), tag.th('Markup', nbsp)]
    spacer_style = 'width:%dem;border:none' % colspace
    # Find max width to make value cols equally wide
    width = 0
    for i in items:
        if (isinstance(i, str) or isinstance(i, unicode)) and len(i) > width:
            width = len(i)
    value_style = 'border:none'
    #noinspection PyUnusedLocal
    if width:
        # empirical...
        value_style = '%s;width:%dem' % (value_style, width * 2 / 3)

    def render_def(s):
        rendered = s and render_item(s) or None
        if isinstance(s, str):
            s = Markup(s.replace('&', '&'))
        return [
            tag.td(rendered, nbsp, style='border:none'),
            tag.td(tag.kbd(s), style=value_style)
        ]

    return tag.table(  #tag.tr((hdr + [tag.td(style=spacer_style)]) *
        #       (columns-1) + hdr),
        [
            tag.tr([
                render_def(s) + [tag.td(style=spacer_style)] for s in row[:-1]
            ] + render_def(row[-1]))
            for row in group_over(sorted(items), columns)
        ],
        class_='wiki',
        style='border:none')
Beispiel #12
0
 def _head_row():
     return tag.tr([
         tag.th(labels[a], class_=a, title=titles[a])
         for a in annotations
     ] + [tag.th(u'\xa0', class_='content')])
Beispiel #13
0
    def render_property_diff(self, name, old_context, old_props, new_context,
                             new_props, options):
        # Build 5 columns table showing modifications on merge sources
        # || source || added || removed || added (ni) || removed (ni) ||
        # || source || removed                                        ||
        rm = RepositoryManager(self.env)
        repos = rm.get_repository(old_context.resource.parent.id)

        def parse_sources(props):
            sources = {}
            value = props[name]
            lines = value.splitlines() if name == 'svn:mergeinfo' \
                                       else value.split()
            for line in lines:
                path, revs = line.split(':', 1)
                spath = _path_within_scope(repos.scope, path)
                if spath is not None:
                    inheritable, non_inheritable = _partition_inheritable(revs)
                    sources[spath] = (set(Ranges(inheritable)),
                                      set(Ranges(non_inheritable)))
            return sources

        old_sources = parse_sources(old_props)
        new_sources = parse_sources(new_props)
        # Go through new sources, detect modified ones or added ones
        blocked = name.endswith('blocked')
        added_label = [_("merged: "), _("blocked: ")][blocked]
        removed_label = [_("reverse-merged: "), _("un-blocked: ")][blocked]
        added_ni_label = _("marked as non-inheritable: ")
        removed_ni_label = _("unmarked as non-inheritable: ")

        sources = []
        changed_revs = {}
        changed_nodes = []
        for spath, (new_revs, new_revs_ni) in new_sources.iteritems():
            new_spath = spath not in old_sources
            if new_spath:
                old_revs = old_revs_ni = set()
            else:
                old_revs, old_revs_ni = old_sources.pop(spath)
            added = new_revs - old_revs
            removed = old_revs - new_revs
            # unless new revisions differ from old revisions
            if not added and not removed:
                continue
            added_ni = new_revs_ni - old_revs_ni
            removed_ni = old_revs_ni - new_revs_ni
            revs = sorted(added | removed | added_ni | removed_ni)
            try:
                node = repos.get_node(spath, revs[-1])
                changed_nodes.append((node, revs[0]))
            except NoSuchNode:
                pass
            sources.append(
                (spath, new_spath, added, removed, added_ni, removed_ni))
        if changed_nodes:
            changed_revs = repos._get_changed_revs(changed_nodes)

        def revs_link(revs, context):
            if revs:
                revs = to_ranges(revs)
                return _get_revs_link(revs.replace(',', u',\u200b'), context,
                                      spath, revs)

        modified_sources = []
        for spath, new_spath, added, removed, added_ni, removed_ni in sources:
            if spath in changed_revs:
                revs = set(changed_revs[spath])
                added &= revs
                removed &= revs
                added_ni &= revs
                removed_ni &= revs
            if added or removed:
                if new_spath:
                    status = _(" (added)")
                else:
                    status = None
                modified_sources.append(
                    (spath, [_get_source_link(spath, new_context),
                             status], added
                     and tag(added_label, revs_link(added, new_context)),
                     removed
                     and tag(removed_label, revs_link(removed, old_context)),
                     added_ni
                     and tag(added_ni_label, revs_link(added_ni, new_context)),
                     removed_ni and tag(removed_ni_label,
                                        revs_link(removed_ni, old_context))))
        # Go through remaining old sources, those were deleted
        removed_sources = []
        for spath, old_revs in old_sources.iteritems():
            removed_sources.append(
                (spath, _get_source_link(spath, old_context)))
        if modified_sources or removed_sources:
            modified_sources.sort()
            removed_sources.sort()
            changes = tag.table(tag.tbody([
                tag.tr(tag.td(c) for c in cols[1:])
                for cols in modified_sources
            ], [
                tag.tr(tag.td(src), tag.td(_('removed'), colspan=4))
                for spath, src in removed_sources
            ]),
                                class_='props')
        else:
            changes = tag.em(_(' (with no actual effect on merging)'))
        return tag.li(tag_('Property %(prop)s changed', prop=tag.strong(name)),
                      changes)
Beispiel #14
0
    def render_property(self, name, mode, context, props):
        """Parse svn:mergeinfo and svnmerge-* properties, converting branch
        names to links and providing links to the revision log for merged
        and eligible revisions.
        """
        has_eligible = name in ('svnmerge-integrated', 'svn:mergeinfo')
        revs_label = _('blocked') if name.endswith('blocked') else _('merged')
        revs_cols = 2 if has_eligible else None
        reponame = context.resource.parent.id
        target_path = context.resource.id
        repos = RepositoryManager(self.env).get_repository(reponame)
        target_rev = context.resource.version
        if has_eligible:
            node = repos.get_node(target_path, target_rev)
            branch_starts = {}
            for path, rev in node.get_copy_ancestry():
                if path not in branch_starts:
                    branch_starts[path] = rev + 1
        rows = []
        eligible_infos = []
        if name.startswith('svnmerge-'):
            sources = props[name].split()
        else:
            sources = props[name].splitlines()
        for line in sources:
            path, revs = line.split(':', 1)
            spath = _path_within_scope(repos.scope, path)
            if spath is None:
                continue
            revs = revs.strip()
            inheritable, non_inheritable = _partition_inheritable(revs)
            revs = ','.join(inheritable)
            deleted = False
            try:
                node = repos.get_node(spath, target_rev)
                resource = context.resource.parent.child('source', spath)
                if 'LOG_VIEW' in context.perm(resource):
                    row = [
                        _get_source_link(spath, context),
                        _get_revs_link(revs_label, context, spath, revs)
                    ]
                    if non_inheritable:
                        non_inheritable = ','.join(non_inheritable)
                        row.append(
                            _get_revs_link(
                                _('non-inheritable'), context, spath,
                                non_inheritable,
                                _('merged on the directory '
                                  'itself but not below')))
                    if has_eligible:
                        first_rev = branch_starts.get(spath)
                        if not first_rev:
                            first_rev = node.get_branch_origin()
                        eligible = set(xrange(first_rev or 1, target_rev + 1))
                        eligible -= set(Ranges(revs))
                        blocked = _get_blocked_revs(props, name, spath)
                        if blocked:
                            eligible -= set(Ranges(blocked))
                        if eligible:
                            node = repos.get_node(spath, max(eligible))
                            eligible_infos.append((spath, node, eligible, row))
                            continue
                        eligible = to_ranges(eligible)
                        row.append(
                            _get_revs_link(_('eligible'), context, spath,
                                           eligible))
                    rows.append((False, spath, [tag.td(each) for each in row]))
                    continue
            except NoSuchNode:
                deleted = True
            revs = revs.replace(',', u',\u200b')
            rows.append(
                (deleted, spath,
                 [tag.td('/' + spath),
                  tag.td(revs, colspan=revs_cols)]))

        # fetch eligible revisions for each path at a time
        changed_revs = {}
        changed_nodes = [(node, min(eligible))
                         for spath, node, eligible, row in eligible_infos]
        if changed_nodes:
            changed_revs = repos._get_changed_revs(changed_nodes)
        for spath, node, eligible, row in eligible_infos:
            if spath in changed_revs:
                eligible &= set(changed_revs[spath])
            else:
                eligible.clear()
            row.append(
                _get_revs_link(_("eligible"), context, spath,
                               to_ranges(eligible)))
            rows.append((False, spath, [tag.td(each) for each in row]))

        if not rows:
            return None
        rows.sort()
        if rows and rows[-1][0]:
            toggledeleted = tag.a(_("(toggle deleted branches)"),
                                  class_='trac-toggledeleted',
                                  href='#')
        else:
            toggledeleted = None
        return tag(
            toggledeleted,
            tag.table(tag.tbody([
                tag.tr(row, class_='trac-deleted' if deleted else None)
                for deleted, spath, row in rows
            ]),
                      class_='props'))