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))
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
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
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'))
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
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), ']'))
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), ']'))
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
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) )
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))
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
def expand_macro(self, formatter, name, content): def wikify(text): return format_to_oneliner(self.env, formatter.context, text) return tag.div( tag.p(wikify(_(""" The following tokens can be used in the `PageTemplates/MyPage` or `PageTemplates/MyPage/<user>` wiki pages: """))), tag.dl([(tag.dt(tag.tt(token)), tag.dd(wikify(gettext(description)))) for token, description in sorted(MyPageModule(self.env).tokens.values())]), tag.p(wikify(_(""" Note that you can also use the `[[MyPageNav]]` wiki macro for creating dynamic links to other ''MyPage'' pages (use `[[MyPageNav?]]` to get help on this macro). """))) )
def _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'))
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'))
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'))
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
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)
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])