예제 #1
0
파일: macros.py 프로젝트: jier38/TracSite
    def _render_full_format(self, formatter, post_list, post_instances,
                            heading, max_size, show_meta):
        """ Renters full blog posts. """
        out = ''
        if 'BLOG_VIEW' in formatter.req.perm('blog'):
            out = tag.div(class_="blog")
            out.append(
                tag.div(tag.a(heading, href=formatter.req.href.blog()),
                        class_="blog-list-title"))
            for post in post_instances:
                data = {
                    'post':
                    post,
                    'blog_personal_blog':
                    self.config.getbool('fullblog', 'personal_blog'),
                    'list_mode':
                    True,
                    'show_meta':
                    show_meta,
                    'execute_blog_macro':
                    True
                }
                if max_size:
                    data['blog_max_size'] = max_size

                txt = Chrome(self.env).render_template(
                    formatter.req, 'fullblog_macro_post.html', data,
                    {'fragment': True})
                out.append(Markup(to_unicode(txt)))
        return out
예제 #2
0
    def expand_macro(self, formatter, name, text, args):
        if not text:
            raw_actions = self.config.options('ticket-workflow')
        else:
            if args is None:
                text = '\n'.join(line.lstrip() for line in text.split(';'))
            if '[ticket-workflow]' not in text:
                text = '[ticket-workflow]\n' + text
            parser = RawConfigParser()
            try:
                parser.readfp(io.StringIO(text))
            except ParsingError as e:
                return system_message(_("Error parsing workflow."), unicode(e))
            raw_actions = list(parser.items('ticket-workflow'))
        actions = parse_workflow_config(raw_actions)
        states = list({
            state
            for action in actions.itervalues() for state in action['oldstates']
        } | {action['newstate']
             for action in actions.itervalues()})
        action_labels = [attrs['label'] for attrs in actions.values()]
        action_names = actions.keys()
        edges = []
        for name, action in actions.items():
            new_index = states.index(action['newstate'])
            name_index = action_names.index(name)
            for old_state in action['oldstates']:
                old_index = states.index(old_state)
                edges.append((old_index, new_index, name_index))

        args = args or {}
        width = args.get('width', 800)
        height = args.get('height', 600)
        graph = {
            'nodes': states,
            'actions': action_labels,
            'edges': edges,
            'width': width,
            'height': height
        }
        graph_id = '%012x' % id(graph)
        req = formatter.req
        add_script(req, 'common/js/excanvas.js', ie_if='IE')
        add_script(req, 'common/js/workflow_graph.js')
        add_script_data(req, {'graph_%s' % graph_id: graph})
        return tag(
            tag.div('',
                    class_='trac-workflow-graph trac-noscript',
                    id='trac-workflow-graph-%s' % graph_id,
                    style="display:inline-block;width:%spx;height:%spx" %
                    (width, height)),
            tag.noscript(
                tag.div(_("Enable JavaScript to display the workflow graph."),
                        class_='system-message')))
예제 #3
0
    def generate_captcha(self, req):
        add_script(req, 'https://www.google.com/recaptcha/api.js')

        return None, tag(
            tag.div(class_='g-recaptcha', data_sitekey=self.public_key),
            tag.input(type='submit', value=_("Submit"))
        )
예제 #4
0
 def _render(self, formatter, cols, name_pat, size, header, limit):
     #noinspection PyArgumentList
     icon = Icons(self.env)
     icon_dir = icon.icon_location(size)[1]
     files = fnmatch.filter(os.listdir(icon_dir), '%s.png' % name_pat)
     icon_names = [os.path.splitext(p)[0] for p in files]
     if limit:
         displayed_icon_names = reduce_names(icon_names, limit)
     else:
         displayed_icon_names = icon_names
     icon_table = render_table(
         displayed_icon_names, cols,
         lambda name: icon._render_icon(formatter, name, size))
     if not len(icon_names):
         message = 'No %s icon matches %s' % (SIZE_DESCR[size], name_pat)
     elif len(icon_names) == 1:
         message = 'Showing the only %s icon matching %s' % \
                   (SIZE_DESCR[size], name_pat)
     elif len(displayed_icon_names) == len(icon_names):
         message = 'Showing all %d %s icons matching %s' % \
                   (len(icon_names), SIZE_DESCR[size], name_pat)
     else:
         message = 'Showing %d of %d %s icons matching %s' % \
                   (len(displayed_icon_names), len(icon_names),
                    SIZE_DESCR[size], name_pat)
     return tag.div(tag.p(tag.small(message)) if header else '', icon_table)
