~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/filediff_ui.py

  • Committer: Michael Hudson
  • Date: 2009-03-18 05:16:32 UTC
  • mfrom: (299.1.21 ajaxy-revision-page)
  • Revision ID: michael.hudson@canonical.com-20090318051632-txkcwcjod7u08l5q
merge ajaxy-revision-page
this makes the initial page load for the revision page much lighter.

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