35
34
from loggerhead import util
38
class AnnotateUI(TemplatedBranchView):
40
template_path = 'loggerhead.templates.annotate'
42
def annotate_file(self, file_id, revid):
37
class ViewUI(TemplatedBranchView):
39
template_path = 'loggerhead.templates.view'
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)
45
def text_lines(self, file_id, revid):
50
46
file_name = os.path.basename(self._history.get_path(revid, file_id))
48
tree = self.tree_for(file_id, revid)
52
49
file_text = tree.get_file_text(file_id)
58
55
file_text = file_text.decode(encoding)
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)
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)
67
hl_lines = map(util.html_escape, file_lines)
71
def file_contents(self, file_id, revid):
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())
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)))
74
hl_lines = map(cgi.escape, file_lines)
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
86
last_line_revid = line_revid
87
if line_revid in change_cache:
88
change = change_cache[line_revid]
90
change = self._history.get_changes([line_revid])[0]
91
change_cache[line_revid] = change
94
parity=parity, lineno=lineno, status=status,
95
change=change, text=hl_lines[lineno - 1])
98
self.log.debug('annotate: %r secs' % (time.time() - z,))
76
return ['(This is a binary file.)']
100
80
def get_values(self, path, kwargs, headers):
101
81
history = self._history
139
119
raise HTTPServerError('Could not fetch changes')
140
120
branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
122
if inv[file_id].kind == "directory":
123
raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
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.
143
130
'revno_url': revno_url,
144
131
'file_id': file_id,
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,