예제 #5
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))))
예제 #6
0
 def expand_macro(self, formatter, name, content, args=None):
     args = args or {}
     reponame = args.get('repository') or ''
     rev = args.get('revision')
     repos = RepositoryManager(self.env).get_repository(reponame)
     try:
         changeset = repos.get_changeset(rev)
     except Exception:
         message = content
         resource = Resource('repository', reponame)
     else:
         message = changeset.message
         rev = changeset.rev
         resource = repos.resource
     if formatter.context.resource.realm == 'ticket':
         ticket_re = CommitTicketUpdater.ticket_re
         if not any(
                 int(tkt_id) == int(formatter.context.resource.id)
                 for tkt_id in ticket_re.findall(message)):
             return tag.p(_("(The changeset message doesn't reference "
                            "this ticket)"),
                          class_='hint')
     if ChangesetModule(self.env).wiki_format_messages:
         return tag.div(format_to_html(self.env,
                                       formatter.context.child(
                                           'changeset',
                                           rev,
                                           parent=resource),
                                       message,
                                       escape_newlines=True),
                        class_='message')
     else:
         return tag.pre(message, class_='message')
예제 #7
0
    def render_registration_fields(self, req, data):
        insert = tag.div(tag.label(_("Details:"), tag.input(type="text",
                     name=TrapFieldFilterStrategy(self.env).name_register, size=60, class_="textwidget")))

        if RegistrationFilterStrategy:
            return RegistrationFilterStrategy(self.env).render_registration_fields(req, data, dict(optional=insert))
        else:
            return dict(optional=insert), data
예제 #8
0
 def filter_stream(self, req, method, filename, stream, data):
     if self.karma_points > 0:
         # Insert the hidden field right before the submit buttons
         trap = tag.div(style='display:none;')(
                 tag.input(type='text', name=self.name, value=''),
                 tag.input(type='hidden', name=self.name_hidden, value=''))
         stream = stream | \
                  Transformer('//div[@class="buttons"]').before(trap)
     return stream
예제 #9
0
    def expand_macro(self, formatter, name, content):
        min_depth, max_depth = 1, 6
        title = None
        inline = False
        numbered = True
        if content:
            argv = [arg.strip() for arg in content.split(',')]
            if len(argv) > 0:
                depth = argv[0]
                if '-' in depth:
                    min_depth, max_depth = \
                        [_arg_as_int(d, min=min_depth, max=max_depth)
                         for d in depth.split('-', 1)]
                else:
                    min_depth = max_depth = \
                        _arg_as_int(depth, min=min_depth, max=max_depth)
                if len(argv) > 1:
                    title = argv[1].strip()
                    for arg in argv[2:]:
                        arg = arg.strip().lower()
                        if arg == 'inline':
                            inline = True
                        elif arg == 'unnumbered':
                            numbered = False

        # TODO: - integrate the rest of the OutlineFormatter directly here
        #       - use formatter.wikidom instead of formatter.source
        out = io.StringIO()
        oformatter = OutlineFormatter(self.env, formatter.context)
        oformatter.format(formatter.source,
                          out,
                          max_depth,
                          min_depth,
                          shorten=not inline)
        outline = Markup(out.getvalue())

        if title:
            outline = tag.h4(title, class_='section') + outline
        if not inline:
            outline = tag.div(outline, class_='wiki-toc')
        elif not numbered:
            outline = tag.div(outline, class_='wiki-toc-un')
        return outline
