~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/filediff_ui.py

  • Committer: Michael Hudson
  • Date: 2008-02-28 04:34:51 UTC
  • mto: This revision was merged to the branch mainline in revision 147.
  • Revision ID: michael.hudson@canonical.com-20080228043451-nuyn35437fuphe9y
more prep

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
 
    supports_json = True
81
 
 
82
 
    def get_values(self, path, kwargs, headers):
83
 
        revid = urllib.unquote(self.args[0])
84
 
        compare_revid = urllib.unquote(self.args[1])
85
 
        file_id = urllib.unquote(self.args[2])
86
 
 
87
 
        chunks = diff_chunks_for_file(
88
 
            self._history._branch.repository, file_id, compare_revid, revid)
89
 
 
90
 
        return {
91
 
            'chunks': chunks,
92
 
        }