Beispiel #1
0
 def __iter__(self):
     if self.this_milestone is not None:  # for /milestone/xxx
         milestone = self.this_milestone
     else:
         milestone = self.buffer.events[3][1]
     if not milestone in self.hours.keys():
         return iter([])
     hours = self.hours[milestone]
     estimated_hours = hours['estimatedhours']
     total_hours = hours['totalhours']
     if not (estimated_hours or total_hours):
         return iter([])
     items = []
     if estimated_hours:
         items.append(tag.dt("Estimated Hours:"))
         items.append(tag.dd(str(estimated_hours)))
     date = hours['date']
     link = self.href("hours",
                      milestone=milestone,
                      from_year=date.year,
                      from_month=date.month,
                      from_day=date.day)
     items.append(tag.dt(tag.a("Total Hours:", href=link)))
     items.append(tag.dd(tag.a(hours_format % total_hours, href=link)))
     return iter(tag.dl(*items))
Beispiel #2
0
    def process_request(self, req):
        if req.path_info == '/mindmap/status':
            db = self.env.get_db_cnx()
            cursor = db.cursor()
            try:
                cursor.execute('SELECT hash,content FROM mindmapcache')
                content = tag.html(
                    tag.body(
                        tag.dd([[
                            tag.dt(tag.a(k, href=req.href.mindmap(k + '.mm'))),
                            tag.dd(tag.pre(v))
                        ] for k, v in cursor.fetchall()])))
            except Exception, e:
                content = tag.html(
                    tag.body(tag.strong("DB Error: " + unicode(e))))
            html = content.generate().render("xhtml")
            req.send_response(200)
            req.send_header('Cache-control', 'must-revalidate')
            req.send_header('Content-Type', 'text/html;charset=utf-8')
            req.send_header('Content-Length', len(html))
            req.end_headers()

            if req.method != 'HEAD':
                req.write(html)
            raise RequestDone
