Merge lp:~mkanat/loggerhead/launchpad into lp:~launchpad-pqm/loggerhead/devel

Proposed by Max Kanat-Alexander
Status: Merged
Merged at revision: 178
Proposed branch: lp:~mkanat/loggerhead/launchpad
Merge into: lp:~launchpad-pqm/loggerhead/devel
Diff against target: 598 lines (+211/-101)
15 files modified
NEWS (+2/-2)
__init__.py (+19/-7)
info.py (+13/-0)
loggerhead/__init__.py (+1/-1)
loggerhead/apps/branch.py (+2/-0)
loggerhead/controllers/annotate_ui.py (+54/-0)
loggerhead/controllers/view_ui.py (+33/-48)
loggerhead/highlight.py (+4/-2)
loggerhead/static/css/view.css (+14/-12)
loggerhead/templatefunctions.py (+2/-2)
loggerhead/templates/inventory.pt (+8/-8)
loggerhead/templates/revision.pt (+2/-2)
loggerhead/templates/view.pt (+30/-17)
loggerhead/tests/__init__.py (+26/-0)
loggerhead/trace.py (+1/-0)
To merge this branch: bzr merge lp:~mkanat/loggerhead/launchpad
Reviewer Review Type Date Requested Status
Michael Hudson-Doyle Approve
Launchpad PQM Bot Pending
Review via email: mp+42338@code.launchpad.net

Description of the change

