Beispiel #1
0
    def _render_diff(self, req, filename, repos, diff, diff_options):
        """Raw Unified Diff version"""
        req.send_response(200)
        req.send_header('Content-Type', 'text/plain;charset=utf-8')
        req.send_header('Content-Disposition', 'inline;'
                        'filename=%s.diff' % filename)
        req.end_headers()

        mimeview = Mimeview(self.env)
        for old_node, new_node, kind, change in repos.get_changes(**diff):
            # TODO: Property changes

            # Content changes
            if kind == Node.DIRECTORY:
                continue

            new_content = old_content = ''
            new_node_info = old_node_info = ('','')
            mimeview = Mimeview(self.env)

            if old_node:
                old_content = old_node.get_content().read()
                if is_binary(old_content):
                    continue
                old_node_info = (old_node.path, old_node.rev)
                old_content = mimeview.to_unicode(old_content,
                                                  old_node.content_type)
            if new_node:
                new_content = new_node.get_content().read()
                if is_binary(new_content):
                    continue
                new_node_info = (new_node.path, new_node.rev)
                new_path = new_node.path
                new_content = mimeview.to_unicode(new_content,
                                                  new_node.content_type)
            else:
                old_node_path = repos.normalize_path(old_node.path)
                diff_old_path = repos.normalize_path(diff.old_path)
                new_path = posixpath.join(diff.new_path,
                                          old_node_path[len(diff_old_path)+1:])

            if old_content != new_content:
                context = 3
                options = diff_options[1]
                for option in options:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                if not old_node_info[0]:
                    old_node_info = new_node_info # support for 'A'dd changes
                req.write('Index: ' + new_path + CRLF)
                req.write('=' * 67 + CRLF)
                req.write('--- %s (revision %s)' % old_node_info + CRLF)
                req.write('+++ %s (revision %s)' % new_node_info + CRLF)
                for line in unified_diff(old_content.splitlines(),
                                         new_content.splitlines(), context,
                                         ignore_blank_lines='-B' in options,
                                         ignore_case='-i' in options,
                                         ignore_space_changes='-b' in options):
                    req.write(line + CRLF)
Beispiel #2
0
    def _render_diff(self, req, filename, repos, diff, diff_options):
        """Raw Unified Diff version"""
        req.send_response(200)
        req.send_header('Content-Type', 'text/plain;charset=utf-8')
        req.send_header('Content-Disposition', 'inline;'
                        'filename=%s.diff' % filename)
        req.end_headers()

        mimeview = Mimeview(self.env)
        for old_node, new_node, kind, change in repos.get_changes(**diff):
            # TODO: Property changes

            # Content changes
            if kind == Node.DIRECTORY:
                continue

            new_content = old_content = ''
            new_node_info = old_node_info = ('','')
            mimeview = Mimeview(self.env)

            if old_node:
                old_content = old_node.get_content().read()
                if is_binary(old_content):
                    continue
                old_node_info = (old_node.path, old_node.rev)
                old_content = mimeview.to_unicode(old_content,
                                                  old_node.content_type)
            if new_node:
                new_content = new_node.get_content().read()
                if is_binary(new_content):
                    continue
                new_node_info = (new_node.path, new_node.rev)
                new_path = new_node.path
                new_content = mimeview.to_unicode(new_content,
                                                  new_node.content_type)
            else:
                old_node_path = repos.normalize_path(old_node.path)
                diff_old_path = repos.normalize_path(diff.old_path)
                new_path = posixpath.join(diff.new_path,
                                          old_node_path[len(diff_old_path)+1:])

            if old_content != new_content:
                context = 3
                options = diff_options[1]
                for option in options:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                if not old_node_info[0]:
                    old_node_info = new_node_info # support for 'A'dd changes
                req.write('Index: ' + new_path + CRLF)
                req.write('=' * 67 + CRLF)
                req.write('--- %s (revision %s)' % old_node_info + CRLF)
                req.write('+++ %s (revision %s)' % new_node_info + CRLF)
                for line in unified_diff(old_content.splitlines(),
                                         new_content.splitlines(), context,
                                         ignore_blank_lines='-B' in options,
                                         ignore_case='-i' in options,
                                         ignore_space_changes='-b' in options):
                    req.write(line + CRLF)
