def _annotate(self, lines, annotations): buf = StringIO() buf.write('<table class="code"><thead><tr>') annotators = [] for annotator in self.annotators: atype, alabel, adesc = annotator.get_annotation_type() if atype in annotations: buf.write('<th class="%s">%s</th>' % (atype, alabel)) annotators.append(annotator) buf.write('<th class="content"> </th>') buf.write('</tr></thead><tbody>') space_re = re.compile('(?P<spaces> (?: +))|' '^(?P<tag><\w+.*?>)?( )') def htmlify(match): m = match.group('spaces') if m: div, mod = divmod(len(m), 2) return div * ' ' + mod * ' ' return (match.group('tag') or '') + ' ' for num, line in enum(_html_splitlines(lines)): cells = [] for annotator in annotators: cells.append(annotator.annotate_line(num + 1, line)) cells.append('<td>%s</td>\n' % space_re.sub(htmlify, line)) buf.write('<tr>' + '\n'.join(cells) + '</tr>') else: if num == 0: return '' buf.write('</tbody></table>') return buf.getvalue()
def _group_opcodes(opcodes, n=3): """ Python 2.2 doesn't have SequenceMatcher.get_grouped_opcodes(), so let's provide equivalent here. The opcodes parameter can be any iterable or sequence. This function can also be used to generate full-context diffs by passing None for the parameter n. """ # Full context produces all the opcodes if n is None: yield opcodes return # Otherwise we leave at most n lines with the tag 'equal' before and after # every change nn = n + n group = [] for idx, (tag, i1, i2, j1, j2) in enum(opcodes): if idx == 0 and tag == 'equal': # Fixup leading unchanged block i1, j1 = max(i1, i2 - n), max(j1, j2 - n) elif tag == 'equal' and i2 - i1 > nn: group.append((tag, i1, min(i2, i1 + n), j1, min(j2, j1 + n))) yield group group = [] i1, j1 = max(i1, i2 - n), max(j1, j2 - n) group.append((tag, i1, i2, j1 ,j2)) if group and not (len(group) == 1 and group[0][0] == 'equal'): if group[-1][0] == 'equal': # Fixup trailing unchanged block tag, i1, i2, j1, j2 = group[-1] group[-1] = tag, i1, min(i2, i1 + n), j1, min(j2, j1 + n) yield group
def format_props(self): tkt = self.ticket fields = [f for f in tkt.fields if f['type'] != 'textarea' and f['name'] not in ('summary', 'cc')] t = self.modtime or tkt.time_changed width = [0, 0, 0, 0] for i, f in enum([f['name'] for f in fields]): if not tkt.values.has_key(f): continue fval = tkt[f] if fval.find('\n') > -1: continue idx = 2 * (i % 2) if len(f) > width[idx]: width[idx] = len(f) if len(fval) > width[idx + 1]: width[idx + 1] = len(fval) format = ('%%%is: %%-%is | ' % (width[0], width[1]), ' %%%is: %%-%is%s' % (width[2], width[3], CRLF)) i = 1 l = (width[0] + width[1] + 5) sep = l*'-' + '+' + (self.COLS-l)*'-' txt = sep + CRLF big = [] for i, f in enum([f['name'] for f in fields]): if not tkt.values.has_key(f): continue fval = tkt[f] if '\n' in str(fval): big.append((f.capitalize(), fval)) else: txt += format[i % 2] % (f.capitalize(), fval) if not i % 2: txt += '\n' if big: txt += sep for k,v in big: txt += '\n%s:\n%s\n\n' % (k,v) txt += sep return txt
def process_request(self, req): req.perm.assert_permission('ROADMAP_VIEW') req.hdf['title'] = 'Roadmap' showall = req.args.get('show') == 'all' req.hdf['roadmap.showall'] = showall db = self.env.get_db_cnx() milestones = [] for idx, milestone in enum(Milestone.select(self.env, showall)): hdf = milestone_to_hdf(self.env, db, req, milestone) milestones.append(hdf) req.hdf['roadmap.milestones'] = milestones for idx,milestone in enum(milestones): prefix = 'roadmap.milestones.%d.' % idx tickets = get_tickets_for_milestone(self.env, db, milestone['name'], 'owner') req.hdf[prefix + 'stats'] = calc_ticket_stats(tickets) for k, v in get_query_links(self.env, milestone['name']).items(): req.hdf[prefix + 'queries.' + k] = escape(v) milestone['tickets'] = tickets # for the iCalendar view if req.args.get('format') == 'ics': self.render_ics(req, db, milestones) return add_stylesheet(req, 'common/css/roadmap.css') # FIXME should use the 'webcal:' scheme, probably username = None if req.authname and req.authname != 'anonymous': username = req.authname icshref = self.env.href.roadmap(show=req.args.get('show'), user=username, format='ics') add_link(req, 'alternate', icshref, 'iCalendar', 'text/calendar', 'ics') return 'roadmap.cs', None
def add_value(prefix, value): if value is None: return elif value in (True, False): self.hdf.setValue(prefix, str(int(value))) elif isinstance(value, (str, unicode)): self.hdf.setValue(prefix, value) elif isinstance(value, dict): for k in value.keys(): add_value('%s.%s' % (prefix, k), value[k]) else: if hasattr(value, '__iter__') or \ isinstance(value, (list, tuple)): for idx, item in enum(value): add_value('%s.%d' % (prefix, idx), item) else: self.hdf.setValue(prefix, str(value))
def process_request(self, req): req.perm.assert_permission('TIMELINE_VIEW') format = req.args.get('format') maxrows = int(req.args.get('max', 0)) # Parse the from date and adjust the timestamp to the last second of # the day t = time.localtime() if req.args.has_key('from'): try: t = time.strptime(req.args.get('from'), '%x') except: pass fromdate = time.mktime( (t[0], t[1], t[2], 23, 59, 59, t[6], t[7], t[8])) try: daysback = max(0, int(req.args.get('daysback', ''))) except ValueError: daysback = int(self.config.get('timeline', 'default_daysback')) req.hdf['timeline.from'] = format_date(fromdate) req.hdf['timeline.daysback'] = daysback available_filters = [] for event_provider in self.event_providers: available_filters += event_provider.get_timeline_filters(req) filters = [] # check the request or session for enabled filters, or use default for test in (lambda f: req.args.has_key(f[0]), lambda f: req.session.get('timeline.filter.%s' % f[0], '')\ == '1', lambda f: len(f) == 2 or f[2]): if filters: break filters = [f[0] for f in available_filters if test(f)] # save the results of submitting the timeline form to the session if req.args.has_key('update'): for filter in available_filters: key = 'timeline.filter.%s' % filter[0] if req.args.has_key(filter[0]): req.session[key] = '1' elif req.session.has_key(key): del req.session[key] stop = fromdate start = stop - (daysback + 1) * 86400 events = [] for event_provider in self.event_providers: events += event_provider.get_timeline_events( req, start, stop, filters) events.sort(lambda x, y: cmp(y[3], x[3])) if maxrows and len(events) > maxrows: del events[maxrows:] req.hdf['title'] = 'Timeline' # Get the email addresses of all known users email_map = {} for username, name, email in self.env.get_known_users(): if email: email_map[username] = email idx = 0 for kind, href, title, date, author, message in events: event = { 'kind': kind, 'title': title, 'href': escape(href), 'author': escape(author or 'anonymous'), 'date': format_date(date), 'time': format_time(date, '%H:%M'), 'message': message } if format == 'rss': # Strip/escape HTML markup event['title'] = re.sub(r'</?\w+(?: .*?)?>', '', title) event['message'] = escape(message) if author: # For RSS, author must be an email address if author.find('@') != -1: event['author.email'] = escape(author) elif email_map.has_key(author): event['author.email'] = escape(email_map[author]) event['date'] = http_date(date) req.hdf['timeline.events.%s' % idx] = event idx += 1 if format == 'rss': return 'timeline_rss.cs', 'application/rss+xml' add_stylesheet(req, 'common/css/timeline.css') rss_href = self.env.href.timeline([(f, 'on') for f in filters], daysback=90, max=50, format='rss') add_link(req, 'alternate', rss_href, 'RSS Feed', 'application/rss+xml', 'rss') for idx, fltr in enum(available_filters): req.hdf['timeline.filters.%d' % idx] = { 'name': fltr[0], 'label': fltr[1], 'enabled': int(fltr[0] in filters) } return 'timeline.cs', None
def _insert_ticket_data(self, req, db, ticket, reporter_id): """Insert ticket data into the hdf""" req.hdf['ticket'] = ticket.values req.hdf['ticket.id'] = ticket.id req.hdf['ticket.href'] = self.env.href.ticket(ticket.id) for field in TicketSystem(self.env).get_ticket_fields(): if field['type'] in ('radio', 'select'): value = ticket.values.get(field['name']) options = field['options'] if value and not value in options: # Current ticket value must be visible even if its not in the # possible values options.append(value) field['options'] = options name = field['name'] del field['name'] if name in ('summary', 'reporter', 'description', 'type', 'status', 'resolution', 'owner'): field['skip'] = True req.hdf['ticket.fields.' + name] = field req.hdf['ticket.reporter_id'] = reporter_id req.hdf['title'] = '#%d (%s)' % (ticket.id, ticket['summary']) req.hdf['ticket.description.formatted'] = wiki_to_html(ticket['description'], self.env, req, db) req.hdf['ticket.opened'] = util.format_datetime(ticket.time_created) req.hdf['ticket.opened_delta'] = util.pretty_timedelta(ticket.time_created) if ticket.time_changed != ticket.time_created: req.hdf['ticket.lastmod'] = util.format_datetime(ticket.time_changed) req.hdf['ticket.lastmod_delta'] = util.pretty_timedelta(ticket.time_changed) changelog = ticket.get_changelog(db=db) curr_author = None curr_date = 0 changes = [] for date, author, field, old, new in changelog: if date != curr_date or author != curr_author: changes.append({ 'date': util.format_datetime(date), 'author': author, 'fields': {} }) curr_date = date curr_author = author if field == 'comment': changes[-1]['comment'] = wiki_to_html(new, self.env, req, db) elif field == 'description': changes[-1]['fields'][field] = '' else: changes[-1]['fields'][field] = {'old': old, 'new': new} req.hdf['ticket.changes'] = changes # List attached files for idx, attachment in util.enum(Attachment.select(self.env, 'ticket', ticket.id)): hdf = attachment_to_hdf(self.env, db, req, attachment) req.hdf['ticket.attachments.%s' % idx] = hdf if req.perm.has_permission('TICKET_APPEND'): req.hdf['ticket.attach_href'] = self.env.href.attachment('ticket', ticket.id) # Add the possible actions to hdf actions = TicketSystem(self.env).get_available_actions(ticket, req.perm) for action in actions: req.hdf['ticket.actions.' + action] = '1'
def _insert_ticket_data(self, req, db, ticket, reporter_id): """Insert ticket data into the hdf""" req.hdf['ticket'] = dict(zip(ticket.values.keys(), map(lambda x: util.escape(x), ticket.values.values()))) req.hdf['ticket.id'] = ticket.id req.hdf['ticket.href'] = self.env.href.ticket(ticket.id) for field in TicketSystem(self.env).get_ticket_fields(): if field['type'] in ('radio', 'select'): value = ticket.values.get(field['name']) options = field['options'] if value and not value in options: # Current ticket value must be visible even if its not in the # possible values options.append(value) field['options'] = [util.escape(option) for option in options] name = field['name'] del field['name'] if name in ('summary', 'reporter', 'description', 'type', 'status', 'resolution', 'owner'): field['skip'] = True req.hdf['ticket.fields.' + name] = field req.hdf['ticket.reporter_id'] = util.escape(reporter_id) req.hdf['title'] = '#%d (%s)' % (ticket.id, util.escape(ticket['summary'])) req.hdf['ticket.description.formatted'] = wiki_to_html(ticket['description'], self.env, req, db) req.hdf['ticket.opened'] = util.format_datetime(ticket.time_created) req.hdf['ticket.opened_delta'] = util.pretty_timedelta(ticket.time_created) if ticket.time_changed != ticket.time_created: req.hdf['ticket.lastmod'] = util.format_datetime(ticket.time_changed) req.hdf['ticket.lastmod_delta'] = util.pretty_timedelta(ticket.time_changed) changelog = ticket.get_changelog(db=db) curr_author = None curr_date = 0 changes = [] for date, author, field, old, new in changelog: if date != curr_date or author != curr_author: changes.append({ 'date': util.format_datetime(date), 'author': util.escape(author), 'fields': {} }) curr_date = date curr_author = author if field == 'comment': changes[-1]['comment'] = wiki_to_html(new, self.env, req, db) elif field == 'description': changes[-1]['fields'][field] = '' else: changes[-1]['fields'][field] = {'old': util.escape(old), 'new': util.escape(new)} req.hdf['ticket.changes'] = changes # List attached files for idx, attachment in util.enum(Attachment.select(self.env, 'ticket', ticket.id)): hdf = attachment_to_hdf(self.env, db, req, attachment) req.hdf['ticket.attachments.%s' % idx] = hdf if req.perm.has_permission('TICKET_APPEND'): req.hdf['ticket.attach_href'] = self.env.href.attachment('ticket', ticket.id) # Add the possible actions to hdf actions = TicketSystem(self.env).get_available_actions(ticket, req.perm) for action in actions: req.hdf['ticket.actions.' + action] = '1'
# Special columns begin and end with '__' if column.startswith('__') and column.endswith('__'): value['hidden'] = 1 elif (column[0] == '_' and column[-1] == '_'): value['fullrow'] = 1 column = column[1:-1] req.hdf[prefix + '.breakrow'] = 1 elif column[-1] == '_': value['breakrow'] = 1 value['breakafter'] = 1 column = column[:-1] elif column[0] == '_': value['hidehtml'] = 1 column = column[1:] if column in ['id', 'ticket', '#', 'summary']: id_cols = [idx for idx, col in util.enum(cols) if col[0] in ('ticket', 'id')] if id_cols: id_val = row[id_cols[0]] value['ticket_href'] = self.env.href.ticket(id_val) elif column == 'description': value['parsed'] = wiki_to_html(cell, self.env, req, db) elif column == 'reporter' and cell.find('@') != -1: value['rss'] = util.escape(cell) elif column == 'report': value['report_href'] = self.env.href.report(cell) elif column in ['time', 'date','changetime', 'created', 'modified']: value['date'] = util.format_date(cell) value['time'] = util.format_time(cell) value['datetime'] = util.format_datetime(cell) value['gmt'] = util.http_date(cell)
if column.startswith('__') and column.endswith('__'): value['hidden'] = 1 elif (column[0] == '_' and column[-1] == '_'): value['fullrow'] = 1 column = column[1:-1] req.hdf[prefix + '.breakrow'] = 1 elif column[-1] == '_': value['breakrow'] = 1 value['breakafter'] = 1 column = column[:-1] elif column[0] == '_': value['hidehtml'] = 1 column = column[1:] if column in ['id', 'ticket', '#', 'summary']: id_cols = [ idx for idx, col in util.enum(cols) if col[0] in ('ticket', 'id') ] if id_cols: id_val = row[id_cols[0]] value['ticket_href'] = self.env.href.ticket(id_val) elif column == 'description': value['parsed'] = wiki_to_html(cell, self.env, req, db) elif column == 'reporter' and cell.find('@') != -1: value['rss'] = util.escape(cell) elif column == 'report': value['report_href'] = self.env.href.report(cell) elif column in [ 'time', 'date', 'changetime', 'created', 'modified' ]: t = time.localtime(int(cell))
# Special columns begin and end with '__' if column.startswith('__') and column.endswith('__'): value['hidden'] = 1 elif (column[0] == '_' and column[-1] == '_'): value['fullrow'] = 1 column = column[1:-1] req.hdf[prefix + '.breakrow'] = 1 elif column[-1] == '_': value['breakrow'] = 1 value['breakafter'] = 1 column = column[:-1] elif column[0] == '_': value['hidehtml'] = 1 column = column[1:] if column in ['id', 'ticket', '#', 'summary']: id_cols = [idx for idx, col in util.enum(cols) if col[0] in ('ticket', 'id')] if id_cols: id_val = row[id_cols[0]] value['ticket_href'] = self.env.href.autotrac("ticket/" + str(id_val)) elif column == 'description': value['parsed'] = wiki_to_html(cell, self.env, req, db) elif column == 'reporter' and cell.find('@') != -1: value['rss'] = cell elif column == 'report': value['report_href'] = self.env.href.report(cell) elif column in ['time', 'date','changetime', 'created', 'modified']: value['date'] = util.format_date(cell) value['time'] = util.format_time(cell) value['datetime'] = util.format_datetime(cell) value['gmt'] = util.http_date(cell)