~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/filediff_ui.py

  • Committer: Ian Clatworthy
  • Date: 2010-04-23 00:02:29 UTC
  • mfrom: (407.1.2 loggerhead)
  • Revision ID: ian.clatworthy@canonical.com-20100423000229-ysxj7lzkx6oklt35
Skip syntax highlighting on files over 512K

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from StringIO import StringIO
 
2
import urllib
 
3
 
 
4
from bzrlib import diff
 
5
from bzrlib import errors
 
6
from bzrlib import osutils
 
7
 
 
8
from loggerhead import util
 
9
from loggerhead.controllers import TemplatedBranchView
 
10
 
 
11
def _process_diff(difftext):
 
12
    chunks = []
 
13
    chunk = None
 
14
    for line in difftext.splitlines():
 
15
        if len(line) == 0:
 
16
            continue
 
17
        if line.startswith('+++ ') or line.startswith('--- '):
 
18
            continue
 
19
        if line.startswith('@@ '):
 
20
            # new chunk
 
21
            if chunk is not None:
 
22
                chunks.append(chunk)
 
23
            chunk = util.Container()
 
24
            chunk.diff = []
 
25
            split_lines = line.split(' ')[1:3]
 
26
            lines = [int(x.split(',')[0][1:]) for x in split_lines]
 
27
            old_lineno = lines[0]
 
28
            new_lineno = lines[1]
 
29
        elif line.startswith(' '):
 
30
            chunk.diff.append(util.Container(old_lineno=old_lineno,
 
31
                                             new_lineno=new_lineno,
 
32
                                             type='context',
 
33
                                             line=line[1:]))
 
34
            old_lineno += 1
 
35
            new_lineno += 1
 
36
        elif line.startswith('+'):
 
37
            chunk.diff.append(util.Container(old_lineno=None,
 
38
                                             new_lineno=new_lineno,
 
39
                                             type='insert', line=line[1:]))
 
40
            new_lineno += 1
 
41
        elif line.startswith('-'):
 
42
            chunk.diff.append(util.Container(old_lineno=old_lineno,
 
43
                                             new_lineno=None,
 
44
                                             type='delete', line=line[1:]))
 
45
            old_lineno += 1
 
46
        else:
 
47
            chunk.diff.append(util.Container(old_lineno=None,
 
48
                                             new_lineno=None,
 
49
                                             type='unknown',
 
50
                                             line=repr(line)))
 
51
    if chunk is not None:
 
52
        chunks.append(chunk)
 
53
    return chunks
 
54
 
 
55
 
 
56
def diff_chunks_for_file(repository, file_id, compare_revid, revid):
 
57
    lines = {}
 
58
    args = []
 
59
    for r in (compare_revid, revid):
 
60
        if r == 'null:':
 
61
            lines[r] = []
 
62
        else:
 
63
            args.append((file_id, r, r))
 
64
    for r, bytes_iter in repository.iter_files_bytes(args):
 
65
        lines[r] = osutils.split_lines(''.join(bytes_iter))
 
66
    buffer = StringIO()
 
67
    try:
 
68
        diff.internal_diff('', lines[compare_revid], '', lines[revid], buffer)
 
69
    except errors.BinaryFile:
 
70
        difftext = ''
 
71
    else:
 
72
        difftext = buffer.getvalue()
 
73
 
 
74
    return _process_diff(difftext)
 
75
 
 
76
 
 
77
class FileDiffUI(TemplatedBranchView):
 
78
 
 
79
    template_path = 'loggerhead.templates.filediff'
 
80
 
 
81
    def get_values(self, path, kwargs, headers):
 
82
        revid = urllib.unquote(self.args[0])
 
83
        compare_revid = urllib.unquote(self.args[1])
 
84
        file_id = urllib.unquote(self.args[2])
 
85
 
 
86
        chunks = diff_chunks_for_file(
 
87
            self._history._branch.repository, file_id, compare_revid, revid)
 
88
 
 
89
        return {
 
90
            'util': util,
 
91
            'chunks': chunks,
 
92
        }