~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/view_ui.py

  • Committer: Francesco 'pr0gg3d' Del Degan
  • Date: 2011-08-09 11:03:18 UTC
  • mto: This revision was merged to the branch mainline in revision 454.
  • Revision ID: f.deldegan@pr0gg3d.net-20110809110318-9dp352psllgecydx
Added test against zero-sized files

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#
19
19
 
20
20
import os
21
 
import posixpath
22
 
 
23
 
from paste.httpexceptions import HTTPBadRequest
 
21
import time
 
22
 
 
23
import bzrlib.errors
 
24
import bzrlib.textfile
 
25
import bzrlib.osutils
 
26
 
 
27
from paste.httpexceptions import HTTPBadRequest, HTTPServerError, HTTPMovedPermanently
24
28
 
25
29
from loggerhead.controllers import TemplatedBranchView
 
30
try:
 
31
    from loggerhead.highlight import highlight
 
32
except ImportError:
 
33
    highlight = None
26
34
from loggerhead import util
27
35
 
28
36
 
29
 
def dirname(path):
30
 
    while path.endswith('/'):
31
 
        path = path[:-1]
32
 
    path = posixpath.dirname(path)
33
 
    return path
34
 
 
35
 
class AnnotateUI (TemplatedBranchView):
36
 
 
37
 
    template_path = 'loggerhead.templates.annotate'
38
 
 
39
 
    def get_values(self, h, args, kw, headers):
40
 
        if len(args) > 0:
41
 
            revid = h.fix_revid(args[0])
 
37
class ViewUI(TemplatedBranchView):
 
38
 
 
39
    template_path = 'loggerhead.templates.view'
 
40
    
 
41
    def tree_for(self, file_id, revid):
 
42
        file_revid = self._history.get_inventory(revid)[file_id].revision
 
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)
42
66
        else:
43
 
            revid = h.last_revid
44
 
 
45
 
        path = None
46
 
        if len(args) > 1:
47
 
            path = '/'.join(args[1:])
48
 
            if not path.startswith('/'):
49
 
                path = '/' + path
50
 
 
51
 
        file_id = kw.get('file_id', None)
 
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)
 
74
        except bzrlib.errors.BinaryFile:
 
75
            # bail out; this isn't displayable text
 
76
            return ['(This is a binary file.)']
 
77
 
 
78
        return file_lines
 
79
 
 
80
    def get_values(self, path, kwargs, headers):
 
81
        history = self._history
 
82
        branch = history._branch
 
83
        revid = self.get_revid()
 
84
        revid = history.fix_revid(revid)
 
85
        file_id = kwargs.get('file_id', None)
52
86
        if (file_id is None) and (path is None):
53
 
            raise HTTPBadRequest('No file_id or filename provided to annotate')
 
87
            raise HTTPBadRequest('No file_id or filename '
 
88
                                 'provided to view')
54
89
 
55
90
        if file_id is None:
56
 
            file_id = h.get_file_id(revid, path)
 
91
            file_id = history.get_file_id(revid, path)
57
92
 
58
93
        # no navbar for revisions
59
94
        navigation = util.Container()
60
95
 
61
96
        if path is None:
62
 
            path = h.get_path(revid, file_id)
 
97
            path = history.get_path(revid, file_id)
63
98
        filename = os.path.basename(path)
64
99
 
 
100
        change = history.get_changes([ revid ])[0]
 
101
        # If we're looking at the tip, use head: in the URL instead
 
102
        if revid == branch.last_revision():
 
103
            revno_url = 'head:'
 
104
        else:
 
105
            revno_url = history.get_revno(revid)
 
106
 
 
107
        # Directory Breadcrumbs
 
108
        directory_breadcrumbs = (
 
109
            util.directory_breadcrumbs(
 
110
                self._branch.friendly_name,
 
111
                self._branch.is_root,
 
112
                'files'))
 
113
 
 
114
        # Create breadcrumb trail for the path within the branch
 
115
        try:
 
116
            inv = history.get_inventory(revid)
 
117
        except:
 
118
            self.log.exception('Exception fetching changes')
 
119
            raise HTTPServerError('Could not fetch changes')
 
120
        branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
 
121
 
 
122
        if inv[file_id].kind == "directory":
 
123
            raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
 
124
 
65
125
        return {
66
 
            'revid': revid,
 
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': {},
 
130
            'revno_url': revno_url,
67
131
            'file_id': file_id,
68
 
            'path': path,
 
132
            'file_path': path,
69
133
            'filename': filename,
70
134
            'navigation': navigation,
71
 
            'change': h.get_changes([ revid ])[0],
72
 
            'contents': list(h.annotate_file(file_id, revid)),
 
135
            'change': change,
 
136
            'contents':  self.file_contents(file_id, revid),
73
137
            'fileview_active': True,
 
138
            'directory_breadcrumbs': directory_breadcrumbs,
 
139
            'branch_breadcrumbs': branch_breadcrumbs,
74
140
        }