예제 #10
0
 def _error_div(self, msg):
     """Display msg in an error box, using Trac style."""
     self.log.error(msg)
     if isinstance(msg, str):
         msg = tag.pre(escape(msg))
     return tag.div(tag.strong(
         _("Graphviz macro processor has detected an error. "
           "Please fix the problem before continuing.")),
                    msg,
                    class_="system-message")
예제 #11
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]))
예제 #12
0
    def expand_macro(self, formatter, name, content):
        args, kw = parse_args(content)
        prefix = args[0].strip() if args else None
        limit = _arg_as_int(args[1].strip(), min=1) if len(args) > 1 else None
        group = kw.get('group', 'date')

        sql = """SELECT name, max(version) AS max_version,
                        max(time) AS max_time FROM wiki"""
        args = []
        if prefix:
            with self.env.db_query as db:
                sql += " WHERE name %s" % db.prefix_match()
                args.append(db.prefix_match_value(prefix))
        sql += " GROUP BY name ORDER BY max_time DESC"
        if limit:
            sql += " LIMIT %s"
            args.append(limit)

        entries_per_date = []
        prevdate = None
        for name, version, ts in self.env.db_query(sql, args):
            if 'WIKI_VIEW' not in formatter.perm('wiki', name, version):
                continue
            req = formatter.req
            date = user_time(req, format_date, from_utimestamp(ts))
            if date != prevdate:
                prevdate = date
                entries_per_date.append((date, []))
            version = int(version)
            diff_href = None
            if version > 1:
                diff_href = formatter.href.wiki(name, action='diff',
                                                version=version)
            page_name = formatter.wiki.format_page_name(name)
            entries_per_date[-1][1].append((page_name, name, version,
                                            diff_href))

        items_per_date = (
            (date, (tag.li(tag.a(page, href=formatter.href.wiki(name)),
                           tag.small(' (', tag.a(_("diff"), href=diff_href),
                                     ')') if diff_href else None,
                           '\n')
                    for page, name, version, diff_href in entries))
            for date, entries in entries_per_date)

        if group == 'date':
            out = ((tag.h3(date, class_='section'), tag.ul(entries))
                   for date, entries in items_per_date)
        else:
            out = tag.ul(entries for date, entries in items_per_date)
        return tag.div(out, class_="wikipage")
예제 #13
0
 def _wiki_edit(self, req, stream):
     tags = ' '.join(self._page_tags(req))
     # TRANSLATOR: Label text for link to '/tags'.
     link = tag.a(_("view all tags"), href=req.href.tags())
     # TRANSLATOR: ... (view all tags)
     insert = tag(
         tag_("Tag under: (%(tags_link)s)", tags_link=link), tag.br(),
         tag.input(id='tags',
                   type='text',
                   name='tags',
                   size='50',
                   value=req.args.get('tags', tags)))
     insert = tag.div(tag.label(insert), class_='field')
     return stream | Transformer('//div[@id="changeinfo1"]').append(insert)
예제 #14
0
파일: prefs.py 프로젝트: rwbaumg/trac
    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)))))
예제 #15
0
파일: auth.py 프로젝트: wataash/trac
 def get_navigation_items(self, req):
     if req.is_authenticated:
         yield ('metanav', 'login',
                tag_("logged in as %(user)s",
                     user=Chrome(self.env).authorinfo(req, req.authname)))
         yield ('metanav', 'logout',
                tag.form(
                    tag.div(
                        tag.button(_("Logout"), name='logout',
                                   type='submit'),
                        tag.input(type='hidden', name='__FORM_TOKEN',
                                  value=req.form_token)
                    ),
                    action=req.href.logout(), method='post',
                    id='logout', class_='trac-logout'))
     else:
         yield ('metanav', 'login',
                tag.a(_("Login"), href=req.href.login()))
