Пример #1
0
    def render(self):
        self.perm.assert_permission(perm.TICKET_VIEW)

        action = self.args.get('action', 'view')
        preview = self.args.has_key('preview')

        if not self.args.has_key('id'):
            self.req.redirect(self.env.href.wiki())

        id = int(self.args.get('id'))

        if not preview \
               and action in ['leave', 'accept', 'reopen', 'resolve', 'reassign']:
            self.save_changes(id)

        ticket = Ticket(self.db, id)
        reporter_id = util.get_reporter_id(self.req)

        if preview:
            # Use user supplied values
            for field in Ticket.std_fields:
                if self.args.has_key(field) and field != 'reporter':
                    ticket[field] = self.args.get(field)
            self.req.hdf.setValue('ticket.action', action)
            reporter_id = self.args.get('author')
            comment = self.args.get('comment')
            if comment:
                self.req.hdf.setValue('ticket.comment', comment)
                # Wiki format a preview of comment
                self.req.hdf.setValue(
                    'ticket.comment_preview',
                    wiki_to_html(comment, self.req.hdf, self.env, self.db))

        self.insert_ticket_data(self.req.hdf, id, ticket, reporter_id)

        cursor = self.db.cursor()
        cursor.execute("SELECT max(id) FROM ticket")
        row = cursor.fetchone()
        if row:
            max_id = int(row[0])
            if id > 1:
                self.add_link('first', self.env.href.ticket(1), 'Ticket #1')
                self.add_link('prev', self.env.href.ticket(id - 1),
                              'Ticket #%d' % (id - 1))
            if id < max_id:
                self.add_link('next', self.env.href.ticket(id + 1),
                              'Ticket #%d' % (id + 1))
                self.add_link('last', self.env.href.ticket(max_id),
                              'Ticket #%d' % (max_id))
Пример #2
0
    def render(self):
        self.perm.assert_permission(perm.CHANGESET_VIEW)

        self.add_link('alternate', '?format=diff', 'Unified Diff',
                      'text/plain', 'diff')

        youngest_rev = svn.fs.youngest_rev(self.fs_ptr, self.pool)
        if self.args.has_key('rev'):
            self.rev = int(self.args.get('rev'))
        else:
            self.rev = youngest_rev

        Diff.get_options(self.env, self.req, self.args, 1)
        if self.args.has_key('update'):
            self.req.redirect(self.env.href.changeset(self.rev))

        change_info = self.get_change_info(self.rev)
        changeset_info = self.get_changeset_info(self.rev)

        self.req.hdf.setValue('title', '[%d] (changeset)' % self.rev)
        self.req.hdf.setValue(
            'changeset.time',
            time.asctime(time.localtime(int(changeset_info['time']))))
        author = changeset_info['author'] or 'anonymous'
        self.req.hdf.setValue('changeset.author', util.escape(author))
        message = changeset_info['message'] or '--'
        self.req.hdf.setValue(
            'changeset.message',
            wiki_to_html(util.wiki_escape_newline(message), self.req.hdf,
                         self.env, self.db))
        self.req.hdf.setValue('changeset.revision', str(self.rev))
        util.add_dictlist_to_hdf(change_info, self.req.hdf,
                                 'changeset.changes')

        self.req.hdf.setValue('changeset.href',
                              self.env.href.changeset(self.rev))
        if self.rev > 1:
            self.add_link('first', self.env.href.changeset(1), 'Changeset 1')
            self.add_link('prev', self.env.href.changeset(self.rev - 1),
                          'Changeset %d' % (self.rev - 1))
        if self.rev < youngest_rev:
            self.add_link('next', self.env.href.changeset(self.rev + 1),
                          'Changeset %d' % (self.rev + 1))
            self.add_link('last', self.env.href.changeset(youngest_rev),
                          'Changeset %d' % youngest_rev)
Пример #3
0
 def get_milestone(self, name):
     cursor = self.db.cursor()
     cursor.execute(
         "SELECT name, time, descr FROM milestone "
         "WHERE name = %s ORDER BY time, name", name)
     row = cursor.fetchone()
     cursor.close()
     if not row:
         raise TracError('Milestone %s does not exist.' % name,
                         'Invalid Milestone Number')
     milestone = {'name': row['name']}
     descr = row['descr']
     if descr:
         milestone['descr_source'] = descr
         milestone['descr'] = wiki_to_html(descr, self.req.hdf, self.env,
                                           self.db)
     t = row['time'] and int(row['time'])
     if t > 0:
         milestone['date'] = time.strftime('%x', time.localtime(t))
     return milestone
