~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/view_ui.py

[bug=758618] Remove the HeadMiddleware in 'bzr serve --http',
until it can be fixed properly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
import bzrlib.errors
24
24
import bzrlib.textfile
 
25
import bzrlib.osutils
25
26
 
26
 
from paste.httpexceptions import HTTPBadRequest, HTTPServerError
 
27
from paste.httpexceptions import HTTPBadRequest, HTTPServerError, HTTPMovedPermanently
27
28
 
28
29
from loggerhead.controllers import TemplatedBranchView
 
30
try:
 
31
    from loggerhead.highlight import highlight
 
32
except ImportError:
 
33
    highlight = None
29
34
from loggerhead import util
30
35
 
31
36
 
32
 
class AnnotateUI(TemplatedBranchView):
33
 
 
34
 
    template_path = 'loggerhead.templates.annotate'
35
 
 
36
 
    def annotate_file(self, file_id, revid):
37
 
        z = time.time()
38
 
        lineno = 1
39
 
        parity = 0
40
 
 
 
37
class ViewUI(TemplatedBranchView):
 
38
 
 
39
    template_path = 'loggerhead.templates.view'
 
40
    
 
41
    def tree_for(self, file_id, revid):
41
42
        file_revid = self._history.get_inventory(revid)[file_id].revision
42
 
        tree = self._history._branch.repository.revision_tree(file_revid)
43
 
 
44
 
        try:
45
 
            bzrlib.textfile.check_text_lines(tree.get_file_lines(file_id))
 
43
        return self._history._branch.repository.revision_tree(file_revid)
 
44
 
 
45
    def text_lines(self, file_id, revid):
 
46
        file_name = os.path.basename(self._history.get_path(revid, file_id))
 
47
        
 
48
        tree = self.tree_for(file_id, revid)
 
49
        file_text = tree.get_file_text(file_id)
 
50
        encoding = 'utf-8'
 
51
        try:
 
52
            file_text = file_text.decode(encoding)
 
53
        except UnicodeDecodeError:
 
54
            encoding = 'iso-8859-15'
 
55
            file_text = file_text.decode(encoding)
 
56
 
 
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;
 
70
 
 
71
    def file_contents(self, file_id, revid):
 
72
        try:
 
73
            file_lines = self.text_lines(file_id, revid)
46
74
        except bzrlib.errors.BinaryFile:
47
 
                # bail out; this isn't displayable text
48
 
                yield util.Container(parity=0, lineno=1, status='same',
49
 
                                     text='(This is a binary file.)',
50
 
                                     change=util.Container())
51
 
        else:
52
 
            change_cache = {}
53
 
 
54
 
            last_line_revid = None
55
 
            for line_revid, text in tree.annotate_iter(file_id):
56
 
                if line_revid == last_line_revid:
57
 
                    # remember which lines have a new revno and which don't
58
 
                    status = 'same'
59
 
                else:
60
 
                    status = 'changed'
61
 
                    parity ^= 1
62
 
                    last_line_revid = line_revid
63
 
                    if line_revid in change_cache:
64
 
                        change = change_cache[line_revid]
65
 
                    else:
66
 
                        change = self._history.get_changes([line_revid])[0]
67
 
                        change_cache[line_revid] = change
68
 
 
69
 
                yield util.Container(
70
 
                    parity=parity, lineno=lineno, status=status,
71
 
                    change=change, text=util.fixed_width(text))
72
 
                lineno += 1
73
 
 
74
 
        self.log.debug('annotate: %r secs' % (time.time() - z))
 
75
            # bail out; this isn't displayable text
 
76
            return ['(This is a binary file.)']
 
77
 
 
78
        return file_lines
75
79
 
76
80
    def get_values(self, path, kwargs, headers):
77
81
        history = self._history
81
85
        file_id = kwargs.get('file_id', None)
82
86
        if (file_id is None) and (path is None):
83
87
            raise HTTPBadRequest('No file_id or filename '
84
 
                                 'provided to annotate')
 
88
                                 'provided to view')
85
89
 
86
90
        if file_id is None:
87
91
            file_id = history.get_file_id(revid, path)
115
119
            raise HTTPServerError('Could not fetch changes')
116
120
        branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
117
121
 
 
122
        if inv[file_id].kind == "directory":
 
123
            raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
 
124
 
118
125
        return {
 
126
            # In AnnotateUI, "annotated" is a generator giving revision
 
127
            # numbers per lines, but the template checks if "annotated" is
 
128
            # true or not before using it, so we have to define it here also.
 
129
            'annotated': False,
119
130
            'revno_url': revno_url,
120
131
            'file_id': file_id,
121
 
            'path': path,
 
132
            'file_path': path,
122
133
            'filename': filename,
123
134
            'navigation': navigation,
124
135
            'change': change,
125
 
            'contents': list(self.annotate_file(file_id, revid)),
 
136
            'contents':  self.file_contents(file_id, revid),
126
137
            'fileview_active': True,
127
138
            'directory_breadcrumbs': directory_breadcrumbs,
128
139
            'branch_breadcrumbs': branch_breadcrumbs,