Beispiel #3
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        add_stylesheet(req, 'hacks/css/trachacks.css')

        tag_system = TagSystem(self.env)
        releases = natural_sort([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki release')])

        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        dl = builder.dl(class_='tracreleasesmacro')
        for release in releases:
            page = WikiPage(self.env, release)
            match = self.title_extract.search(page.text)
            if match:
                rel_title = '%s' % match.group(1).strip()
            else:
                rel_title = '%s' % release

            dl(builder.dt(link(Resource('wiki', release))))
            dl(builder.dd(wiki_to_html(rel_title, self.env, req)))

        return dl
Beispiel #4
0
 def _display_list(self, tickets, cols, req):
     '''Returns a list formatted '''
     return tag.div(
         tag.dl([(tag.dt(self._format_ticket_link(
             ticket, req)), tag.dd(self._format_ticket_label(ticket, cols)))
                 for ticket in tickets],
                class_='wiki compact'))
Beispiel #5
0
    def expand_macro(self, formatter, name, args):
        req = formatter.req
        add_stylesheet(req, 'hacks/css/trachacks.css')

        tag_system = TagSystem(self.env)

        categories = natural_sort([r.id for r, _ in
                                 tag_system.query(req, 'realm:wiki type')])

        def link(resource):
            return render_resource_link(self.env, formatter.context,
                                        resource, 'compact')

        dl = builder.dl(class_='hacktypesmacro')
        for category in categories:
            page = WikiPage(self.env, category)
            match = self.title_extract.search(page.text)
            if match:
                cat_title = '%s' % match.group(1).strip()
                cat_body = self.title_extract.sub('', page.text, 1)
            else:
                cat_title = '%s' % category
                cat_body = page.text
            cat_body = self.self_extract.sub('', cat_body).strip()
            dl(builder.dt(link(Resource('wiki', category))))
            dl(builder.dd(wiki_to_html(cat_body, self.env, req)))

        return dl
Beispiel #6
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        format = kwargs.get('format', 'compact')
        glob = kwargs.get('glob', '*')
        order = kwargs.get('order')
        desc = as_bool(kwargs.get('desc', 0))

        rm = RepositoryManager(self.env)
        all_repos = dict(rdata for rdata in rm.get_all_repositories().items()
                         if fnmatchcase(rdata[0], glob))

        if format == 'table':
            repo = self._render_repository_index(formatter.context, all_repos,
                                                 order, desc)

            add_stylesheet(formatter.req, 'common/css/browser.css')
            wiki_format_messages = self.config['changeset'] \
                                       .getbool('wiki_format_messages')
            data = {'repo': repo, 'order': order, 'desc': 1 if desc else None,
                    'reponame': None, 'path': '/', 'stickyrev': None,
                    'wiki_format_messages': wiki_format_messages}
            from trac.web.chrome import Chrome
            return Chrome(self.env).render_template(
                    formatter.req, 'repository_index.html', data, None,
                    fragment=True)

        def get_repository(reponame):
            try:
                return rm.get_repository(reponame)
            except TracError:
                return

        all_repos = [(reponame, get_repository(reponame))
                     for reponame in all_repos]
        all_repos = sorted(((reponame, repos) for reponame, repos in all_repos
                            if repos
                            and not as_bool(repos.params.get('hidden'))
                            and repos.is_viewable(formatter.perm)),
                           reverse=desc)

        def repolink(reponame, repos):
            label = reponame or _('(default)')
            return Markup(tag.a(label,
                          title=_('View repository %(repo)s', repo=label),
                          href=formatter.href.browser(repos.reponame or None)))

        if format == 'list':
            return tag.dl([
                tag(tag.dt(repolink(reponame, repos)),
                    tag.dd(repos.params.get('description')))
                for reponame, repos in all_repos])
        else: # compact
            return Markup(', ').join([repolink(reponame, repos)
                                      for reponame, repos in all_repos])
    def __iter__(self):

        """
        Return a <dd><a> link to be inserted at the end of the stats block of
        the milstone summary.
        """
        milestoneName = u"".join(e[1] for e in self.buffer.events)
        title = "Go to TracMetrix for %s" % milestoneName
        href = self.baseHref.mdashboard(milestoneName)

        return iter(tag.dd('[', tag.a('TracMetrix', href=href, title=title), ']'))
Beispiel #8
0
    def __iter__(self):
        """
        Return a <dd><a> link to be inserted at the end of the stats block of
        the milstone summary.
        """
        milestoneName = u"".join(e[1] for e in self.buffer.events)
        title = "Go to TracMetrix for %s" % milestoneName
        href = self.baseHref.mdashboard(milestoneName)

        return iter(
            tag.dd('[', tag.a('TracMetrix', href=href, title=title), ']'))
Beispiel #9
0
    def process_request(self, req):
        if req.path_info == '/mindmap/status':
          db = self.env.get_db_cnx()
          cursor = db.cursor()
          try:
              cursor.execute('SELECT hash,content FROM mindmapcache')
              content = tag.html(tag.body(tag.dd(
                  [ [tag.dt(tag.a(k,href=req.href.mindmap(k + '.mm'))),tag.dd(tag.pre(v))] for k,v in cursor.fetchall()]
                )))
          except Exception, e:
              content = tag.html(tag.body(tag.strong("DB Error: " + unicode(e))))
          html = content.generate().render("xhtml")
          req.send_response(200)
          req.send_header('Cache-control', 'must-revalidate')
          req.send_header('Content-Type', 'text/html;charset=utf-8')
          req.send_header('Content-Length', len(html))
          req.end_headers()

          if req.method != 'HEAD':
             req.write(html)
          raise RequestDone
Beispiel #10
0
 def _review_attrs(self, req, changeset):
     review = Review.get(self.env.get_db_cnx(),changeset.rev, self.author(changeset))
     if req.perm.has_permission('CODE_REVIEW'):
         comment = tag.textarea(review.comment, name="review_comment", rows=6, cols=100 )
         if review.status=="ACCEPTED":
             checkbox = tag.input(type="checkbox", name="review_passed", checked="true")
         else:
             checkbox = tag.input(type="checkbox", name="review_passed")
         submit = tag.input(type="hidden", name="review_rev", value=changeset.rev)+ \
             tag.input(type="hidden", name="review_author", value=self.author(changeset))+ \
             tag.input(type="submit", name="review", value="Review")
     else:
         comment = tag.span(review.comment)
         checkbox = tag.span(review.status)
         submit = "";
     return tag.form(
                     tag.dt("Reviewer:",class_="property author"),
                     tag.dd( req.authname,class_="author"),
                     tag.dt("Comment:",class_="property author"),
                     tag.dd( comment ),       
                     tag.dt("Passed:",class_="property author"),
                     tag.dd(checkbox+submit)
                     )       
Beispiel #11
0
 def __iter__(self):
     if self.this_milestone is not None: # for /milestone/xxx
         milestone = self.this_milestone
     else:
         milestone = self.buffer.events[3][1]
     if not milestone in self.hours.keys(): 
         return iter([]) 
     hours = self.hours[milestone]
     estimatedhours = hours['estimatedhours']
     totalhours = hours['totalhours']
     if not (estimatedhours or totalhours):
         return iter([])
     items = []
     if estimatedhours:
         items.append(tag.dt("Estimated Hours:"))
         items.append(tag.dd(str(estimatedhours)))
     date = hours['date']
     link = self.href("hours", milestone=milestone, 
                      from_year=date.year,
                      from_month=date.month,
                      from_day=date.day)
     items.append(tag.dt(tag.a("Total Hours:", href=link)))
     items.append(tag.dd(tag.a(hours_format % totalhours, href=link)))
     return iter(tag.dl(*items))
Beispiel #12
0
    def changelog(self, req, stream, data):
        changes = data['changes']
        url = self.url(data['location'])
        stream |= Transformer("//dt[@class='property files']").before(
            tag.dt('URL:', **{'class': "property url"}) + tag.dd(
                tag.a(
                    url, **{
                        'class': "url",
                        'href': url,
                        'title': self.link_title
                    })))

        # make the header link to the canonical location if just at '/changeset'
        if req.path_info.strip('/') == 'changeset':
            stream |= Transformer("//h1").wrap(
                tag.a(None, href=req.href('changeset', data['new_rev'])))

        return stream
Beispiel #13
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).
                """)))
            )
Beispiel #14
0
 def _display_list(self, tickets, cols, req):
     '''Returns a list formatted '''
     return tag.div(tag.dl([(tag.dt(self._format_ticket_link(ticket, req)),
                             tag.dd(self._format_ticket_label(ticket, cols)))
                            for ticket in tickets],
                           class_='wiki compact'))
Beispiel #15
0
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        query_string, kwargs, format = self.parse_args(content)
        if query_string:
            query_string += '&'
        query_string += '&'.join('%s=%s' % item
                                 for item in kwargs.iteritems())

        env = ProductEnvironment.lookup_global_env(self.env)
        query = ProductQuery.from_string(env, query_string)

        if format == 'count':
            cnt = query.count(req)
            return tag.span(cnt, title='%d tickets for which %s' %
                            (cnt, query_string), class_='query_count')

        tickets = query.execute(req)

        if format == 'table':
            data = query.template_data(formatter.context, tickets,
                                       req=formatter.context.req)

            add_stylesheet(req, 'common/css/report.css')

            return Chrome(env).render_template(
                req, 'query_results.html', data, None, fragment=True)

        if format == 'progress':
            from trac.ticket.roadmap import (RoadmapModule,
                                             apply_ticket_permissions,
                                             get_ticket_stats,
                                             grouped_stats_data)

            add_stylesheet(req, 'common/css/roadmap.css')

            def query_href(extra_args, group_value = None):
                q = ProductQuery.from_string(env, query_string)
                if q.group:
                    extra_args[q.group] = group_value
                    q.group = None
                for constraint in q.constraints:
                    constraint.update(extra_args)
                if not q.constraints:
                    q.constraints.append(extra_args)
                return q.get_href(formatter.context)
            chrome = Chrome(env)
            tickets = apply_ticket_permissions(env, req, tickets)
            stats_provider = RoadmapModule(env).stats_provider
            by = query.group
            if not by:
                stat = get_ticket_stats(stats_provider, tickets)
                data = {
                    'stats': stat,
                    'stats_href': query_href(stat.qry_args),
                    'interval_hrefs': [query_href(interval['qry_args'])
                                       for interval in stat.intervals],
                    'legend': True,
                }
                return tag.div(
                    chrome.render_template(req, 'progress_bar.html', data,
                                           None, fragment=True),
                    class_='trac-progress')

            def per_group_stats_data(gstat, group_name):
                return {
                    'stats': gstat,
                    'stats_href': query_href(gstat.qry_args,  group_name),
                    'interval_hrefs': [query_href(interval['qry_args'],
                                                  group_name)
                                       for interval in gstat.intervals],
                    'percent': '%d / %d' % (gstat.done_count,
                                            gstat.count),
                    'legend': False,
                }

            groups = grouped_stats_data(env, stats_provider, tickets, by,
                                        per_group_stats_data)
            data = {
                'groups': groups, 'grouped_by': by,
                'summary': _("Ticket completion status for each %(group)s",
                             group=by),
            }
            return tag.div(
                chrome.render_template(req, 'progress_bar_grouped.html', data,
                                       None, fragment=True),
                class_='trac-groupprogress')

        # Formats above had their own permission checks, here we need to
        # do it explicitly:

        tickets = [t for t in tickets
                   if 'TICKET_VIEW' in req.perm('ticket', t['id'])]

        if not tickets:
            return tag.span(_("No results"), class_='query_no_results')

        # Cache resolved href targets
        hrefcache = {}

        def ticket_anchor(ticket):
            try:
                pvalue = ticket.get('product') or GLOBAL_PRODUCT
                envhref = hrefcache[pvalue]
            except KeyError:
                try:
                    env = lookup_product_env(self.env, prefix= pvalue,
                                             name=pvalue)
                except LookupError:
                    return tag.a('#%s' % ticket['id'], 
                                 class_='missing product')
                hrefcache[pvalue] = envhref = resolve_product_href(
                         to_env=env, at_env=self.env)
            return tag.a('#%s' % ticket['id'],
                         class_=ticket['status'],
                         href=envhref.ticket(int(ticket['id'])),
                         title=shorten_line(ticket['summary']))

        def ticket_groups():
            groups = []
            for v, g in groupby(tickets, lambda t: t[query.group]):
                q = ProductQuery.from_string(env, query_string)
                # produce the hint for the group
                q.group = q.groupdesc = None
                order = q.order
                q.order = None
                title = _("%(groupvalue)s %(groupname)s tickets matching "
                          "%(query)s", groupvalue=v, groupname=query.group,
                          query=q.to_string())
                # produce the href for the query corresponding to the group
                for constraint in q.constraints:
                    constraint[str(query.group)] = v
                q.order = order
                href = q.get_href(formatter.context)
                groups.append((v, [t for t in g], href, title))
            return groups

        if format == 'compact':
            if query.group:
                groups = [(v, ' ',
                           tag.a('#%s' % u',\u200b'.join(str(t['id'])
                                                         for t in g),
                                 href=href, class_='query', title=title))
                          for v, g, href, title in ticket_groups()]
                return tag(groups[0], [(', ', g) for g in groups[1:]])
            else:
                alist = [ticket_anchor(ticket) for ticket in tickets]
                return tag.span(alist[0], *[(', ', a) for a in alist[1:]])
        else:
            if query.group:
                return tag.div(
                    [(tag.p(tag_('%(groupvalue)s %(groupname)s tickets:',
                                 groupvalue=tag.a(v, href=href, class_='query',
                                                  title=title),
                                 groupname=query.group)),
                      tag.dl([(tag.dt(ticket_anchor(t)),
                               tag.dd(t['summary'])) for t in g],
                             class_='wiki compact'))
                     for v, g, href, title in ticket_groups()])
            else:
                return tag.div(tag.dl([(tag.dt(ticket_anchor(ticket)),
                                        tag.dd(ticket['summary']))
                                       for ticket in tickets],
                                      class_='wiki compact'))
Beispiel #16
0
    def expand_macro(self, formatter, name, content):
        req = formatter.req
        query_string = ''
        argv, kwargs = parse_args(content, strict=False)
        if len(argv) > 0 and not 'format' in kwargs: # 0.10 compatibility hack
            kwargs['format'] = argv[0]

        if 'order' not in kwargs:
            kwargs['order'] = 'id'
        if 'max' not in kwargs:
            kwargs['max'] = '0' # unlimited by default

        format = kwargs.pop('format', 'list').strip().lower()
        if format in ('list', 'compact'): # we need 'status' and 'summary'
            kwargs['col'] = '|'.join(['status', 'summary', 
                                      kwargs.get('col', '')])

        query_string = '&'.join(['%s=%s' % item
                                 for item in kwargs.iteritems()])
        query = Query.from_string(self.env, query_string)

        if format == 'count':
            cnt = query.count(req)
            return tag.span(cnt, title='%d tickets for which %s' %
                            (cnt, query_string), class_='query_count')
        
        tickets = query.execute(req)

        if format == 'table':
            data = query.template_data(formatter.context, tickets)

            add_stylesheet(req, 'common/css/report.css')
            
            return Chrome(self.env).render_template(
                req, 'query_results.html', data, None, fragment=True)

        # 'table' format had its own permission checks, here we need to
        # do it explicitly:

        tickets = [t for t in tickets 
                   if 'TICKET_VIEW' in req.perm('ticket', t['id'])]

        if not tickets:
            return tag.span(_("No results"), class_='query_no_results')

        def ticket_anchor(ticket):
            return tag.a('#%s' % ticket['id'],
                         class_=ticket['status'],
                         href=req.href.ticket(int(ticket['id'])),
                         title=shorten_line(ticket['summary']))

        def ticket_groups():
            groups = []
            for v, g in groupby(tickets, lambda t: t[query.group]):
                q = Query.from_string(self.env, query_string)
                # produce the hint for the group
                q.group = q.groupdesc = None
                order = q.order
                q.order = None
                title = _("%(groupvalue)s %(groupname)s tickets matching "
                          "%(query)s", groupvalue=v, groupname=query.group,
                          query=q.to_string())
                # produce the href for the query corresponding to the group
                q.constraints[str(query.group)] = v
                q.order = order
                href = q.get_href(formatter.context)
                groups.append((v, [t for t in g], href, title))
            return groups

        if format == 'compact':
            if query.group:
                groups = [(v, ' ', 
                           tag.a('#%s' % ','.join([str(t['id']) for t in g]),
                                 href=href, class_='query', title=title))
                          for v, g, href, title in ticket_groups()]
                return tag(groups[0], [(', ', g) for g in groups[1:]])
            else:
                alist = [ticket_anchor(ticket) for ticket in tickets]
                return tag.span(alist[0], *[(', ', a) for a in alist[1:]])
        else:
            if query.group:
                return tag.div(
                    [(tag.p(tag.a(query.group, ' ', v, href=href,
                                  class_='query', title=title)),
                      tag.dl([(tag.dt(ticket_anchor(t)),
                               tag.dd(t['summary'])) for t in g],
                             class_='wiki compact'))
                     for v, g, href, title in ticket_groups()])
            else:
                return tag.div(tag.dl([(tag.dt(ticket_anchor(ticket)),
                                        tag.dd(ticket['summary']))
                                       for ticket in tickets],
                                      class_='wiki compact'))
Beispiel #17
0
    def changelog(self, req, stream, data):
        changes = data['changes']
        url = self.url(data['location'])
        stream |= Transformer("//dt[@class='property files']").before(tag.dt('URL:', **{'class': "property url"}) + tag.dd(tag.a(url, **{'class': "url", 'href': url, 'title': self.link_title})))

        # make the header link to the canonical location if just at '/changeset'
        if req.path_info.strip('/') == 'changeset':
            stream |= Transformer("//h1").wrap(tag.a(None, href=req.href('changeset', data['new_rev'])))

        return stream
Beispiel #18
0
    def expand_macro(self, formatter, name, text):

        req = formatter.req
        context = formatter.context
        resource = context.resource

        # Process the arguments.
        args, kwargs = parse_args(text)

        if 'ticket' not in kwargs and len(args)>0:
            kwargs['ticket'] = args[0]
        elif 'ticket' not in kwargs and not len(args):
            kwargs['ticket'] = str( WikiPage(self.env, resource).name )   # This seems to provide the correct ticket id.

        try:
            kwargs['ticket'] = int( kwargs.get('ticket').lstrip('#') )
        except ValueError:
            raise TracError('No ticket id supplied or it is not valid integer value.')

        ticket = Ticket( self.env, kwargs['ticket'] )

        self.childtickets = {}    # { parent -> children } - 1:n

        db = self.env.get_db_cnx() 
        cursor = db.cursor() 
        cursor.execute("SELECT ticket,value FROM ticket_custom WHERE name='parent'")
        for child,parent in cursor.fetchall():
            if parent and re.match('#\d+',parent):
                self.childtickets.setdefault( int(parent.lstrip('#')), [] ).append(child)

        # First ticket has no indentation.
        ticket['indent'] = '0'

        # List of tickets that will be displayed.
        if as_bool( kwargs.get('root') ):
            self.tickets = [ ticket, ]
        else:
            self.tickets = []

        # Do this neater!
        self.indent_children(ticket)

        def ticket_anchor(t):
            return tag.a( '#%s' % t.id, class_=t['status'], href=req.href.ticket(int(t.id)), title="%s : %s : %s" % (t['type'],t['owner'],t['status']))

        def_list = tag.dl(
                [( tag.dt(ticket_anchor(t),style='padding-left: %spx;' % (t['indent']*20)), tag.dd("%s" % t['summary'])) for t in self.tickets],
                class_='wiki compact',
                )

        if as_bool( kwargs.get('border') ):
            return tag.fieldset(
                    def_list,
                    tag.legend('Ticket Child Tree (#%s)' % ticket.id),
                    class_='description',
                    )
        else:
            return tag.div(def_list)
Beispiel #19
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        format = kwargs.get("format", "compact")
        glob = kwargs.get("glob", "*")
        order = kwargs.get("order")
        desc = as_bool(kwargs.get("desc", 0))

        rm = RepositoryManager(self.env)
        all_repos = dict(rdata for rdata in rm.get_all_repositories().items() if fnmatchcase(rdata[0], glob))

        if format == "table":
            repo = self._render_repository_index(formatter.context, all_repos, order, desc)

            add_stylesheet(formatter.req, "common/css/browser.css")
            wiki_format_messages = self.config["changeset"].getbool("wiki_format_messages")
            data = {
                "repo": repo,
                "order": order,
                "desc": 1 if desc else None,
                "reponame": None,
                "path": "/",
                "stickyrev": None,
                "wiki_format_messages": wiki_format_messages,
            }
            from trac.web.chrome import Chrome

            return Chrome(self.env).render_template(formatter.req, "repository_index.html", data, None, fragment=True)

        def get_repository(reponame):
            try:
                return rm.get_repository(reponame)
            except TracError:
                return

        all_repos = [(reponame, get_repository(reponame)) for reponame in all_repos]
        all_repos = sorted(
            (
                (reponame, repos)
                for reponame, repos in all_repos
                if repos and not as_bool(repos.params.get("hidden")) and repos.is_viewable(formatter.perm)
            ),
            reverse=desc,
        )

        def repolink(reponame, repos):
            label = reponame or _("(default)")
            return Markup(
                tag.a(
                    label,
                    title=_("View repository %(repo)s", repo=label),
                    href=formatter.href.browser(repos.reponame or None),
                )
            )

        if format == "list":
            return tag.dl(
                [
                    tag(tag.dt(repolink(reponame, repos)), tag.dd(repos.params.get("description")))
                    for reponame, repos in all_repos
                ]
            )
        else:  # compact
            return Markup(", ").join([repolink(reponame, repos) for reponame, repos in all_repos])