Пример #4
0
    def render(self):
        self.perm.assert_permission(perm.TICKET_CREATE)

        if self.args.has_key('create'):
            self.create_ticket()

        ticket = Ticket()
        ticket.populate(self.args)
        ticket.setdefault('component',
                          self.env.get_config('ticket', 'default_component'))
        ticket.setdefault('milestone',
                          self.env.get_config('ticket', 'default_milestone'))
        ticket.setdefault('priority',
                          self.env.get_config('ticket', 'default_priority'))
        ticket.setdefault('severity',
                          self.env.get_config('ticket', 'default_severity'))
        ticket.setdefault('version',
                          self.env.get_config('ticket', 'default_version'))
        ticket.setdefault('reporter', util.get_reporter_id(self.req))

        if ticket.has_key('description'):
            self.req.hdf.setValue(
                'newticket.description_preview',
                wiki_to_html(ticket['description'], self.req.hdf, self.env,
                             self.db))

        self.req.hdf.setValue('title', 'New Ticket')
        evals = util.mydict(
            zip(ticket.keys(), map(lambda x: util.escape(x), ticket.values())))
        util.add_to_hdf(evals, self.req.hdf, 'newticket')

        util.sql_to_hdf(self.db, 'SELECT name FROM component ORDER BY name',
                        self.req.hdf, 'newticket.components')
        util.sql_to_hdf(self.db, 'SELECT name FROM milestone ORDER BY name',
                        self.req.hdf, 'newticket.milestones')
        util.sql_to_hdf(self.db, 'SELECT name FROM version ORDER BY name',
                        self.req.hdf, 'newticket.versions')

        insert_custom_fields(self.env, self.req.hdf, ticket)