Beispiel #3
0
    def filter_stream(self, req, method, filename, stream, data):
        action = req.args.get('action', '')
        
        if filename == 'browser.html' and action == 'edit':
            req.perm.require('REPOSITORY_MODIFY')
            # NB TracBrowserOps already inserts javascript and css we need
            # So only add css/javascript needed solely by the editor
            
            if data['file'] and data['file']['preview']['rendered']:
                max_edit_size = self.max_edit_size
                data['max_edit_size'] = max_edit_size
                
                # Discard rendered table, replace with textarea of file contents
                # This means reading the file from the repository again
                # N.B. If a file is rendered as something other than a table
                # e.g. due to PreCodeBrowserPlugin this code won't trigger
                
                # Retrieve the same node that BrowserModule.process_request() 
                # used to render the preview.
                # At this point reponame has been removed from data['path']
                # and repos has already been determined
                repos = data['repos']
                path = data['path']
                rev = data['rev']
                node = repos.get_node(path, rev)
                
                # If node is too large then don't allow editing, abort
                if max_edit_size > 0 and node.content_length > max_edit_size:
                    return stream
                
                # Open the node and read it
                node_file = node.get_content() 
                node_data = node_file.read()

                # Discover the mime type and character encoding of the node
                # Try in order
                #  - svn:mime-type property
                #  - detect from file name and content (BOM)
                #  - use configured default for Trac
                mime_view = Mimeview(self.env)
                mime_type = node.content_type \
                            or mime_view.get_mimetype(node.name, node_data) \
                            or 'text/plain'
                encoding = mime_view.get_charset(node_data, mime_type)
                
                # Populate template data
                content = mime_view.to_unicode(node_data, mime_type, encoding)
                data['file_content'] = content               
                data['file_encoding'] = encoding
                
                # Replace the already rendered preview with a form and textarea
                bsops_stream = Chrome(self.env).render_template(req,
                        'file_edit.html', data, fragment=True)
                transf = Transformer('//div[@id="preview"]'
                                     '/table[@class="code"]')
                stream |=  transf.replace(
                        bsops_stream.select('//div[@id="bsop_edit"]'))
        return stream
Beispiel #4
0
    def filter_stream(self, req, method, filename, stream, data):
        action = req.args.get('action', '')

        if filename == 'browser.html' and action == 'edit':
            req.perm.require('REPOSITORY_MODIFY')
            # NB TracBrowserOps already inserts javascript and css we need
            # So only add css/javascript needed solely by the editor

            if data['file'] and data['file']['preview']['rendered']:
                max_edit_size = self.max_edit_size
                data['max_edit_size'] = max_edit_size

                # Discard rendered table, replace with textarea of file contents
                # This means reading the file from the repository again
                # N.B. If a file is rendered as something other than a table
                # e.g. due to PreCodeBrowserPlugin this code won't trigger

                # Retrieve the same node that BrowserModule.process_request()
                # used to render the preview.
                # At this point reponame has been removed from data['path']
                # and repos has already been determined
                repos = data['repos']
                path = data['path']
                rev = data['rev']
                node = repos.get_node(path, rev)

                # If node is too large then don't allow editing, abort
                if max_edit_size > 0 and node.content_length > max_edit_size:
                    return stream

                # Open the node and read it
                node_file = node.get_content()
                node_data = node_file.read()

                # Discover the mime type and character encoding of the node
                # Try in order
                #  - svn:mime-type property
                #  - detect from file name and content (BOM)
                #  - use configured default for Trac
                mime_view = Mimeview(self.env)
                mime_type = node.content_type \
                            or mime_view.get_mimetype(node.name, node_data) \
                            or 'text/plain'
                encoding = mime_view.get_charset(node_data, mime_type)

                # Populate template data
                content = mime_view.to_unicode(node_data, mime_type, encoding)
                data['file_content'] = content
                data['file_encoding'] = encoding

                # Replace the already rendered preview with a form and textarea
                bsops_stream = Chrome(self.env).render_template(
                    req, 'file_edit.html', data, fragment=True)
                transf = Transformer('//div[@id="preview"]'
                                     '/table[@class="code"]')
                stream |= transf.replace(
                    bsops_stream.select('//div[@id="bsop_edit"]'))
        return stream
