Esempio n. 1
0
    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'])
Esempio n. 2
0
    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]
Esempio n. 3
0
    def save_changes(self, id):
        self.perm.assert_permission(perm.TICKET_MODIFY)
        ticket = Ticket(self.db, id)

        if not self.args.get('summary'):
            raise util.TracError('Tickets must contain Summary.')

        if self.args.has_key('description'):
            self.perm.assert_permission(perm.TICKET_ADMIN)

        if self.args.has_key('reporter'):
            self.perm.assert_permission(perm.TICKET_ADMIN)

        # TODO: this should not be hard-coded like this
        action = self.args.get('action', None)
        if action == 'accept':
            ticket['status'] = 'assigned'
            ticket['owner'] = self.req.authname
        if action == 'resolve':
            ticket['status'] = 'closed'
            ticket['resolution'] = self.args.get('resolve_resolution')
        elif action == 'reassign':
            ticket['owner'] = self.args.get('reassign_owner')
            ticket['status'] = 'new'
        elif action == 'reopen':
            ticket['status'] = 'reopened'
            ticket['resolution'] = ''

        ticket.populate(self.args)

        now = int(time.time())

        ticket.save_changes(self.db,
                            self.args.get('author', self.req.authname),
                            self.args.get('comment'),
                            when=now)

        tn = TicketNotifyEmail(self.env)
        tn.notify(ticket, newticket=0, modtime=now)
        self.req.redirect(self.env.href.ticket(id))
Esempio n. 4
0
    def create_attachment(self, cnx, type, id, attachment, description, author,
                          ipnr):
        # Maximum attachment size (in bytes)
        max_size = int(self.get_config('attachment', 'max_size', '262144'))
        if hasattr(attachment.file, 'fileno'):
            stat = os.fstat(attachment.file.fileno())
            length = stat[6]
        else:
            length = attachment.file.len
        if length > max_size:
            raise util.TracError(
                'Maximum attachment size: %d bytes' % max_size,
                'Upload failed')
        dir = os.path.join(self.get_attachments_dir(), type, urllib.quote(id))
        if not os.access(dir, os.F_OK):
            os.makedirs(dir)
        filename = attachment.filename.replace('\\', '/').replace(':', '/')
        filename = os.path.basename(filename)

        # We try to normalize the filename to utf-8 NFC if we can.
        # Files uploaded from OS X might be in NFD.
        if sys.version_info[0] > 2 or \
           (sys.version_info[0] == 2 and sys.version_info[1] >= 3):
            filename = unicodedata.normalize('NFC',
                                             unicode(filename,
                                                     'utf-8')).encode('utf-8')

        filename = urllib.quote(filename)
        path, fd = util.create_unique_file(os.path.join(dir, filename))
        filename = os.path.basename(path)
        filename = urllib.unquote(filename)
        cursor = cnx.cursor()
        cursor.execute(
            'INSERT INTO attachment VALUES(%s,%s,%s,%s,%s,%s,%s,%s)', type, id,
            filename, length, int(time.time()), description, author, ipnr)
        shutil.copyfileobj(attachment.file, fd)
        self.log.info('New attachment: %s/%s/%s by %s', type, id, filename,
                      author)
        cnx.commit()
        return filename
Esempio n. 5
0
    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]
Esempio n. 6
0
    def create_ticket(self):
        if not self.args.get('summary'):
            raise util.TracError('Tickets must contain Summary.')

        ticket = Ticket()
        ticket.populate(self.args)
        ticket.setdefault('reporter', self.req.authname)

        # The owner field defaults to the component owner
        cursor = self.db.cursor()
        if ticket.get('component') and ticket.get('owner', '') == '':
            cursor.execute('SELECT owner FROM component '
                           'WHERE name=%s', ticket['component'])
            owner = cursor.fetchone()[0]
            ticket['owner'] = owner

        tktid = ticket.insert(self.db)

        # Notify
        tn = TicketNotifyEmail(self.env)
        tn.notify(ticket, newticket=1)
        self.req.redirect(self.env.href.ticket(tktid))
