Пример #1
0
    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">&nbsp;</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 * '&nbsp; ' + mod * '&nbsp;'
            return (match.group('tag') or '') + '&nbsp;'

        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()
Пример #2
0
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
Пример #3
0
 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
Пример #4
0
    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
Пример #5
0
 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))
Пример #6
0
    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
Пример #7
0
    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'
Пример #8
0
    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'
Пример #9
0
 # 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)
Пример #10
0
 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))
Пример #11
0
 # 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)