Пример #5
0
class Report(Module):
    template_name = 'report.cs'
    template_rss_name = 'report_rss.cs'
    template_csv_name = 'report_csv.cs'

    def sql_sub_vars(self, sql, args):
        m = re.search(dynvars_re, sql)
        if not m:
            return sql
        aname = m.group()[1:]
        try:
            arg = args[aname]
        except KeyError:
            raise util.TracError("Dynamic variable '$%s' not defined." % aname)
        self.req.hdf.setValue('report.var.' + aname, arg)
        sql = m.string[:m.start()] + arg + m.string[m.end():]
        return self.sql_sub_vars(sql, args)

    def get_info(self, id, args):
        cursor = self.db.cursor()

        if id == -1:
            # If no particular report was requested, display
            # a list of available reports instead
            title = 'Available Reports'
            sql = 'SELECT id AS report, title FROM report ORDER BY report'
            description = 'This is a list of reports available.'
        else:
            cursor.execute(
                'SELECT title, sql, description from report '
                ' WHERE id=%s', id)
            row = cursor.fetchone()
            if not row:
                raise util.TracError('Report %d does not exist.' % id,
                                     'Invalid Report Number')
            title = row[0] or ''
            sql = row[1]
            description = row[2] or ''

        return [title, description, sql]

    def create_report(self, title, description, sql):
        self.perm.assert_permission(perm.REPORT_CREATE)

        cursor = self.db.cursor()
        cursor.execute(
            'INSERT INTO report (id, title, sql, description)'
            'VALUES (NULL, %s, %s, %s)', title, sql, description)
        id = self.db.db.sqlite_last_insert_rowid()
        self.db.commit()
        self.req.redirect(self.env.href.report(id))

    def delete_report(self, id):
        self.perm.assert_permission(perm.REPORT_DELETE)

        if not self.args.has_key('cancel'):
            cursor = self.db.cursor()
            cursor.execute('DELETE FROM report WHERE id=%s', id)
            self.db.commit()
            self.req.redirect(self.env.href.report())
        else:
            self.req.redirect(self.env.href.report(id))

    def execute_report(self, sql, args):
        cursor = self.db.cursor()
        sql = self.sql_sub_vars(sql, args)
        if not sql:
            raise util.TracError('Report %s has no SQL query.' % id)
        cursor.execute(sql)

        if sql.find('__group__') == -1:
            self.req.hdf.setValue('report.sorting.enabled', '1')

        # FIXME: fetchall should probably not be used.
        info = cursor.fetchall()
        cols = cursor.rs.col_defs
        # Escape the values so that they are safe to have as html parameters
        #info = map(lambda row: map(lambda x: escape(x), row), info)

        return [cols, info]

    def commit_changes(self, id):
        """
        saves report changes to the database
        """
        self.perm.assert_permission(perm.REPORT_MODIFY)

        if not self.args.has_key('cancel'):
            cursor = self.db.cursor()
            title = self.args.get('title', '')
            sql = self.args.get('sql', '')
            description = self.args.get('description', '')

            cursor.execute(
                'UPDATE report SET title=%s, sql=%s, description=%s '
                ' WHERE id=%s', title, sql, description, id)
            self.db.commit()
        self.req.redirect(self.env.href.report(id))

    def render_confirm_delete(self, id):
        self.perm.assert_permission(perm.REPORT_DELETE)
        cursor = self.db.cursor()

        cursor.execute('SELECT title FROM report WHERE id = %s', id)
        row = cursor.fetchone()
        if not row:
            raise util.TracError('Report %s does not exist.' % id,
                                 'Invalid Report Number')
        self.req.hdf.setValue('title',
                              'Delete Report {%s} %s' % (id, row['title']))
        self.req.hdf.setValue('report.mode', 'delete')
        self.req.hdf.setValue('report.id', str(id))
        self.req.hdf.setValue('report.title', row['title'])

    def render_report_editor(self, id, action='commit', copy=0):
        self.perm.assert_permission(perm.REPORT_MODIFY)
        cursor = self.db.cursor()

        if id == -1:
            title = sql = description = ''
        else:
            cursor.execute(
                'SELECT title, description, sql FROM report '
                ' WHERE id=%s', id)
            row = cursor.fetchone()
            if not row:
                raise util.TracError('Report %s does not exist.' % id,
                                     'Invalid Report Number')
            sql = row[2] or ''
            description = row[1] or ''
            title = row[0] or ''

        if copy:
            title += ' copy'

        if action == 'commit':
            self.req.hdf.setValue('title',
                                  'Edit Report {%d} %s' % (id, row['title']))
        else:
            self.req.hdf.setValue('title', 'Create New Report')
        self.req.hdf.setValue('report.mode', 'editor')
        self.req.hdf.setValue('report.title', title)
        self.req.hdf.setValue('report.id', str(id))
        self.req.hdf.setValue('report.action', action)
        self.req.hdf.setValue('report.sql', sql)
        self.req.hdf.setValue('report.description', description)

    def add_alternate_links(self, args):
        params = args
        if self.args.has_key('sort'):
            params['sort'] = self.args['sort']
        if self.args.has_key('asc'):
            params['asc'] = self.args['asc']
        href = ''
        if params:
            href = '&amp;' + urllib.urlencode(params).replace('&', '&amp;')
        self.add_link('alternate', '?format=rss' + href, 'RSS Feed',
                      'application/rss+xml', 'rss')
        self.add_link('alternate', '?format=csv' + href,
                      'Comma-delimited Text', 'text/plain')
        self.add_link('alternate', '?format=tab' + href, 'Tab-delimited Text',
                      'text/plain')
        if self.perm.has_permission(perm.REPORT_SQL_VIEW):
            self.add_link('alternate', '?format=sql', 'SQL Query',
                          'text/plain')

    def render_report_list(self, id):
        """
        uses a user specified sql query to extract some information
        from the database and presents it as a html table.
        """
        if self.perm.has_permission(perm.REPORT_CREATE):
            self.req.hdf.setValue('report.create_href',
                                  self.env.href.report(None, 'new'))

        if id != -1:
            if self.perm.has_permission(perm.REPORT_MODIFY):
                self.req.hdf.setValue('report.edit_href',
                                      self.env.href.report(id, 'edit'))
            if self.perm.has_permission(perm.REPORT_CREATE):
                self.req.hdf.setValue('report.copy_href',
                                      self.env.href.report(id, 'copy'))
            if self.perm.has_permission(perm.REPORT_DELETE):
                self.req.hdf.setValue('report.delete_href',
                                      self.env.href.report(id, 'delete'))

        try:
            args = self.get_var_args()
        except ValueError, e:
            self.req.hdf.setValue('report.message', 'report failed: %s' % e)
            return

        if id != -1:
            self.add_alternate_links(args)

        self.req.hdf.setValue('report.mode', 'list')
        info = self.get_info(id, args)
        if not info:
            return
        [title, description, sql] = info
        self.error = None

        if id > 0:
            title = '{%i} %s' % (id, title)
        self.req.hdf.setValue('title', title)
        self.req.hdf.setValue('report.title', title)
        self.req.hdf.setValue('report.id', str(id))
        descr_html = wiki_to_html(description, self.req.hdf, self.env, self.db)
        self.req.hdf.setValue('report.description', descr_html)

        if self.args.get('format') == 'sql':
            return

        try:
            [self.cols, self.rows] = self.execute_report(sql, args)
        except Exception, e:
            self.error = e
            self.req.hdf.setValue('report.message', 'Report failed: %s' % e)
            return None