예제 #16
0
    def expand_macro(self, formatter, name, content):
        curpage = formatter.resource.id

        # scoped TOC (e.g. TranslateRu/TracGuide or 0.11/TracGuide ...)
        prefix = ''
        idx = curpage.find('/')
        if idx > 0:
            prefix = curpage[:idx+1]

        ws = WikiSystem(self.env)
        return tag.div(
            tag.h4(_('Table of Contents')),
            tag.ul([tag.li(tag.a(title, href=formatter.href.wiki(prefix+ref),
                                 class_=(not ws.has_page(prefix+ref) and
                                         'missing')),
                           class_=(prefix+ref == curpage and 'active'))
                    for ref, title in self.TOC]),
            class_='wiki-toc')
예제 #17
0
파일: wiki.py 프로젝트: jier38/TracSite
 def _post_process_request_wiki_edit(self, req):
     tags = ' '.join(self._page_tags(req))
     # TRANSLATOR: Label text for link to '/tags'.
     link = tag.a(_("view all tags"), href=req.href.tags())
     # TRANSLATOR: ... (view all tags)
     insert = tag(
         tag_("Tag under: (%(tags_link)s)", tags_link=link), tag.br(),
         tag.input(id='tags',
                   type='text',
                   name='tags',
                   size='50',
                   value=req.args.get('tags', tags)))
     insert = tag.div(tag.label(insert), class_='field')
     filter_lst = []
     # xpath = //div[@id="changeinfo1"]
     xform = JTransformer('div#changeinfo1')
     filter_lst.append(xform.append(Markup(insert)))
     self._add_jtransform(req, filter_lst)
예제 #18
0
    def expand_macro(self, formatter, name, content):
        def wikify(text):
            return format_to_oneliner(self.env, formatter.context, text)

        return tag.div(
            tag.p(
                wikify(
                    _("""
                The following tokens can be used in the `PageTemplates/MyPage`
                or `PageTemplates/MyPage/<user>` wiki pages:
                """))),
            tag.dl([(tag.dt(tag.tt(token)),
                     tag.dd(wikify(gettext(description))))
                    for token, description in sorted(
                        MyPageModule(self.env).tokens.values())]),
            tag.p(
                wikify(
                    _("""
                Note that you can also use the `[[MyPageNav]]` wiki macro for
                creating dynamic links to other ''MyPage'' pages (use
                `[[MyPageNav?]]` to get help on this macro).
                """))))
예제 #19
0
    def expand_macro(self, formatter, name, content, args=None):
        if content is not None:
            content = content.strip()
        if not args and not content:
            raw_actions = self.config.options('ticket-workflow')
        else:
            is_macro = args is None
            if is_macro:
                kwargs = parse_args(content)[1]
                file = kwargs.get('file')
            else:
                file = args.get('file')
                if not file and not content:
                    raise ProcessorError("Invalid argument(s).")

            if file:
                print(file)
                text = RepositoryManager(self.env).read_file_by_path(file)
                if text is None:
                    raise ProcessorError(
                        tag_("The file %(file)s does not exist.",
                             file=tag.code(file)))
            elif is_macro:
                text = '\n'.join(line.lstrip() for line in content.split(';'))
            else:
                text = content

            if '[ticket-workflow]' not in text:
                text = '[ticket-workflow]\n' + text
            parser = RawConfigParser()
            try:
                parser.readfp(io.StringIO(text))
            except ParsingError as e:
                if is_macro:
                    raise MacroError(exception_to_unicode(e))
                else:
                    raise ProcessorError(exception_to_unicode(e))
            raw_actions = list(parser.items('ticket-workflow'))
        actions = parse_workflow_config(raw_actions)
        states = list(
            {state for action in actions.itervalues()
                   for state in action['oldstates']} |
            {action['newstate'] for action in actions.itervalues()})
        action_labels = [attrs['label'] for attrs in actions.values()]
        action_names = list(actions)
        edges = []
        for name, action in actions.items():
            new_index = states.index(action['newstate'])
            name_index = action_names.index(name)
            for old_state in action['oldstates']:
                old_index = states.index(old_state)
                edges.append((old_index, new_index, name_index))

        args = args or {}
        width = args.get('width', 800)
        height = args.get('height', 600)
        graph = {'nodes': states, 'actions': action_labels, 'edges': edges,
                 'width': width, 'height': height}
        graph_id = '%012x' % id(graph)
        req = formatter.req
        add_script(req, 'common/js/excanvas.js', ie_if='IE')
        add_script(req, 'common/js/workflow_graph.js')
        add_script_data(req, {'graph_%s' % graph_id: graph})
        return tag(
            tag.div('', class_='trac-workflow-graph trac-noscript',
                    id='trac-workflow-graph-%s' % graph_id,
                    style="display:inline-block;width:%spx;height:%spx" %
                          (width, height)),
            tag.noscript(
                tag.div(_("Enable JavaScript to display the workflow graph."),
                        class_='system-message')))