Beispiel #5
0
        def _content_changes(old_node, new_node):
            """Returns the list of differences.

            The list is empty when no differences between comparable files
            are detected, but the return value is None for non-comparable files.
            """
            mview = Mimeview(self.env)
            if mview.is_binary(old_node.content_type, old_node.path):
                return None
            if mview.is_binary(new_node.content_type, new_node.path):
                return None
            old_content = old_node.get_content().read()
            if mview.is_binary(content=old_content):
                return None
            new_content = new_node.get_content().read()
            if mview.is_binary(content=new_content):
                return None

            old_content = mview.to_unicode(old_content, old_node.content_type)
            new_content = mview.to_unicode(new_content, new_node.content_type)

            if old_content != new_content:
                context = options.get('contextlines', 3)
                if context < 0:
                    context = None
                tabwidth = self.config['diff'].getint('tab_width') or \
                           self.config['mimeviewer'].getint('tab_width', 8)
                ignore_blank_lines = options.get('ignoreblanklines')
                ignore_case = options.get('ignorecase')
                ignore_space = options.get('ignorewhitespace')
                return diff_blocks(old_content.splitlines(),
                                   new_content.splitlines(),
                                   context, tabwidth,
                                   ignore_blank_lines=ignore_blank_lines,
                                   ignore_case=ignore_case,
                                   ignore_space_changes=ignore_space)
            else:
                return []
Beispiel #6
0
        def _content_changes(old_node, new_node):
            """Returns the list of differences.

            The list is empty when no differences between comparable files
            are detected, but the return value is None for non-comparable files.
            """
            old_content = old_node.get_content().read()
            if is_binary(old_content):
                return None

            new_content = new_node.get_content().read()
            if is_binary(new_content):
                return None

            mview = Mimeview(self.env)
            old_content = mview.to_unicode(old_content, old_node.content_type)
            new_content = mview.to_unicode(new_content, new_node.content_type)

            if old_content != new_content:
                context = 3
                options = diff_options[1]
                for option in options:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                if context < 0:
                    context = None
                tabwidth = self.config['diff'].getint('tab_width') or \
                           self.config['mimeviewer'].getint('tab_width', 8)
                return hdf_diff(old_content.splitlines(),
                                new_content.splitlines(),
                                context, tabwidth,
                                ignore_blank_lines='-B' in options,
                                ignore_case='-i' in options,
                                ignore_space_changes='-b' in options)
            else:
                return []
Beispiel #7
0
        def _content_changes(old_node, new_node):
            """Returns the list of differences.

            The list is empty when no differences between comparable files
            are detected, but the return value is None for non-comparable files.
            """
            old_content = old_node.get_content().read()
            if is_binary(old_content):
                return None

            new_content = new_node.get_content().read()
            if is_binary(new_content):
                return None

            mview = Mimeview(self.env)
            old_content = mview.to_unicode(old_content, old_node.content_type)
            new_content = mview.to_unicode(new_content, new_node.content_type)

            if old_content != new_content:
                context = 3
                options = diff_options[1]
                for option in options:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                if context < 0:
                    context = None
                tabwidth = self.config['diff'].getint('tab_width') or \
                           self.config['mimeviewer'].getint('tab_width', 8)
                return hdf_diff(old_content.splitlines(),
                                new_content.splitlines(),
                                context, tabwidth,
                                ignore_blank_lines='-B' in options,
                                ignore_case='-i' in options,
                                ignore_space_changes='-b' in options)
            else:
                return []
Beispiel #8
0
    def _render_diff(self, req, filename, repos, data):
        """Raw Unified Diff version"""
        req.send_response(200)
        req.send_header('Content-Type', 'text/x-patch;charset=utf-8')
        req.send_header('Content-Disposition',
                        content_disposition('inline', filename + '.diff'))
        buf = StringIO()
        mimeview = Mimeview(self.env)

        for old_node, new_node, kind, change in repos.get_changes(
            new_path=data['new_path'], new_rev=data['new_rev'],
            old_path=data['old_path'], old_rev=data['old_rev']):
            # TODO: Property changes

            # Content changes
            if kind == Node.DIRECTORY:
                continue

            new_content = old_content = ''
            new_node_info = old_node_info = ('','')
            mimeview = Mimeview(self.env)

            if old_node:
                if mimeview.is_binary(old_node.content_type, old_node.path):
                    continue
                old_content = old_node.get_content().read()
                if mimeview.is_binary(content=old_content):
                    continue
                old_node_info = (old_node.path, old_node.rev)
                old_content = mimeview.to_unicode(old_content,
                                                  old_node.content_type)
            if new_node:
                if mimeview.is_binary(new_node.content_type, new_node.path):
                    continue
                new_content = new_node.get_content().read()
                if mimeview.is_binary(content=new_content):
                    continue
                new_node_info = (new_node.path, new_node.rev)
                new_path = new_node.path
                new_content = mimeview.to_unicode(new_content,
                                                  new_node.content_type)
            else:
                old_node_path = repos.normalize_path(old_node.path)
                diff_old_path = repos.normalize_path(data['old_path'])
                new_path = posixpath.join(data['new_path'],
                                          old_node_path[len(diff_old_path)+1:])

            if old_content != new_content:
                options = data['diff']['options']
                context = options.get('contextlines', 3)
                if context < 0:
                    context = 3 # FIXME: unified_diff bugs with context=None
                ignore_blank_lines = options.get('ignoreblanklines')
                ignore_case = options.get('ignorecase')
                ignore_space = options.get('ignorewhitespace')
                if not old_node_info[0]:
                    old_node_info = new_node_info # support for 'A'dd changes
                buf.write('Index: ' + new_path + CRLF)
                buf.write('=' * 67 + CRLF)
                buf.write('--- %s\t(revision %s)' % old_node_info + CRLF)
                buf.write('+++ %s\t(revision %s)' % new_node_info + CRLF)
                for line in unified_diff(old_content.splitlines(),
                                         new_content.splitlines(), context,
                                         ignore_blank_lines=ignore_blank_lines,
                                         ignore_case=ignore_case,
                                         ignore_space_changes=ignore_space):
                    buf.write(line + CRLF)
                    
        diff_str = buf.getvalue().encode('utf-8')
        req.send_header('Content-Length', len(diff_str))
        req.end_headers()
        req.write(diff_str)
        raise RequestDone