Esempio n. 7
0
    def render_diffs(self, editor_class=HtmlDiffEditor):
        """
        generates a unified diff of the changes for a given changeset.
        the output is written to stdout.
        """
        try:
            old_root = svn.fs.revision_root(self.fs_ptr,
                                            int(self.rev) - 1, self.pool)
            new_root = svn.fs.revision_root(self.fs_ptr, int(self.rev),
                                            self.pool)
        except svn.core.SubversionException:
            raise util.TracError('Invalid revision number: %d' % int(self.rev))

        editor = editor_class(old_root, new_root, int(self.rev), self.req,
                              self.args, self.env, self.authzperm)
        e_ptr, e_baton = svn.delta.make_editor(editor, self.pool)

        def authz_cb(root, path, pool):
            return self.authzperm.has_permission(path) and 1 or 0

        svn.repos.svn_repos_dir_delta(old_root, '', '', new_root, '', e_ptr,
                                      e_baton, authz_cb, 0, 1, 0, 1, self.pool)
Esempio n. 8
0
    def _fetch_ticket(self, db, id):
        cursor = db.cursor()
        fetch = string.join(Ticket.std_fields, ',')
        cursor.execute(('SELECT %s FROM ticket ' % fetch) + 'WHERE id=%s', id)
        row = cursor.fetchone()
        cursor.close()

        if not row:
            raise util.TracError('Ticket %d does not exist.' % id,
                                 'Invalid Ticket Number')

        self['id'] = id
        # Escape the values so that they are safe to have as html parameters
        for i in range(len(Ticket.std_fields)):
            self[Ticket.std_fields[i]] = row[i] or ''

        cursor = db.cursor()
        cursor.execute('SELECT name,value FROM ticket_custom WHERE ticket=%i',
                       id)
        rows = cursor.fetchall()
        if rows:
            for r in rows:
                self['custom_' + r[0]] = r[1]
        self._forget_changes()
Esempio n. 9
0
    def get_info(self, path, revision, rev_specified):
        """
        Extracts information for a given path and revision
        """
        # We need to really make sure it's an ordinary string. The FieldStorage
        # class provided by modpython might give us some strange string-like object
        # that svn doesn't like.
        path = str(path)
        try:
            root = svn.fs.revision_root(self.fs_ptr, revision, self.pool)
        except svn.core.SubversionException:
            raise util.TracError('Invalid revision number: %d' % revision)

        node_type = svn.fs.check_path(root, path, self.pool)
        if not node_type in [svn.core.svn_node_dir, svn.core.svn_node_file]:
            raise util.TracError('"%s": no such file or directory in revision %d' \
                            % (path, revision), 'No such file or directory')

        # Redirect to the file module if the requested path happens
        # to point to a regular file
        if svn.fs.is_file(root, path, self.pool):
            if rev_specified:
                self.req.redirect(self.env.href.file(path, revision))
            else:
                self.req.redirect(self.env.href.log(path))

        entries = svn.fs.dir_entries(root, path, self.pool)
        info = []
        for item in entries.keys():
            fullpath = posixpath.join(path, item)

            is_dir = svn.fs.is_dir(root, fullpath, self.pool)
            if is_dir:
                name = item + '/'
                fullpath = fullpath + '/'
            else:
                name = item

            created_rev = svn.fs.node_created_rev(root, fullpath, self.pool)
            date = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                    svn.core.SVN_PROP_REVISION_DATE,
                                    self.pool)
            if date:
                date_seconds = svn.core.svn_time_from_cstring(date,
                                                              self.pool) / 1000000
                date = time.strftime('%x %X', time.localtime(date_seconds))
            else:
                date_seconds = 0
                date = ''
            author = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                          svn.core.SVN_PROP_REVISION_AUTHOR,
                                          self.pool)
            change = svn.fs.revision_prop(self.fs_ptr, created_rev,
                                          svn.core.SVN_PROP_REVISION_LOG,
                                          self.pool)
            item = {
                'name'         : name,
                'fullpath'     : fullpath,
                'created_rev'  : created_rev,
                'date'         : date,
                'date_seconds' : date_seconds,
                'age'          : util.pretty_age(date_seconds),
                'is_dir'       : is_dir,
                'author'       : author,
                'change'       : wiki_to_oneliner(util.shorten_line(util.wiki_escape_newline(change)),
                                                  self.req.hdf, self.env,self.db),
		'permission'   : self.authzperm.has_permission(fullpath)
                }
            if rev_specified:
                item['log_href'] = self.env.href.log(fullpath, revision)
                if is_dir:
                    item['browser_href'] = self.env.href.browser(fullpath,
                                                                 revision)
                else:
                    item['browser_href'] = self.env.href.file(fullpath, revision)
            else:
                item['log_href'] = self.env.href.log(fullpath)
                if is_dir:
                    item['browser_href'] = self.env.href.browser(fullpath)
                else:
                    item['browser_href'] = self.env.href.file(fullpath)

            info.append(item)
        return info