Пример #6
0
     value['hidden'] = 1
 elif (column[0] == '_' and column[-1] == '_'):
     value['fullrow'] = 1
     column = column[1:-1]
     self.req.hdf.setValue(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 ['ticket', '#', 'summary']:
     value['ticket_href'] = self.env.href.ticket(row['ticket'])
 elif column == 'description':
     value['parsed'] = wiki_to_html(cell, self.req.hdf,
                                    self.env, self.db)
 elif column == 'reporter':
     value['reporter'] = cell
     value['reporter.rss'] = cell.find('@') and cell or ''
 elif column == 'report':
     value['report_href'] = self.env.href.report(cell)
 elif column in [
         'time', 'date', 'changetime', 'created', 'modified'
 ]:
     t = time.localtime(int(cell))
     value['date'] = time.strftime('%x', t)
     value['time'] = time.strftime('%X', t)
     value['datetime'] = time.strftime('%c', t)
     value['gmt'] = time.strftime('%a, %d %b %Y %H:%M:%S GMT',
                                  time.gmtime(int(cell)))
 prefix = 'report.items.%d.%s' % (row_idx, str(column))
Пример #7
0
    def insert_ticket_data(self, hdf, id, ticket, reporter_id):
        """Insert ticket data into the hdf"""
        evals = util.mydict(
            zip(ticket.keys(), map(lambda x: util.escape(x), ticket.values())))
        util.add_to_hdf(evals, self.req.hdf, 'ticket')

        util.sql_to_hdf(self.db, 'SELECT name FROM component ORDER BY name',
                        self.req.hdf, 'ticket.components')
        util.sql_to_hdf(self.db, 'SELECT name FROM milestone ORDER BY name',
                        self.req.hdf, 'ticket.milestones')
        util.sql_to_hdf(self.db, 'SELECT name FROM version ORDER BY name',
                        self.req.hdf, 'ticket.versions')
        util.sql_to_hdf(
            self.db, "SELECT name FROM enum WHERE type='resolution'"
            " ORDER BY value", self.req.hdf, 'enums.resolution')
        util.hdf_add_if_missing(self.req.hdf, 'ticket.components',
                                ticket['component'])
        util.hdf_add_if_missing(self.req.hdf, 'ticket.milestones',
                                ticket['milestone'])
        util.hdf_add_if_missing(self.req.hdf, 'ticket.versions',
                                ticket['version'])
        util.hdf_add_if_missing(self.req.hdf, 'enums.priority',
                                ticket['priority'])
        util.hdf_add_if_missing(self.req.hdf, 'enums.severity',
                                ticket['severity'])
        util.hdf_add_if_missing(self.req.hdf, 'enums.resolution', 'fixed')

        self.req.hdf.setValue('ticket.reporter_id', util.escape(reporter_id))
        self.req.hdf.setValue('title', '#%d (%s)' % (id, ticket['summary']))
        self.req.hdf.setValue(
            'ticket.description.formatted',
            wiki_to_html(ticket['description'], self.req.hdf, self.env,
                         self.db))
        self.req.hdf.setValue(
            'ticket.opened',
            time.strftime('%c', time.localtime(int(ticket['time']))))

        changelog = ticket.get_changelog(self.db)
        curr_author = None
        curr_date = 0
        comment = None
        idx = 0
        for date, author, field, old, new in changelog:
            hdf.setValue('ticket.changes.%d.date' % idx,
                         time.strftime('%c', time.localtime(date)))
            hdf.setValue('ticket.changes.%d.time' % idx, str(date))
            hdf.setValue('ticket.changes.%d.author' % idx, util.escape(author))
            hdf.setValue('ticket.changes.%d.field' % idx, field)
            hdf.setValue('ticket.changes.%d.old' % idx, util.escape(old))
            if field == 'comment':
                hdf.setValue(
                    'ticket.changes.%d.new' % idx,
                    wiki_to_html(new, self.req.hdf, self.env, self.db))
            else:
                hdf.setValue('ticket.changes.%d.new' % idx, util.escape(new))
            idx = idx + 1

        insert_custom_fields(self.env, hdf, ticket)
        # List attached files
        self.env.get_attachments_hdf(self.db, 'ticket', str(id), self.req.hdf,
                                     'ticket.attachments')
Пример #8
0
    def render(self):
        FileCommon.render(self)

        self.rev = self.args.get('rev', None)
        self.path = self.args.get('path', '/')
        if not self.rev:
            rev_specified = 0
            self.rev = svn.fs.youngest_rev(self.fs_ptr, self.pool)
        else:
            rev_specified = 1
            try:
                self.rev = int(self.rev)
            except ValueError:
                rev_specified = 0
                self.rev = svn.fs.youngest_rev(self.fs_ptr, self.pool)

        self.generate_path_links(self.rev, rev_specified)

        try:
            root = svn.fs.revision_root(self.fs_ptr, self.rev, self.pool)
        except svn.core.SubversionException:
            self.rev = svn.fs.youngest_rev(self.fs_ptr, self.pool)
            root = svn.fs.revision_root(self.fs_ptr, self.rev, self.pool)

        node_type = svn.fs.check_path(root, self.path, self.pool)
        if not node_type in [svn.core.svn_node_dir, svn.core.svn_node_file]:
            self.rev = svn.fs.youngest_rev(self.fs_ptr, self.pool)
            root = svn.fs.revision_root(self.fs_ptr, self.rev, self.pool)
            oh = svn.fs.node_history(root, self.path, self.pool)
            while oh:
                h = oh
                oh = svn.fs.history_prev(h, 0, self.pool)
            history = h
        else:
            history = svn.fs.node_history(root, self.path, self.pool)
            history = svn.fs.history_prev(history, 0, self.pool)
        history_path, history_rev = svn.fs.history_location(history, self.pool);

        if self.rev != history_rev:
            self.rev = history_rev

        author = svn.fs.revision_prop(self.fs_ptr, self.rev,
                                      svn.core.SVN_PROP_REVISION_AUTHOR, self.pool)
        msg = svn.fs.revision_prop(self.fs_ptr, self.rev,
                                   svn.core.SVN_PROP_REVISION_LOG, self.pool)
        msg_html = wiki_to_html(util.wiki_escape_newline(msg), self.req.hdf, self.env, self.db)
        date = svn.fs.revision_prop(self.fs_ptr, self.rev,
                                    svn.core.SVN_PROP_REVISION_DATE, self.pool)
        sdate = util.svn_date_to_string(date, self.pool)

        self.req.hdf.setValue('file.chgset_href', self.env.href.changeset(self.rev))
        self.req.hdf.setValue('file.rev', str(self.rev))
        self.req.hdf.setValue('file.rev_author', str(author))
        self.req.hdf.setValue('file.rev_date', sdate)
        self.req.hdf.setValue('file.rev_msg', msg_html)
        self.req.hdf.setValue('file.path', self.path)
        self.req.hdf.setValue('file.logurl',
            saxutils.escape(self.env.href.log(self.path, self.rev)))

        # Try to do an educated guess about the mime-type
        self.mime_type = svn.fs.node_prop (root, self.path,
                                           svn.util.SVN_PROP_MIME_TYPE,
                                           self.pool)
        if not self.mime_type:
            self.mime_type = self.env.mimeview.get_mimetype(filename=self.path) or \
                             'text/plain'
        elif self.mime_type == 'application/octet-stream':
            self.mime_type = self.env.mimeview.get_mimetype(filename=self.path) or \
                             'application/octet-stream'

        self.add_link('alternate', self.env.href.file(self.path, self.rev, 'raw'),
            'Original Format', self.mime_type)
        self.add_link('alternate', self.env.href.file(self.path, self.rev, 'txt'),
            'Plain Text', 'text/plain')

        self.length = svn.fs.file_length(root, self.path, self.pool)
        date = svn.fs.revision_prop(self.fs_ptr, self.rev,
                                svn.util.SVN_PROP_REVISION_DATE, self.pool)
        date_seconds = svn.util.svn_time_from_cstring(date, self.pool) / 1000000
        self.last_modified = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                      time.gmtime(date_seconds))
        fd = svn.fs.file_contents(root, self.path, self.pool)
        self.read_func = lambda x, f=fd: svn.util.svn_stream_read(f, x)