Brings in the fix for Bug 568148, which gives us some important performance improvements in the default file view that we believe will make a significant difference for Launchpad. In addition, this syncs up codebrowse with the 1.18 stable branch of loggerhead (although that doesn't bring in any code that will actually affect LP, as far as I know).

To post a comment you must log in.
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

I approve of this branch, but can't set the mp status. Oh well. Do you want me to merge it too?

review: Approve
Revision history for this message
Max Kanat-Alexander (mkanat) wrote :

Yeah, if you could merge it, that would be great.

lp:~mkanat/loggerhead/launchpad updated
178. By Launchpad PQM Bot

[r=mwhudson] bring in the fix for bug 568148,
 which stops the default file content view being the annotated view

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2010-05-10 13:48:25 +0000
+++ NEWS 2010-12-01 08:41:33 +0000
@@ -1,8 +1,8 @@
1What's changed in loggerhead?1What's changed in loggerhead?
2=============================2=============================
33
4dev [future]41.18 [10Nov2010]
5------------5----------------
66
7 - Syntax highlighting is no longer applied for files greater than 512K,7 - Syntax highlighting is no longer applied for files greater than 512K,
8 reducing codebrowse.launchpad.net overloading.8 reducing codebrowse.launchpad.net overloading.
99
=== modified file '__init__.py'
--- __init__.py 2010-04-22 08:52:59 +0000
+++ __init__.py 2010-12-01 08:41:33 +0000
@@ -30,15 +30,16 @@
30starts a web server to browse the contents of a branch.30starts a web server to browse the contents of a branch.
31"""31"""
3232
33version_info = (1, 17, 0)33from info import (
34 bzr_plugin_version as version_info,
35 bzr_compatible_versions,
36 )
3437
35if __name__ == 'bzrlib.plugins.loggerhead':38if __name__ == 'bzrlib.plugins.loggerhead':
36 import bzrlib39 import bzrlib
37 from bzrlib.api import require_any_api40 from bzrlib.api import require_any_api
3841
39 require_any_api(bzrlib, [42 require_any_api(bzrlib, bzr_compatible_versions)
40 (1, 13, 0), (1, 15, 0), (1, 16, 0), (1, 17, 0), (1, 18, 0),
41 (2, 0, 0), (2, 1, 0), (2, 2, 0)])
4243
43 # NB: Normally plugins should lazily load almost everything, but this44 # NB: Normally plugins should lazily load almost everything, but this
44 # seems reasonable to have in-line here: bzrlib.commands and options are45 # seems reasonable to have in-line here: bzrlib.commands and options are
@@ -69,10 +70,9 @@
69 logging.getLogger('simpleTAL').addHandler(handler)70 logging.getLogger('simpleTAL').addHandler(handler)
70 logging.getLogger('simpleTALES').addHandler(handler)71 logging.getLogger('simpleTALES').addHandler(handler)
7172
72 def serve_http(transport, host=None, port=None, inet=None):
73 from paste.httpexceptions import HTTPExceptionHandler
74 from paste.httpserver import serve
7573
74 def _ensure_loggerhead_path():
75 """Ensure that you can 'import loggerhead' and get the root."""
76 # loggerhead internal code will try to 'import loggerhead', so76 # loggerhead internal code will try to 'import loggerhead', so
77 # let's put it on the path if we can't find it in the existing path77 # let's put it on the path if we can't find it in the existing path
78 try:78 try:
@@ -81,6 +81,12 @@
81 import os.path, sys81 import os.path, sys
82 sys.path.append(os.path.dirname(__file__))82 sys.path.append(os.path.dirname(__file__))
8383
84 def serve_http(transport, host=None, port=None, inet=None):
85 from paste.httpexceptions import HTTPExceptionHandler
86 from paste.httpserver import serve
87
88 _ensure_loggerhead_path()
89
84 from loggerhead.apps.transport import BranchesFromTransportRoot90 from loggerhead.apps.transport import BranchesFromTransportRoot
85 from loggerhead.config import LoggerheadConfig91 from loggerhead.config import LoggerheadConfig
8692
@@ -132,3 +138,9 @@
132 super(cmd_serve, self).run(*args, **kw)138 super(cmd_serve, self).run(*args, **kw)
133139
134 register_command(cmd_serve)140 register_command(cmd_serve)
141
142 def load_tests(standard_tests, module, loader):
143 _ensure_loggerhead_path()
144 standard_tests.addTests(loader.loadTestsFromModuleNames(
145 ['bzrlib.plugins.loggerhead.loggerhead.tests']))
146 return standard_tests
135147
=== added file 'info.py'
--- info.py 1970-01-01 00:00:00 +0000
+++ info.py 2010-12-01 08:41:33 +0000
@@ -0,0 +1,13 @@
1#!/usr/bin/env python
2# API Info for loggerhead
3
4bzr_plugin_name = "loggerhead"
5
6bzr_plugin_version = (1, 18, 0)
7
8bzr_compatible_versions = [
9 (1, 17, 0), (1, 18, 0), (2, 0, 0), (2, 1, 0), (2, 2, 0), (2, 3, 0)]
10
11bzr_minimum_version = bzr_compatible_versions[0]
12
13bzr_maximum_version = bzr_compatible_versions[-1]
014
=== modified file 'loggerhead/__init__.py'
--- loggerhead/__init__.py 2009-08-20 13:30:37 +0000
+++ loggerhead/__init__.py 2010-12-01 08:41:33 +0000
@@ -22,7 +22,7 @@
2222
23import pkg_resources23import pkg_resources
2424
25__version__ = '1.17'25__version__ = '1.18'
26required_bzrlib = (1, 17)26required_bzrlib = (1, 17)
2727
28pkg_resources.get_distribution('Paste>=1.6')28pkg_resources.get_distribution('Paste>=1.6')
2929
=== modified file 'loggerhead/apps/branch.py'
--- loggerhead/apps/branch.py 2010-05-05 18:28:54 +0000
+++ loggerhead/apps/branch.py 2010-12-01 08:41:33 +0000
@@ -29,6 +29,7 @@
2929
30from loggerhead.apps import static_app30from loggerhead.apps import static_app
31from loggerhead.controllers.annotate_ui import AnnotateUI31from loggerhead.controllers.annotate_ui import AnnotateUI
32from loggerhead.controllers.view_ui import ViewUI
32from loggerhead.controllers.atom_ui import AtomUI33from loggerhead.controllers.atom_ui import AtomUI
33from loggerhead.controllers.changelog_ui import ChangeLogUI34from loggerhead.controllers.changelog_ui import ChangeLogUI
34from loggerhead.controllers.diff_ui import DiffUI35from loggerhead.controllers.diff_ui import DiffUI
@@ -124,6 +125,7 @@
124 'files': InventoryUI,125 'files': InventoryUI,
125 'revision': RevisionUI,126 'revision': RevisionUI,
126 'search': SearchUI,127 'search': SearchUI,
128 'view': ViewUI,
127 }129 }
128130
129 def last_updated(self):131 def last_updated(self):
130132
=== added file 'loggerhead/controllers/annotate_ui.py'
--- loggerhead/controllers/annotate_ui.py 1970-01-01 00:00:00 +0000
+++ loggerhead/controllers/annotate_ui.py 2010-12-01 08:41:33 +0000
@@ -0,0 +1,54 @@
1#
2# Copyright (C) 2010 Canonical Ltd.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#
18
19from loggerhead.controllers.view_ui import ViewUI
20from loggerhead import util
21
22class AnnotateUI(ViewUI):
23
24 def annotate_file(self, info):
25 file_id = info['file_id']
26 revid = info['change'].revid
27
28 tree = self.tree_for(file_id, revid)
29
30 change_cache = {}
31 last_line_revid = None
32 parity = 1
33 for line_revid, text in tree.annotate_iter(file_id):
34 if line_revid == last_line_revid:
35 # remember which lines have a new revno and which don't
36 new_rev = False
37 else:
38 new_rev = True
39 parity ^= 1
40 last_line_revid = line_revid
41 if line_revid in change_cache:
42 change = change_cache[line_revid]
43 else:
44 change = self._history.get_changes([line_revid])[0]
45 change_cache[line_revid] = change
46
47 yield util.Container(
48 parity=parity, new_rev=new_rev, change=change)
49
50 def get_values(self, path, kwargs, headers):
51 values = super(AnnotateUI, self).get_values(path, kwargs, headers)
52 values['annotated'] = self.annotate_file(values)
53
54 return values
055
=== renamed file 'loggerhead/controllers/annotate_ui.py' => 'loggerhead/controllers/view_ui.py'
--- loggerhead/controllers/annotate_ui.py 2009-10-17 06:35:33 +0000
+++ loggerhead/controllers/view_ui.py 2010-12-01 08:41:33 +0000
@@ -35,20 +35,18 @@
35from loggerhead import util35from loggerhead import util
3636
3737
38class AnnotateUI(TemplatedBranchView):38class ViewUI(TemplatedBranchView):
3939
40 template_path = 'loggerhead.templates.annotate'40 template_path = 'loggerhead.templates.view'
4141
42 def annotate_file(self, file_id, revid):42 def tree_for(self, file_id, revid):
43 z = time.time()
44 lineno = 1
45 parity = 0
46
47 file_revid = self._history.get_inventory(revid)[file_id].revision43 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)
4945
46 def text_lines(self, file_id, revid):
50 file_name = os.path.basename(self._history.get_path(revid, file_id))47 file_name = os.path.basename(self._history.get_path(revid, file_id))
5148
49 tree = self.tree_for(file_id, revid)
52 file_text = tree.get_file_text(file_id)50 file_text = tree.get_file_text(file_id)
53 encoding = 'utf-8'51 encoding = 'utf-8'
54 try:52 try:
@@ -58,44 +56,27 @@
58 file_text = file_text.decode(encoding)56 file_text = file_text.decode(encoding)
5957
60 file_lines = bzrlib.osutils.split_lines(file_text)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;
6171
72 def file_contents(self, file_id, revid):
62 try:73 try:
63 bzrlib.textfile.check_text_lines(file_lines)74 file_lines = self.text_lines(file_id, revid)
64 except bzrlib.errors.BinaryFile:75 except bzrlib.errors.BinaryFile:
65 # bail out; this isn't displayable text76 # bail out; this isn't displayable text
66 yield util.Container(parity=0, lineno=1, status='same',77 return ['(This is a binary file.)']
67 text='(This is a binary file.)',78
68 change=util.Container())79 return file_lines
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,))
9980
100 def get_values(self, path, kwargs, headers):81 def get_values(self, path, kwargs, headers):
101 history = self._history82 history = self._history
@@ -105,7 +86,7 @@
105 file_id = kwargs.get('file_id', None)86 file_id = kwargs.get('file_id', None)
106 if (file_id is None) and (path is None):87 if (file_id is None) and (path is None):
107 raise HTTPBadRequest('No file_id or filename '88 raise HTTPBadRequest('No file_id or filename '
108 'provided to annotate')89 'provided to view')
10990
110 if file_id is None:91 if file_id is None:
111 file_id = history.get_file_id(revid, path)92 file_id = history.get_file_id(revid, path)
@@ -140,13 +121,17 @@
140 branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')121 branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
141122
142 return {123 return {
124 # In AnnotateUI, "annotated" is a generator giving revision
125 # numbers per lines, but the template checks if "annotated" is
126 # true or not before using it, so we have to define it here also.
127 'annotated': False,
143 'revno_url': revno_url,128 'revno_url': revno_url,
144 'file_id': file_id,129 'file_id': file_id,
145 'path': path,130 'file_path': path,
146 'filename': filename,131 'filename': filename,
147 'navigation': navigation,132 'navigation': navigation,
148 'change': change,133 'change': change,
149 'contents': list(self.annotate_file(file_id, revid)),134 'contents': self.file_contents(file_id, revid),
150 'fileview_active': True,135 'fileview_active': True,
151 'directory_breadcrumbs': directory_breadcrumbs,136 'directory_breadcrumbs': directory_breadcrumbs,
152 'branch_breadcrumbs': branch_breadcrumbs,137 'branch_breadcrumbs': branch_breadcrumbs,
153138
=== modified file 'loggerhead/highlight.py'
--- loggerhead/highlight.py 2010-04-22 03:23:55 +0000
+++ loggerhead/highlight.py 2010-12-01 08:41:33 +0000
@@ -16,6 +16,7 @@
16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA16# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17#17#
1818
19import bzrlib.osutils
19import cgi20import cgi
2021
21from pygments import highlight as _highlight_func22from pygments import highlight as _highlight_func
@@ -36,7 +37,7 @@
36 """37 """
3738
38 if len(text) > MAX_HIGHLIGHT_SIZE:39 if len(text) > MAX_HIGHLIGHT_SIZE:
39 return map(cgi.escape, text.split('\n'))40 return map(cgi.escape, bzrlib.osutils.split_lines(text))
4041
41 formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-')42 formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-')
4243
@@ -48,6 +49,7 @@
48 except (ClassNotFound, ValueError):49 except (ClassNotFound, ValueError):
49 lexer = TextLexer(encoding=encoding)50 lexer = TextLexer(encoding=encoding)
5051
51 hl_lines = _highlight_func(text, lexer, formatter).split('\n')52 hl_lines = _highlight_func(text, lexer, formatter)
53 hl_lines = bzrlib.osutils.split_lines(hl_lines)
5254
53 return hl_lines55 return hl_lines
5456
=== renamed file 'loggerhead/static/css/annotate.css' => 'loggerhead/static/css/view.css'
--- loggerhead/static/css/annotate.css 2009-04-30 10:39:05 +0000
+++ loggerhead/static/css/view.css 2010-12-01 08:41:33 +0000
@@ -1,29 +1,31 @@
1/*table*/1/*table*/
2.annoLineTit, .annoLine, .annoRevTit, .annoRev, .annoComm, .annoCommTit, .annoContTit, .annoCont {2.viewLineTit, .viewLine, .viewRevTit, .viewRev,
3 width:45px;3.viewContTit, .viewCont
4{
4 border:1px solid #d2d2d2;5 border:1px solid #d2d2d2;
5}6}
6.annoLine, .annoRev, .annoComm, .annoCont {7.viewLine, .viewRev, .viewComm, .viewCont {
7 border:none;8 border:none;
8}9}
9.annoLine {10.viewLine, .viewLineTit {
11 padding-right: .2em;
12}
13.viewLine {
10 width:37px;14 width:37px;
11}15}
12.annoContTit, .annoCont {16.viewContTit, .viewCont {
13 width:auto;17 width:auto;
18 padding-left: .3em;
14}19}
15.annoRevTit, .annoRev {20.viewRevTit, .viewRev {
16 width:70px;21 width:70px;
17 text-align:center;22 text-align:center;
18}23}
19.annoComm, .annoCommTit {24.viewLine, .viewCont {
20 width:200px;
21}
22.annoLine, .annoCont {
23 font:normal 12px/normal monospace;25 font:normal 12px/normal monospace;
24 whitespace: pre;26 whitespace: pre;
25}27}
26.annoCont pre { margin: 0; }28.viewCont pre { margin: 0; }
27.annoLine {29.viewLine {
28 text-align:right;30 text-align:right;
29}31}
3032
=== modified file 'loggerhead/templatefunctions.py'
--- loggerhead/templatefunctions.py 2009-10-17 08:47:38 +0000
+++ loggerhead/templatefunctions.py 2010-12-01 08:41:33 +0000
@@ -121,9 +121,9 @@
121121
122122
123@templatefunc123@templatefunc
124def annotate_link(url, revno, path):124def view_link(url, revno, path):
125 return '<a href="%s" title="Annotate %s">%s</a>' % (125 return '<a href="%s" title="Annotate %s">%s</a>' % (
126 url(['/annotate', revno, path]), cgi.escape(path), cgi.escape(path))126 url(['/view', revno, path]), cgi.escape(path), cgi.escape(path))
127127
128@templatefunc128@templatefunc
129def revision_link(url, revno, path, frag=''):129def revision_link(url, revno, path, frag=''):
130130
=== modified file 'loggerhead/templates/inventory.pt'
--- loggerhead/templates/inventory.pt 2009-10-17 06:55:25 +0000
+++ loggerhead/templates/inventory.pt 2010-12-01 08:41:33 +0000
@@ -89,11 +89,11 @@
8989
90 <!-- Show this if it's a symlink -->90 <!-- Show this if it's a symlink -->
91 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='symlink'">91 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='symlink'">
92 <td class="autcell"><a tal:attributes="href python:url(['/annotate', change.revno, file.absolutepath])">92 <td class="autcell"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])">
93 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_flecha.gif')" alt="Symlink" />93 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_flecha.gif')" alt="Symlink" />
94 </a>94 </a>
9595
96 <a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath])"96 <a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])"
97 tal:content="file/filename" class="link"></a>97 tal:content="file/filename" class="link"></a>
98 </td>98 </td>
99 <td class="date"><a tal:attributes="href python:url(['/revision', file.change.revno]);99 <td class="date"><a tal:attributes="href python:url(['/revision', file.change.revno]);
@@ -113,17 +113,17 @@
113113
114 <!-- Show this if it's a regular file -->114 <!-- Show this if it's a regular file -->
115 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='file'">115 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='file'">
116 <td class="autcell"><a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath])">116 <td class="autcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])">
117 <img tal:attributes="src python:branch.static_url('/static/images/ico_file.gif');117 <img tal:attributes="src python:branch.static_url('/static/images/ico_file.gif');
118 title string:Annotate ${file/filename}"118 title string:View ${file/filename}"
119 tal:condition="python:file.executable is False" />119 tal:condition="python:file.executable is False" />
120 <!-- Show a different icon id the file executable -->120 <!-- Show a different icon id the file executable -->
121 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_modify.gif');121 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_modify.gif');
122 title string:Annotate ${file/filename}"122 title string:View ${file/filename}"
123 tal:condition="python:file.executable is True" alt="File" />123 tal:condition="python:file.executable is True" alt="File" />
124 </a>124 </a>
125125
126 <a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath])"126 <a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])"
127 tal:content="file/filename" class="link"></a></td>127 tal:content="file/filename" class="link"></a></td>
128 <td class="date"><a tal:attributes="href python:url(['/revision', file.change.revno]);128 <td class="date"><a tal:attributes="href python:url(['/revision', file.change.revno]);
129 title string:Show revision ${file/change/revno}"129 title string:Show revision ${file/change/revno}"
@@ -131,8 +131,8 @@
131 </td>131 </td>
132 <td class="date" tal:content="python:util.date_time(file.change.date)"></td>132 <td class="date" tal:content="python:util.date_time(file.change.date)"></td>
133 <td class="timedate2" tal:content="python:util.human_size(file.size)"></td>133 <td class="timedate2" tal:content="python:util.human_size(file.size)"></td>
134 <td class="expcell"><a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath]);134 <td class="expcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath]);
135 title string:Annotate ${file/filename}">135 title string:View ${file/filename}">
136 <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" />136 <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" />
137 </a>137 </a>
138 </td>138 </td>
139139
=== modified file 'loggerhead/templates/revision.pt'
--- loggerhead/templates/revision.pt 2009-07-21 04:39:33 +0000
+++ loggerhead/templates/revision.pt 2010-12-01 08:41:33 +0000
@@ -41,7 +41,7 @@
41 </tal:compare-to>41 </tal:compare-to>
42 </span>42 </span>
43 <span class="breadcrumb" tal:condition="specific_path">43 <span class="breadcrumb" tal:condition="specific_path">
44 : <tal:annotate content="structure python:annotate_link(url, change.revno, specific_path)" />44 : <tal:annotate content="structure python:view_link(url, change.revno, specific_path)" />
45 </span>45 </span>
46 </h1>46 </h1>
47 <tal:branch-info replace="structure python:branchinfo(branch)" />47 <tal:branch-info replace="structure python:branchinfo(branch)" />
@@ -54,7 +54,7 @@
54 </a>54 </a>
55 </p>55 </p>
56 <p tal:condition="specific_path">56 <p tal:condition="specific_path">
57 Viewing changes to <tal:annotate content="structure python:annotate_link(url, change.revno, specific_path)" />57 Viewing changes to <tal:annotate content="structure python:view_link(url, change.revno, specific_path)" />
58 </p>58 </p>
59 <ul id="submenuTabs">59 <ul id="submenuTabs">
60 <li id="first"><a tal:attributes="href python:url(['/files', change.revno]);60 <li id="first"><a tal:attributes="href python:url(['/files', change.revno]);
6161
=== renamed file 'loggerhead/templates/annotate.pt' => 'loggerhead/templates/view.pt'
--- loggerhead/templates/annotate.pt 2009-04-30 10:39:05 +0000
+++ loggerhead/templates/view.pt 2010-12-01 08:41:33 +0000
@@ -3,12 +3,12 @@
3<html xmlns="http://www.w3.org/1999/xhtml" metal:use-macro="macros/main">3<html xmlns="http://www.w3.org/1999/xhtml" metal:use-macro="macros/main">
4 <head>4 <head>
5 <title metal:fill-slot="title"5 <title metal:fill-slot="title"
6 tal:content="string:${branch/friendly_name} : contents of ${path}6 tal:content="string:${branch/friendly_name} : contents of ${file_path}
7 at revision ${change/revno}">7 at revision ${change/revno}">
8 </title>8 </title>
9 <metal:block fill-slot="header_extras">9 <metal:block fill-slot="header_extras">
10 <link rel="stylesheet" type="text/css" media="all"10 <link rel="stylesheet" type="text/css" media="all"
11 tal:attributes="href python:branch.static_url('/static/css/annotate.css')"/>11 tal:attributes="href python:branch.static_url('/static/css/view.css')"/>
12 <link rel="stylesheet" type="text/css" media="all"12 <link rel="stylesheet" type="text/css" media="all"
13 tal:attributes="href python:branch.static_url('/static/css/highlight.css')"/>13 tal:attributes="href python:branch.static_url('/static/css/highlight.css')"/>
14 </metal:block>14 </metal:block>
@@ -36,6 +36,14 @@
36 <li id="first">36 <li id="first">
37 <a tal:attributes="href python:url(['/files', change.revno], clear=1)">browse files</a>37 <a tal:attributes="href python:url(['/files', change.revno], clear=1)">browse files</a>
38 </li>38 </li>
39 <li tal:condition="not:annotated">
40 <a tal:attributes="href python:url(['/annotate', revno_url, file_path], clear=1)"
41 >view revision numbers per line</a>
42 </li>
43 <li tal:condition="annotated">
44 <a tal:attributes="href python:url(['/view', revno_url, file_path], clear=1)"
45 >view without revision numbers</a>
46 </li>
39 <li>47 <li>
40 <a tal:attributes="href python:url(['/revision', change.revno], clear=1)">view revision</a>48 <a tal:attributes="href python:url(['/revision', change.revno], clear=1)">view revision</a>
41 </li>49 </li>
@@ -50,25 +58,30 @@
50 </li>58 </li>
51 </ul>59 </ul>
5260
53 <div class="annotate">61 <div class="view">
54 <table id="logentries">62 <table id="logentries">
55 <tr class="logheader">63 <tr class="logheader">
56 <td class="annoLineTit">Line</td>64 <td class="viewLineTit">Line</td>
57 <td class="annoRevTit">Revision</td>65 <td class="viewRevTit" tal:condition="annotated">Revision</td>
58 <td class="annoContTit">Contents</td>66 <td class="viewContTit">Contents</td>
59 </tr>67 </tr>
6068
61 <tr tal:repeat="line contents"69 <tal:rep tal:repeat="line contents">
62 tal:attributes="class string:blueRow${line/parity}">70 <tr tal:define="anno python:annotated and annotated.next()"
63 <td class="annoLine"><a tal:attributes="id string:L${line/lineno}; href string:#L${line/lineno}" tal:content="line/lineno">1</a></td>71 tal:attributes="class python:anno and 'blueRow' + str(anno.parity) or None">
64 <td class="annoRev">72 <td class="viewLine">
65 <a tal:condition="python:line.status=='changed'"73 <a tal:attributes="id string:L${repeat/line/number}; href string:#L${repeat/line/number}"
66 tal:content="python:util.trunc(line.change.revno)"74 tal:content="repeat/line/number">1</a>
67 tal:attributes="href python:url(['/revision', line.change.revno], clear=1);75 </td>
68 title python:'%s by %s, on %s (%s)'%(line.change.revno, ', '.join(util.hide_emails(line.change.authors)), line.change.date.strftime('%d %b %Y %H:%M'), util.date_time(line.change.date))"></a>76 <td class="viewRev" tal:condition="annotated">
69 </td>77 <a tal:condition="python:anno.new_rev"
70 <td class="annoCont"><pre tal:content="structure line/text"></pre></td>78 tal:content="python:util.trunc(anno.change.revno)"
71 </tr>79 tal:attributes="href python:url(['/revision', anno.change.revno], clear=1);
80 title python:'%s by %s, on %s (%s)' % (anno.change.revno, ', '.join(util.hide_emails(anno.change.authors)), anno.change.date.strftime('%d %b %Y %H:%M'), util.date_time(anno.change.date))"></a>
81 </td>
82 <td class="viewCont"><pre tal:content="structure line"></pre></td>
83 </tr>
84 </tal:rep>
72 </table>85 </table>
73 </div>86 </div>
7487
7588
=== modified file 'loggerhead/tests/__init__.py'
--- loggerhead/tests/__init__.py 2006-12-11 06:44:19 +0000
+++ loggerhead/tests/__init__.py 2010-12-01 08:41:33 +0000
@@ -0,0 +1,26 @@
1# Copyright 2006, 2010 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
17
18def load_tests(standard_tests, module, loader):
19 standard_tests.addTests(loader.loadTestsFromModuleNames([
20 (__name__ + '.' + x) for x in [
21 'test_controllers',
22 'test_corners',
23 'test_simple',
24 'test_templating',
25 ]]))
26 return standard_tests
027
=== modified file 'loggerhead/trace.py'
--- loggerhead/trace.py 2008-10-24 02:26:05 +0000
+++ loggerhead/trace.py 2010-12-01 08:41:33 +0000
@@ -22,6 +22,7 @@
2222
23import os23import os
24import logging24import logging
25import logging.handlers
25import sys26import sys
2627
2728

Subscribers

People subscribed via source and target branches