예제 #20
0
    def render(self,
               context,
               mimetype,
               content,
               filename=None,
               url=None,
               annotations=None,
               force_source=False):
        """Render an XHTML preview of the given `content`.

        `content` is the same as an `IHTMLPreviewRenderer.render`'s
        `content` argument.

        The specified `mimetype` will be used to select the most appropriate
        `IHTMLPreviewRenderer` implementation available for this MIME type.
        If not given, the MIME type will be infered from the filename or the
        content.

        Return a string containing the XHTML text.

        When rendering with an `IHTMLPreviewRenderer` fails, a warning is added
        to the request associated with the context (if any), unless the
        `disable_warnings` hint is set to `True`.
        """
        if not content:
            return ''

        # Ensure we have a MIME type for this content
        full_mimetype = mimetype
        if not full_mimetype:
            if hasattr(content, 'read'):
                content = content.read(self.max_preview_size)
            full_mimetype = self.get_mimetype(filename, content)
        if full_mimetype:
            mimetype = ct_mimetype(full_mimetype)  # split off charset
        else:
            mimetype = full_mimetype = 'text/plain'  # fallback if not binary

        # Determine candidate `IHTMLPreviewRenderer`s
        candidates = []
        for renderer in self.renderers:
            qr = renderer.get_quality_ratio(mimetype)
            if qr > 0:
                candidates.append((qr, renderer))
        candidates.sort(key=lambda item: -item[0])

        # Wrap file-like object so that it can be read multiple times
        if hasattr(content, 'read'):
            content = Content(content, self.max_preview_size)

        # First candidate which renders successfully wins.
        # Also, we don't want to expand tabs more than once.
        expanded_content = None
        for qr, renderer in candidates:
            if force_source and not getattr(renderer, 'returns_source', False):
                continue  # skip non-source renderers in force_source mode
            if isinstance(content, Content):
                content.reset()
            try:
                ann_names = ', '.join(annotations) if annotations else \
                           'no annotations'
                self.log.debug('Trying to render HTML preview using %s [%s]',
                               renderer.__class__.__name__, ann_names)

                # check if we need to perform a tab expansion
                rendered_content = content
                if getattr(renderer, 'expand_tabs', False):
                    if expanded_content is None:
                        content = content_to_unicode(self.env, content,
                                                     full_mimetype)
                        expanded_content = content.expandtabs(self.tab_width)
                    rendered_content = expanded_content

                result = renderer.render(context, full_mimetype,
                                         rendered_content, filename, url)
                if not result:
                    continue

                if not (force_source
                        or getattr(renderer, 'returns_source', False)):
                    # Direct rendering of content
                    if isinstance(result, basestring):
                        return Markup(to_unicode(result))
                    elif isinstance(result, Fragment):
                        return result.__html__()
                    else:
                        return result

                # Render content as source code
                if annotations:
                    marks = context.req.args.get('marks') if context.req \
                            else None
                    if marks:
                        context.set_hints(marks=marks)
                    return self._render_source(context, result, annotations)
                else:
                    if isinstance(result, list):
                        result = Markup('\n').join(result)
                    return tag.div(class_='code')(tag.pre(result))

            except Exception as e:
                self.log.warning('HTML preview using %s with %r failed: %s',
                                 renderer.__class__.__name__, context,
                                 exception_to_unicode(e, traceback=True))
                if context.req and not context.get_hint('disable_warnings'):
                    from trac.web.chrome import add_warning
                    add_warning(
                        context.req,
                        _("HTML preview using %(renderer)s failed (%(err)s)",
                          renderer=renderer.__class__.__name__,
                          err=exception_to_unicode(e)))
