~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/diff_ui.py

  • Committer: Robert Collins
  • Date: 2012-02-02 05:07:53 UTC
  • mfrom: (464.1.1 mod-wsgi)
  • Revision ID: robertc@robertcollins.net-20120202050753-2d8f8r6m24lglbz5
    - Add a script and documentation for running under mod_wsgi.
      (Stuart Colville, Toshio Kuratomi)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2011 Canonical Ltd.
 
2
#                     (Authored by Martin Albisetti <argentina@gmail.com>)
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
#
 
18
 
 
19
from cStringIO import StringIO
 
20
import time
 
21
 
 
22
from paste.request import path_info_pop
 
23
 
 
24
from bzrlib.diff import show_diff_trees
 
25
from bzrlib.revision import NULL_REVISION
 
26
 
 
27
from loggerhead.controllers import TemplatedBranchView
 
28
 
 
29
 
 
30
class DiffUI(TemplatedBranchView):
 
31
    """Class to output a diff for a single file or revisions."""
 
32
 
 
33
    def __call__(self, environ, start_response):
 
34
        # /diff/<rev_id>/<rev_id>
 
35
        """Default method called from /diff URL."""
 
36
        z = time.time()
 
37
 
 
38
        args = []
 
39
        while True:
 
40
            arg = path_info_pop(environ)
 
41
            if arg is None:
 
42
                break
 
43
            args.append(arg)
 
44
 
 
45
        revid_from = args[0]
 
46
        # Convert a revno to a revid if we get a revno
 
47
        revid_from = self._history.fix_revid(revid_from)
 
48
        change = self._history.get_changes([revid_from])[0]
 
49
 
 
50
        if len(args) == 2:
 
51
            revid_to = self._history.fix_revid(args[1])
 
52
        elif len(change.parents) == 0:
 
53
            revid_to = NULL_REVISION
 
54
        else:
 
55
            revid_to = change.parents[0].revid
 
56
 
 
57
        repo = self._branch.branch.repository
 
58
        revtree1 = repo.revision_tree(revid_to)
 
59
        revtree2 = repo.revision_tree(revid_from)
 
60
 
 
61
        diff_content_stream = StringIO()
 
62
        show_diff_trees(revtree1, revtree2, diff_content_stream,
 
63
                        old_label='', new_label='')
 
64
 
 
65
        content = diff_content_stream.getvalue()
 
66
 
 
67
        self.log.info('/diff %r:%r in %r secs' % (revid_from, revid_to,
 
68
                                                  time.time() - z))
 
69
 
 
70
        revno1 = self._history.get_revno(revid_from)
 
71
        revno2 = self._history.get_revno(revid_to)
 
72
        filename = '%s_%s.diff' % (revno1, revno2)
 
73
        headers = [
 
74
            ('Content-Type', 'application/octet-stream'),
 
75
            ('Content-Length', str(len(content))),
 
76
            ('Content-Disposition', 'attachment; filename=%s' % (filename,)),
 
77
            ]
 
78
        start_response('200 OK', headers)
 
79
        return [content]