~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/view_ui.py

  • Committer: John Arbash Meinel
  • Date: 2011-03-16 14:43:36 UTC
  • mfrom: (411.4.8 page_loading)
  • Revision ID: john@arbash-meinel.com-20110316144336-5or6keig1cbagois
Merge the page-loading change.

When /changes page is loaded, don't walk the whole ancestry during 'get_revids_from'.
Instead, only walk enough history to generate the actual page, plus a little bit more
to get the link for the 'next' page.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import bzrlib.textfile
26
26
import bzrlib.osutils
27
27
 
28
 
from paste.httpexceptions import HTTPBadRequest, HTTPServerError
 
28
from paste.httpexceptions import HTTPBadRequest, HTTPServerError, HTTPMovedPermanently
29
29
 
30
30
from loggerhead.controllers import TemplatedBranchView
31
31
try:
35
35
from loggerhead import util
36
36
 
37
37
 
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
 
 
 
38
class ViewUI(TemplatedBranchView):
 
39
 
 
40
    template_path = 'loggerhead.templates.view'
 
41
    
 
42
    def tree_for(self, file_id, revid):
47
43
        file_revid = self._history.get_inventory(revid)[file_id].revision
48
 
        tree = self._history._branch.repository.revision_tree(file_revid)
 
44
        return self._history._branch.repository.revision_tree(file_revid)
49
45
 
 
46
    def text_lines(self, file_id, revid):
50
47
        file_name = os.path.basename(self._history.get_path(revid, file_id))
51
 
 
 
48
        
 
49
        tree = self.tree_for(file_id, revid)
52
50
        file_text = tree.get_file_text(file_id)
53
51
        encoding = 'utf-8'
54
52
        try:
58
56
            file_text = file_text.decode(encoding)
59
57
 
60
58
        file_lines = bzrlib.osutils.split_lines(file_text)
 
59
        # This can throw bzrlib.errors.BinaryFile (which our caller catches).
 
60
        bzrlib.textfile.check_text_lines(file_lines)
 
61
        
 
62
        if highlight is not None:
 
63
            hl_lines = highlight(file_name, file_text, encoding)
 
64
            # highlight strips off extra newlines at the end of the file.
 
65
            extra_lines = len(file_lines) - len(hl_lines)
 
66
            hl_lines.extend([u''] * extra_lines)
 
67
        else:
 
68
            hl_lines = map(cgi.escape, file_lines)
 
69
        
 
70
        return hl_lines;
61
71
 
 
72
    def file_contents(self, file_id, revid):
62
73
        try:
63
 
            bzrlib.textfile.check_text_lines(file_lines)
 
74
            file_lines = self.text_lines(file_id, revid)
64
75
        except bzrlib.errors.BinaryFile:
65
 
                # 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
            # bail out; this isn't displayable text
 
77
            return ['(This is a binary file.)']
 
78
 
 
79
        return file_lines
99
80
 
100
81
    def get_values(self, path, kwargs, headers):
101
82
        history = self._history
105
86
        file_id = kwargs.get('file_id', None)
106
87
        if (file_id is None) and (path is None):
107
88
            raise HTTPBadRequest('No file_id or filename '
108
 
                                 'provided to annotate')
 
89
                                 'provided to view')
109
90
 
110
91
        if file_id is None:
111
92
            file_id = history.get_file_id(revid, path)
139
120
            raise HTTPServerError('Could not fetch changes')
140
121
        branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
141
122
 
 
123
        if inv[file_id].kind == "directory":
 
124
            raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
 
125
 
142
126
        return {
 
127
            # In AnnotateUI, "annotated" is a generator giving revision
 
128
            # numbers per lines, but the template checks if "annotated" is
 
129
            # true or not before using it, so we have to define it here also.
 
130
            'annotated': False,
143
131
            'revno_url': revno_url,
144
132
            'file_id': file_id,
145
 
            'path': path,
 
133
            'file_path': path,
146
134
            'filename': filename,
147
135
            'navigation': navigation,
148
136
            'change': change,
149
 
            'contents': list(self.annotate_file(file_id, revid)),
 
137
            'contents':  self.file_contents(file_id, revid),
150
138
            'fileview_active': True,
151
139
            'directory_breadcrumbs': directory_breadcrumbs,
152
140
            'branch_breadcrumbs': branch_breadcrumbs,