예제 #21
0
    def expand_macro(self, formatter, name, content, args=None):
        class_list = ['wikiextras', 'box']
        style_list = []
        if args is None:
            content, args = parse_args(content)

        #noinspection PyArgumentList
        if not Icons(self.env).shadowless:
            class_list.append('shadow')

        class_arg = args.get('class', '')
        if class_arg:
            class_list.append(class_arg)

        align = ('right' if name in ('newsbox', 'rbox') else 'center'
                 if name == 'imagebox' else 'left' if name == 'lbox' else '')
        align = args.get('align', align)
        if align:
            class_list.append(align)

        if name == 'newsbox':
            type = 'news'
        elif name == 'imagebox':
            type = 'image'
        else:
            type = args.get('type')
            if not type:
                for flag, value in args.iteritems():
                    if value is True:
                        type = flag
                        break
            type = self._get_type(type)
        if type in self.types:
            td = self.types[type]  # type data
            if td[1]:  #icon
                class_list += ['icon', td[1]]
            else:
                class_list.append(type)
            bg = self.urgency_bg.get(td[0])
            if bg:
                class_list.append(bg)
            del td
        elif type:
            class_list.append(type)

        style = args.get('style', '')
        if style:
            style_list.append(style)

        width = args.get('width', '')
        if width:
            if width.isdigit():
                width = '%spx' % width
            if width.endswith('px'):
                # compensate for padding
                if self._has_icon(type):
                    width = '%dpx' % (int(width[:-2]) - 57)
                else:
                    width = '%dpx' % (int(width[:-2]) - 22)
            style_list.append('width:%s' % width)

        html = format_to_html(self.env, formatter.context, content)
        class_ = ' '.join(class_list)
        style = ';'.join(style_list)
        div = sanitize_attrib(self.env, tag.div(class_=class_, style=style))
        div(html)
        return div
예제 #22
0
 def render(self, context, mimetype, content, filename=None, url=None):
     if url:
         return tag.div(tag.img(src=url, alt=filename), class_='image-file')
예제 #23
0
파일: macros.py 프로젝트: jier38/TracSite
    def expand_macro(self, formatter, name, content):

        # Parse content for arguments
        args_list, args_dict = parse_args(content)
        from_dt, to_dt = parse_period(
            list(args_dict.get('period', '').split('/')))
        category = args_dict.get('category', '')
        author = args_dict.get('author', '')
        recent = as_int(args_dict.get('recent'), 0)
        format = args_dict.get('format', 'inline').lower()
        heading = args_dict.get('heading', '')
        max_size = as_int(args_dict.get('max_size', 0))
        show_meta = args_dict.get('meta', '') != 'off' and True or False

        # Get blog posts
        all_posts = get_blog_posts(self.env,
                                   author=author,
                                   category=category,
                                   from_dt=from_dt,
                                   to_dt=to_dt)

        # Trim posts against permissions and count
        post_list = []
        post_instances = []
        if format in ['float', 'full']:
            recent = recent or self.config.getint('fullblog',
                                                  'num_items_front')
        recent = recent or len(all_posts)
        count = 0
        for post in all_posts:
            if count == recent:
                break
            bp = BlogPost(self.env, post[0])
            if 'BLOG_VIEW' in formatter.req.perm(bp.resource):
                count += 1
                post_instances.append(bp)
                post_list.append(post)

        # Rendering
        add_stylesheet(formatter.req, 'tracfullblog/css/fullblog.css')
        add_stylesheet(formatter.req, 'common/css/code.css')

        if format == 'inline':
            data = {
                'heading':
                heading,
                'posts':
                post_list,
                'blog_personal_blog':
                self.config.getbool('fullblog', 'personal_blog'),
                'show_meta':
                show_meta,
                'execute_blog_macro':
                True
            }
            return Chrome(self.env).render_template(
                formatter.req, 'fullblog_macro_monthlist.html', data,
                {'fragment': True})

        elif format in ('full', 'float'):
            out = self._render_full_format(formatter, post_list,
                                           post_instances, heading, max_size,
                                           show_meta)
            if out and format == 'float':
                return tag.div(out, class_="blogflash")
            else:
                return out

        else:
            raise TracError("Invalid 'format' argument used for macro %s." %
                            name)
