~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/view_ui.py

  • Committer: Andrew Bennetts
  • Date: 2011-06-28 13:13:05 UTC
  • Revision ID: andrew.bennetts@canonical.com-20110628131305-skv4h2z02z3iw8wc
Extract some refactoring of TemplatedBranchView and BranchWSGIApp from the jsonify branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
#
19
19
 
20
 
import cgi
21
20
import os
22
21
import time
23
22
 
25
24
import bzrlib.textfile
26
25
import bzrlib.osutils
27
26
 
28
 
from paste.httpexceptions import HTTPBadRequest, HTTPServerError
 
27
from paste.httpexceptions import HTTPBadRequest, HTTPServerError, HTTPMovedPermanently
29
28
 
30
29
from loggerhead.controllers import TemplatedBranchView
31
30
try:
35
34
from loggerhead import util
36
35
 
37
36
 
38
 
class AnnotateUI(TemplatedBranchView):
39
 
 
40
 
    template_path = 'loggerhead.templates.annotate'
41
 
 
42
 
    def annotate_file(self, file_id, revid):
43
 
        z = time.time()
44
 
        lineno = 1
45
 
        parity = 0
46
 
 
 
37
class ViewUI(TemplatedBranchView):
 
38
 
 
39
    template_path = 'loggerhead.templates.view'
 
40
    
 
41
    def tree_for(self, file_id, revid):
47
42
        file_revid = self._history.get_inventory(revid)[file_id].revision
48
 
        tree = self._history._branch.repository.revision_tree(file_revid)
 
43
        return self._history._branch.repository.revision_tree(file_revid)
49
44
 
 
45
    def text_lines(self, file_id, revid):
50
46
        file_name = os.path.basename(self._history.get_path(revid, file_id))
51
 
 
 
47
        
 
48
        tree = self.tree_for(file_id, revid)
52
49
        file_text = tree.get_file_text(file_id)
53
50
        encoding = 'utf-8'
54
51
        try:
58
55
            file_text = file_text.decode(encoding)
59
56
 
60
57
        file_lines = bzrlib.osutils.split_lines(file_text)
 
58
        # This can throw bzrlib.errors.BinaryFile (which our caller catches).
 
59
        bzrlib.textfile.check_text_lines(file_lines)
 
60
        
 
61
        if highlight is not None:
 
62
            hl_lines = highlight(file_name, file_text, encoding)
 
63
            # highlight strips off extra newlines at the end of the file.
 
64
            extra_lines = len(file_lines) - len(hl_lines)
 
65
            hl_lines.extend([u''] * extra_lines)
 
66
        else:
 
67
            hl_lines = map(util.html_escape, file_lines)
 
68
        
 
69
        return hl_lines;
61
70
 
 
71
    def file_contents(self, file_id, revid):
62
72
        try:
63
 
            bzrlib.textfile.check_text_lines(file_lines)
 
73
            file_lines = self.text_lines(file_id, revid)
64
74
        except bzrlib.errors.BinaryFile:
65
75
            # bail out; this isn't displayable text
66
 
            yield util.Container(parity=0, lineno=1, status='same',
67
 
                                 text='(This is a binary file.)',
68
 
                                 change=util.Container())
69
 
        else:
70
 
            if highlight is not None:
71
 
                hl_lines = highlight(file_name, file_text, encoding)
72
 
                hl_lines.extend([u''] * (len(file_lines) - len(hl_lines)))
73
 
            else:
74
 
                hl_lines = map(cgi.escape, file_lines)
75
 
 
76
 
            change_cache = {}
77
 
 
78
 
            last_line_revid = None
79
 
            for line_revid, text in tree.annotate_iter(file_id):
80
 
                if line_revid == last_line_revid:
81
 
                    # remember which lines have a new revno and which don't
82
 
                    status = 'same'
83
 
                else:
84
 
                    status = 'changed'
85
 
                    parity ^= 1
86
 
                    last_line_revid = line_revid
87
 
                    if line_revid in change_cache:
88
 
                        change = change_cache[line_revid]
89
 
                    else:
90
 
                        change = self._history.get_changes([line_revid])[0]
91
 
                        change_cache[line_revid] = change
92
 
 
93
 
                yield util.Container(
94
 
                    parity=parity, lineno=lineno, status=status,
95
 
                    change=change, text=hl_lines[lineno - 1])
96
 
                lineno += 1
97
 
 
98
 
        self.log.debug('annotate: %r secs' % (time.time() - z,))
 
76
            return ['(This is a binary file.)']
 
77
 
 
78
        return file_lines
99
79
 
100
80
    def get_values(self, path, kwargs, headers):
101
81
        history = self._history
105
85
        file_id = kwargs.get('file_id', None)
106
86
        if (file_id is None) and (path is None):
107
87
            raise HTTPBadRequest('No file_id or filename '
108
 
                                 'provided to annotate')
 
88
                                 'provided to view')
109
89
 
110
90
        if file_id is None:
111
91
            file_id = history.get_file_id(revid, path)
139
119
            raise HTTPServerError('Could not fetch changes')
140
120
        branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
141
121
 
 
122
        if inv[file_id].kind == "directory":
 
123
            raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
 
124
 
142
125
        return {
 
126
            # In AnnotateUI, "annotated" is a dictionary mapping lines to changes.
 
127
            # We exploit the fact that bool({}) is False when checking whether
 
128
            # we're in "annotated" mode.
 
129
            'annotated': {},
143
130
            'revno_url': revno_url,
144
131
            'file_id': file_id,
145
 
            'path': path,
 
132
            'file_path': path,
146
133
            'filename': filename,
147
134
            'navigation': navigation,
148
135
            'change': change,
149
 
            'contents': list(self.annotate_file(file_id, revid)),
 
136
            'contents':  self.file_contents(file_id, revid),
150
137
            'fileview_active': True,
151
138
            'directory_breadcrumbs': directory_breadcrumbs,
152
139
            'branch_breadcrumbs': branch_breadcrumbs,