Beispiel #9
0
    def _get_userlog(self, req, db, user, sort):
        mimeview = Mimeview(self.env)
        repos = self.env.get_repository()
        diff_options = get_diff_options(req)
        cursor = db.cursor()
        cursor.execute("SELECT rev, time, message FROM revision "
                       "WHERE author='%s' ORDER BY time %s" % (user, sort))
                       # Have to sort by time because rev is a text field
                       # and sorts lexicographically rather than numerically
        changesets = []
        for rev, time, message in cursor:
            if self.wiki_format_messages:
                message = wiki_to_html(message, self.env, req,
                                              escape_newlines=True)
            else:
                message = html.PRE(message)
            prev = repos.get_node('/', rev).get_previous()
            if prev:
                prev_rev = prev[1]
            else:
                prev_rev = rev
            diffs = []
            changes = repos.get_changes(old_path='/', old_rev=prev_rev,
                                        new_path='/', new_rev=rev)
            for old_node, new_node, kind, change in changes:
                if kind == Node.DIRECTORY:
                    if change == Changeset.ADD:
                        diffs.append(('%s added' % new_node.path, ''))
                    elif change == Changeset.DELETE:
                        diffs.append(('%s deleted' % old_node.path, ''))
                    continue

                new_content = old_content = ''
                new_node_info = old_node_info = ('','')
                
                if old_node:
                    old_content = old_node.get_content().read()
                    if is_binary(old_content):
                        continue
                    old_node_info = (old_node.path, old_node.rev)
                    old_content = mimeview.to_unicode(old_content,
                                                      old_node.content_type)
                if new_node:
                    new_content = new_node.get_content().read()
                    if is_binary(new_content):
                        continue
                    new_node_info = (new_node.path, new_node.rev)
                    new_path = new_node.path
                    new_content = mimeview.to_unicode(new_content,
                                                      new_node.content_type)
                else:
                    old_node_path = repos.normalize_path(old_node.path)
                    diff_old_path = repos.normalize_path('/')
                    new_path = posixpath.join('/', old_node_path[len(diff_old_path)+1:])

                if old_content != new_content:
                    context = 3
                    options = diff_options[1]
                    for option in options:
                        if option.startswith('-U'):
                            context = int(option[2:])
                            break
                    if not old_node_info[0]:
                        old_node_info = new_node_info # support for 'A'dd changes
                    diff = 'Index: ' + new_path + CRLF
                    diff += '=' * 67 + CRLF
                    diff += '--- %s (revision %s)' % old_node_info + CRLF
                    diff += '+++ %s (revision %s)' % new_node_info + CRLF
                    for line in unified_diff(old_content.splitlines(),
                                             new_content.splitlines(), context,
                                             ignore_blank_lines='-B' in options,
                                             ignore_case='-i' in options,
                                             ignore_space_changes='-b' in options):
                        diff += line + CRLF
                    if change == Changeset.ADD:
                        diffs.append(('%s added' % (new_node.path,), diff))
                    elif change == Changeset.DELETE:
                        diffs.append(('%s deleted' % (old_node.path,), diff))
                    else:
                        diffs.append(('%s edited' % (new_node.path,), diff))
            changesets.append((int(rev), format_datetime(time), message, diffs))
        return changesets