Esempio n. 10
0
    def render(self):
        FileCommon.render(self)
        self.view_form = 0
        self.attachment_type = self.args.get('type', None)
        self.attachment_id = self.args.get('id', None)
        self.filename = self.args.get('filename', None)
        if self.filename:
            self.filename = os.path.basename(self.filename)

        if not self.attachment_type or not self.attachment_id:
            raise util.TracError('Unknown request')

        if self.filename and len(self.filename) > 0 and \
               self.args.has_key('delete'):
            perm_map = {'ticket': perm.TICKET_ADMIN, 'wiki': perm.WIKI_DELETE}
            self.perm.assert_permission(perm_map[self.attachment_type])
            self.env.delete_attachment(self.db,
                                       self.attachment_type,
                                       self.attachment_id,
                                       self.filename)
            text, link = self.get_attachment_parent_link()
            self.req.redirect(link)

        if self.filename and len(self.filename) > 0:
            # Send an attachment
            perm_map = {'ticket': perm.TICKET_VIEW, 'wiki': perm.WIKI_VIEW}
            self.perm.assert_permission(perm_map[self.attachment_type])

            self.path = os.path.join(self.env.get_attachments_dir(),
                                     self.attachment_type,
                                     urllib.quote(self.attachment_id),
                                     urllib.quote(self.filename))
            try:
                fd = open(self.path, 'rb')
            except IOError:
                raise util.TracError('Attachment not found')
            
            stat = os.fstat(fd.fileno())
            self.length = stat[6]
            self.last_modified = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                               time.gmtime(stat[8]))
            self.read_func = lambda x, f=fd: f.read(x)
            self.mime_type = self.env.mimeview.get_mimetype(self.filename) \
                             or 'application/octet-stream'

            self.add_link('alternate',
                          self.env.href.attachment(self.attachment_type,
                                                   self.attachment_id,
                                                   self.filename, 'txt'),
                'Plain Text', 'text/plain')
            self.add_link('alternate',
                          self.env.href.attachment(self.attachment_type,
                                                   self.attachment_id,
                                                   self.filename, 'raw'),
                'Original Format', self.mime_type)

            perm_map = {'ticket': perm.TICKET_ADMIN, 'wiki': perm.WIKI_DELETE}
            if self.perm.has_permission(perm_map[self.attachment_type]):
                self.req.hdf.setValue('attachment.delete_href', '?delete=yes')

            return

        if self.args.has_key('description') and \
               self.args.has_key('author') and \
               self.args.has_key('attachment') and \
               hasattr(self.args['attachment'], 'file'):

            if self.args.has_key('cancel'):
                self.req.redirect(self.get_attachment_parent_link()[1])

            # Create a new attachment
            if not self.attachment_type in ['ticket', 'wiki']:
                raise util.TracError('Unknown attachment type')

            perm_map = {'ticket':perm.TICKET_MODIFY, 'wiki': perm.WIKI_MODIFY}
            self.perm.assert_permission (perm_map[self.attachment_type])

            filename = self.env.create_attachment(self.db,
                                                  self.attachment_type,
                                                  self.attachment_id,
                                                  self.args['attachment'],
                                                  self.args.get('description'),
                                                  self.args.get('author'),
                                                  self.req.remote_addr)
            # Redirect the user to the newly created attachment
            self.req.redirect(self.env.href.attachment(self.attachment_type,
                                                       self.attachment_id,
                                                       filename))
        else:
            # Display an attachment upload form
            self.view_form = 1