예제 #24
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)
예제 #25
0
                        self._record_action(status, type, ("ok" if spamstatus == rejected else "error"), strategy, 0)
                    else:
                        self._record_action(status, type, '', strategy, 0)
                self._record_action(status, type, '', '', 0)

            LogEntry.purge(self.env, self.purge_age)

        if score < self.min_karma:
            self.log.debug('Rejecting submission %r by "%s" (%r) because it '
                           'earned only %d karma points (%d are required).',
                           abbrev, author, req.remote_addr, score, self.min_karma)
            rejects = []
            outreasons.sort()
            for r in outreasons:
                rejects.append(tag.li(r))
            msg = tag.div(tag.ul(rejects), class_='message')

            self.reject_handler.reject_content(req, msg)

    def train(self, req, ids, spam=True, delete=False):
        environ = {}
        for name, value in req.environ.items():
            if not name.startswith('HTTP_'):
                environ[name] = value

        if not isinstance(ids, list):
            ids = [ids]
        for log_id in ids:
            start = time.time()
            entry = LogEntry.fetch(self.env, log_id)
            if entry:
예제 #26
0
    def expand_macro(self, formatter, name, content):
        args, kw = parse_args(content)
        prefix = args[0].strip() if args else None
        hideprefix = args and len(args) > 1 and args[1].strip() == 'hideprefix'
        minsize = _arg_as_int(kw.get('min', 1), 'min', min=1)
        minsize_group = max(minsize, 2)
        depth = _arg_as_int(kw.get('depth', -1), 'depth', min=-1)
        format = kw.get('format', '')

        def parse_list(name):
            return [
                inc.strip() for inc in kw.get(name, '').split(':')
                if inc.strip()
            ]

        includes = parse_list('include') or ['*']
        excludes = parse_list('exclude')

        wiki = formatter.wiki
        resource = formatter.resource
        if prefix and resource and resource.realm == 'wiki':
            prefix = wiki.resolve_relative_name(prefix, resource.id)

        start = prefix.count('/') if prefix else 0

        if hideprefix:
            omitprefix = lambda page: page[len(prefix):]
        else:
            omitprefix = lambda page: page

        pages = sorted(page for page in wiki.get_pages(prefix)
                       if (depth < 0 or depth >= page.count('/') - start)
                       and 'WIKI_VIEW' in formatter.perm('wiki', page) and any(
                           fnmatchcase(page, inc)
                           for inc in includes) and not any(
                               fnmatchcase(page, exc) for exc in excludes))

        if format == 'compact':
            return tag(
                separated((tag.a(wiki.format_page_name(omitprefix(p)),
                                 href=formatter.href.wiki(p))
                           for p in pages), ', '))

        # the function definitions for the different format styles

        # the different page split formats, each corresponding to its rendering
        def split_pages_group(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted at Camel Case word boundaries, numbers and '/'.
            """
            page_paths = []
            for page in pages:
                path = [
                    elt.strip() for elt in self.SPLIT_RE.split(
                        self.NUM_SPLIT_RE.sub(
                            r" \1 ",
                            wiki.format_page_name(omitprefix(page),
                                                  split=True)))
                ]
                page_paths.append(([elt for elt in path if elt], page))
            return page_paths

        def split_pages_hierarchy(pages):
            """Return a list of (path elements, page_name) pairs,
            where path elements correspond to the page name (without prefix)
            splitted according to the '/' hierarchy.
            """
            return [(wiki.format_page_name(omitprefix(page)).split("/"), page)
                    for page in pages]

        # the different tree structures, each corresponding to its rendering
        def tree_group(entries):
            """Transform a flat list of entries into a tree structure.

            `entries` is a list of `(path_elements, page_name)` pairs

            Return a list organized in a tree structure, in which:
              - a leaf is a page name
              - a node is a `(key, nodes)` pairs, where:
                - `key` is the leftmost of the path elements, common to the
                  grouped (path element, page_name) entries
                - `nodes` is a list of nodes or leaves
            """
            def keyfn(args):
                elts, name = args
                return elts[0] if elts else ''

            groups = []

            for key, grouper in groupby(entries, keyfn):
                # remove key from path_elements in grouped entries for further
                # grouping
                grouped_entries = [(path_elements[1:], page_name)
                                   for path_elements, page_name in grouper]

                if key and len(grouped_entries) >= minsize_group:
                    subnodes = tree_group(sorted(grouped_entries))
                    if len(subnodes) == 1:
                        subkey, subnodes = subnodes[0]
                        node = (key + subkey, subnodes)
                        groups.append(node)
                    elif self.SPLIT_RE.match(key):
                        for elt in subnodes:
                            if isinstance(elt, tuple):
                                subkey, subnodes = elt
                                elt = (key + subkey, subnodes)
                            groups.append(elt)
                    else:
                        node = (key, subnodes)
                        groups.append(node)
                else:
                    for path_elements, page_name in grouped_entries:
                        groups.append(page_name)
            return groups

        def tree_hierarchy(entries):
            """Transform a flat list of entries into a tree structure.

            `entries` is a list of `(path_elements, page_name)` pairs

            Return a list organized in a tree structure, in which:
              - a leaf is a `(rest, page)` pair, where:
                - `rest` is the rest of the path to be shown
                - `page` is a page name
              - a node is a `(key, nodes, page)` pair, where:
                - `key` is the leftmost of the path elements, common to the
                  grouped (path element, page_name) entries
                - `page` is a page name (if one exists for that node)
                - `nodes` is a list of nodes or leaves
            """
            def keyfn(args):
                elts, name = args
                return elts[0] if elts else ''

            groups = []

            for key, grouper in groupby(entries, keyfn):
                grouped_entries = [e for e in grouper]
                sub_entries = [e for e in grouped_entries if len(e[0]) > 1]
                key_entries = [e for e in grouped_entries if len(e[0]) == 1]
                key_entry = key_entries[0] if key_entries else None
                key_page = key_entry[1] if key_entries else None

                if key and len(sub_entries) >= minsize:
                    # remove key from path_elements in grouped entries for
                    # further grouping
                    sub_entries = [(path_elements[1:], page)
                                   for path_elements, page in sub_entries]

                    subnodes = tree_hierarchy(sorted(sub_entries))
                    node = (key, key_page, subnodes)
                    groups.append(node)
                else:
                    if key_entry:
                        groups.append(key_entry)
                    groups.extend(sub_entries)
            return groups

        # the different rendering formats
        def render_group(group):
            return tag.ul(
                tag.li(
                    tag(tag.strong(elt[0].strip('/')), render_group(elt[1])
                        ) if isinstance(elt, tuple) else tag.
                    a(wiki.format_page_name(omitprefix(elt)),
                      href=formatter.href.wiki(elt))) for elt in group)

        def render_hierarchy(group):
            return tag.ul(
                tag.li(
                    tag(
                        tag.a(elt[0], href=formatter.href.wiki(elt[1])
                              ) if elt[1] else tag(elt[0]),
                        render_hierarchy(elt[2])) if len(elt) == 3 else tag.
                    a('/'.join(elt[0]), href=formatter.href.wiki(elt[1])))
                for elt in group)

        transform = {
            'group':
            lambda p: render_group(tree_group(split_pages_group(p))),
            'hierarchy':
            lambda p: render_hierarchy(tree_hierarchy(split_pages_hierarchy(p))
                                       ),
        }.get(format)

        if transform:
            titleindex = transform(pages)
        else:
            titleindex = tag.ul(
                tag.li(
                    tag.a(wiki.format_page_name(omitprefix(page)),
                          href=formatter.href.wiki(page))) for page in pages)

        return tag.div(titleindex, class_='titleindex')