17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
import bzrlib.textfile
26
from paste.httpexceptions import HTTPBadRequest, HTTPServerError
28
from loggerhead.controllers import TemplatedBranchView
30
from loggerhead.highlight import highlight
26
from cherrypy import HTTPError
33
28
from loggerhead import util
36
class AnnotateUI(TemplatedBranchView):
38
template_path = 'loggerhead.templates.annotate'
40
def annotate_file(self, file_id, revid):
31
log = logging.getLogger("loggerhead.controllers")
34
while path.endswith('/'):
36
path = posixpath.dirname(path)
40
class AnnotateUI (object):
42
def __init__(self, branch):
47
@util.strip_whitespace
48
@turbogears.expose(html='loggerhead.templates.annotate')
49
def default(self, *args, **kw):
45
file_revid = self._history.get_inventory(revid)[file_id].revision
46
tree = self._history._branch.repository.revision_tree(file_revid)
48
file_name = os.path.basename(self._history.get_path(revid, file_id))
51
h = self._branch.get_history()
51
file_lines = tree.get_file_lines(file_id)
52
bzrlib.textfile.check_text_lines(file_lines)
53
except bzrlib.errors.BinaryFile:
54
# bail out; this isn't displayable text
55
yield util.Container(parity=0, lineno=1, status='same',
56
text='(This is a binary file.)',
57
change=util.Container())
59
if highlight is not None:
60
hl_lines = highlight(file_name, ''.join(file_lines))
61
hl_lines.extend([u''] * (len(file_lines) - len(hl_lines)))
57
revid = h.fix_revid(args[0])
67
last_line_revid = None
68
for line_revid, text in tree.annotate_iter(file_id):
69
if line_revid == last_line_revid:
70
# remember which lines have a new revno and which don't
75
last_line_revid = line_revid
76
if line_revid in change_cache:
77
change = change_cache[line_revid]
79
change = self._history.get_changes([line_revid])[0]
80
change_cache[line_revid] = change
83
parity=parity, lineno=lineno, status=status,
84
change=change, text=hl_lines[lineno - 1])
87
self.log.debug('annotate: %r secs' % (time.time() - z))
89
def get_values(self, path, kwargs, headers):
90
history = self._history
91
branch = history._branch
92
revid = self.get_revid()
93
revid = history.fix_revid(revid)
94
file_id = kwargs.get('file_id', None)
95
if (file_id is None) and (path is None):
96
raise HTTPBadRequest('No file_id or filename '
97
'provided to annotate')
100
file_id = history.get_file_id(revid, path)
102
# no navbar for revisions
103
navigation = util.Container()
106
path = history.get_path(revid, file_id)
107
filename = os.path.basename(path)
109
change = history.get_changes([ revid ])[0]
110
# If we're looking at the tip, use head: in the URL instead
111
if revid == branch.last_revision():
114
revno_url = history.get_revno(revid)
116
# Directory Breadcrumbs
117
directory_breadcrumbs = (
118
util.directory_breadcrumbs(
119
self._branch.friendly_name,
120
self._branch.is_root,
123
# Create breadcrumb trail for the path within the branch
125
inv = history.get_inventory(revid)
127
self.log.exception('Exception fetching changes')
128
raise HTTPServerError('Could not fetch changes')
129
branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
132
'revno_url': revno_url,
135
'filename': filename,
136
'navigation': navigation,
138
'contents': list(self.annotate_file(file_id, revid)),
139
'fileview_active': True,
140
'directory_breadcrumbs': directory_breadcrumbs,
141
'branch_breadcrumbs': branch_breadcrumbs,
63
path = '/'.join(args[1:])
64
if not path.startswith('/'):
67
file_id = kw.get('file_id', None)
68
if (file_id is None) and (path is None):
69
raise HTTPError(400, 'No file_id or filename provided to annotate')
72
file_id = h.get_file_id(revid, path)
74
# no navbar for revisions
75
navigation = util.Container()
78
path = h.get_path(revid, file_id)
79
filename = os.path.basename(path)
82
'branch': self._branch,
89
'navigation': navigation,
90
'change': h.get_changes([ revid ])[0],
91
'contents': list(h.annotate_file(file_id, revid)),
94
self.log.info('/annotate: %r secs' % (time.time() - z,))