Merge lp:~mkanat/loggerhead/launchpad into lp:~launchpad-pqm/loggerhead/devel
- launchpad
- Merge into 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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Hudson-Doyle | Approve | ||
Launchpad PQM Bot | Pending | ||
Review via email: mp+42338@code.launchpad.net |
Commit message
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
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
1 | === modified file 'NEWS' | |||
2 | --- NEWS 2010-05-10 13:48:25 +0000 | |||
3 | +++ NEWS 2010-12-01 08:41:33 +0000 | |||
4 | @@ -1,8 +1,8 @@ | |||
5 | 1 | What's changed in loggerhead? | 1 | What's changed in loggerhead? |
6 | 2 | ============================= | 2 | ============================= |
7 | 3 | 3 | ||
10 | 4 | dev [future] | 4 | 1.18 [10Nov2010] |
11 | 5 | ------------ | 5 | ---------------- |
12 | 6 | 6 | ||
13 | 7 | - Syntax highlighting is no longer applied for files greater than 512K, | 7 | - Syntax highlighting is no longer applied for files greater than 512K, |
14 | 8 | reducing codebrowse.launchpad.net overloading. | 8 | reducing codebrowse.launchpad.net overloading. |
15 | 9 | 9 | ||
16 | === modified file '__init__.py' | |||
17 | --- __init__.py 2010-04-22 08:52:59 +0000 | |||
18 | +++ __init__.py 2010-12-01 08:41:33 +0000 | |||
19 | @@ -30,15 +30,16 @@ | |||
20 | 30 | starts a web server to browse the contents of a branch. | 30 | starts a web server to browse the contents of a branch. |
21 | 31 | """ | 31 | """ |
22 | 32 | 32 | ||
24 | 33 | version_info = (1, 17, 0) | 33 | from info import ( |
25 | 34 | bzr_plugin_version as version_info, | ||
26 | 35 | bzr_compatible_versions, | ||
27 | 36 | ) | ||
28 | 34 | 37 | ||
29 | 35 | if __name__ == 'bzrlib.plugins.loggerhead': | 38 | if __name__ == 'bzrlib.plugins.loggerhead': |
30 | 36 | import bzrlib | 39 | import bzrlib |
31 | 37 | from bzrlib.api import require_any_api | 40 | from bzrlib.api import require_any_api |
32 | 38 | 41 | ||
36 | 39 | require_any_api(bzrlib, [ | 42 | require_any_api(bzrlib, bzr_compatible_versions) |
34 | 40 | (1, 13, 0), (1, 15, 0), (1, 16, 0), (1, 17, 0), (1, 18, 0), | ||
35 | 41 | (2, 0, 0), (2, 1, 0), (2, 2, 0)]) | ||
37 | 42 | 43 | ||
38 | 43 | # NB: Normally plugins should lazily load almost everything, but this | 44 | # NB: Normally plugins should lazily load almost everything, but this |
39 | 44 | # seems reasonable to have in-line here: bzrlib.commands and options are | 45 | # seems reasonable to have in-line here: bzrlib.commands and options are |
40 | @@ -69,10 +70,9 @@ | |||
41 | 69 | logging.getLogger('simpleTAL').addHandler(handler) | 70 | logging.getLogger('simpleTAL').addHandler(handler) |
42 | 70 | logging.getLogger('simpleTALES').addHandler(handler) | 71 | logging.getLogger('simpleTALES').addHandler(handler) |
43 | 71 | 72 | ||
44 | 72 | def serve_http(transport, host=None, port=None, inet=None): | ||
45 | 73 | from paste.httpexceptions import HTTPExceptionHandler | ||
46 | 74 | from paste.httpserver import serve | ||
47 | 75 | 73 | ||
48 | 74 | def _ensure_loggerhead_path(): | ||
49 | 75 | """Ensure that you can 'import loggerhead' and get the root.""" | ||
50 | 76 | # loggerhead internal code will try to 'import loggerhead', so | 76 | # loggerhead internal code will try to 'import loggerhead', so |
51 | 77 | # let's put it on the path if we can't find it in the existing path | 77 | # let's put it on the path if we can't find it in the existing path |
52 | 78 | try: | 78 | try: |
53 | @@ -81,6 +81,12 @@ | |||
54 | 81 | import os.path, sys | 81 | import os.path, sys |
55 | 82 | sys.path.append(os.path.dirname(__file__)) | 82 | sys.path.append(os.path.dirname(__file__)) |
56 | 83 | 83 | ||
57 | 84 | def serve_http(transport, host=None, port=None, inet=None): | ||
58 | 85 | from paste.httpexceptions import HTTPExceptionHandler | ||
59 | 86 | from paste.httpserver import serve | ||
60 | 87 | |||
61 | 88 | _ensure_loggerhead_path() | ||
62 | 89 | |||
63 | 84 | from loggerhead.apps.transport import BranchesFromTransportRoot | 90 | from loggerhead.apps.transport import BranchesFromTransportRoot |
64 | 85 | from loggerhead.config import LoggerheadConfig | 91 | from loggerhead.config import LoggerheadConfig |
65 | 86 | 92 | ||
66 | @@ -132,3 +138,9 @@ | |||
67 | 132 | super(cmd_serve, self).run(*args, **kw) | 138 | super(cmd_serve, self).run(*args, **kw) |
68 | 133 | 139 | ||
69 | 134 | register_command(cmd_serve) | 140 | register_command(cmd_serve) |
70 | 141 | |||
71 | 142 | def load_tests(standard_tests, module, loader): | ||
72 | 143 | _ensure_loggerhead_path() | ||
73 | 144 | standard_tests.addTests(loader.loadTestsFromModuleNames( | ||
74 | 145 | ['bzrlib.plugins.loggerhead.loggerhead.tests'])) | ||
75 | 146 | return standard_tests | ||
76 | 135 | 147 | ||
77 | === added file 'info.py' | |||
78 | --- info.py 1970-01-01 00:00:00 +0000 | |||
79 | +++ info.py 2010-12-01 08:41:33 +0000 | |||
80 | @@ -0,0 +1,13 @@ | |||
81 | 1 | #!/usr/bin/env python | ||
82 | 2 | # API Info for loggerhead | ||
83 | 3 | |||
84 | 4 | bzr_plugin_name = "loggerhead" | ||
85 | 5 | |||
86 | 6 | bzr_plugin_version = (1, 18, 0) | ||
87 | 7 | |||
88 | 8 | bzr_compatible_versions = [ | ||
89 | 9 | (1, 17, 0), (1, 18, 0), (2, 0, 0), (2, 1, 0), (2, 2, 0), (2, 3, 0)] | ||
90 | 10 | |||
91 | 11 | bzr_minimum_version = bzr_compatible_versions[0] | ||
92 | 12 | |||
93 | 13 | bzr_maximum_version = bzr_compatible_versions[-1] | ||
94 | 0 | 14 | ||
95 | === modified file 'loggerhead/__init__.py' | |||
96 | --- loggerhead/__init__.py 2009-08-20 13:30:37 +0000 | |||
97 | +++ loggerhead/__init__.py 2010-12-01 08:41:33 +0000 | |||
98 | @@ -22,7 +22,7 @@ | |||
99 | 22 | 22 | ||
100 | 23 | import pkg_resources | 23 | import pkg_resources |
101 | 24 | 24 | ||
103 | 25 | __version__ = '1.17' | 25 | __version__ = '1.18' |
104 | 26 | required_bzrlib = (1, 17) | 26 | required_bzrlib = (1, 17) |
105 | 27 | 27 | ||
106 | 28 | pkg_resources.get_distribution('Paste>=1.6') | 28 | pkg_resources.get_distribution('Paste>=1.6') |
107 | 29 | 29 | ||
108 | === modified file 'loggerhead/apps/branch.py' | |||
109 | --- loggerhead/apps/branch.py 2010-05-05 18:28:54 +0000 | |||
110 | +++ loggerhead/apps/branch.py 2010-12-01 08:41:33 +0000 | |||
111 | @@ -29,6 +29,7 @@ | |||
112 | 29 | 29 | ||
113 | 30 | from loggerhead.apps import static_app | 30 | from loggerhead.apps import static_app |
114 | 31 | from loggerhead.controllers.annotate_ui import AnnotateUI | 31 | from loggerhead.controllers.annotate_ui import AnnotateUI |
115 | 32 | from loggerhead.controllers.view_ui import ViewUI | ||
116 | 32 | from loggerhead.controllers.atom_ui import AtomUI | 33 | from loggerhead.controllers.atom_ui import AtomUI |
117 | 33 | from loggerhead.controllers.changelog_ui import ChangeLogUI | 34 | from loggerhead.controllers.changelog_ui import ChangeLogUI |
118 | 34 | from loggerhead.controllers.diff_ui import DiffUI | 35 | from loggerhead.controllers.diff_ui import DiffUI |
119 | @@ -124,6 +125,7 @@ | |||
120 | 124 | 'files': InventoryUI, | 125 | 'files': InventoryUI, |
121 | 125 | 'revision': RevisionUI, | 126 | 'revision': RevisionUI, |
122 | 126 | 'search': SearchUI, | 127 | 'search': SearchUI, |
123 | 128 | 'view': ViewUI, | ||
124 | 127 | } | 129 | } |
125 | 128 | 130 | ||
126 | 129 | def last_updated(self): | 131 | def last_updated(self): |
127 | 130 | 132 | ||
128 | === added file 'loggerhead/controllers/annotate_ui.py' | |||
129 | --- loggerhead/controllers/annotate_ui.py 1970-01-01 00:00:00 +0000 | |||
130 | +++ loggerhead/controllers/annotate_ui.py 2010-12-01 08:41:33 +0000 | |||
131 | @@ -0,0 +1,54 @@ | |||
132 | 1 | # | ||
133 | 2 | # Copyright (C) 2010 Canonical Ltd. | ||
134 | 3 | # | ||
135 | 4 | # This program is free software; you can redistribute it and/or modify | ||
136 | 5 | # it under the terms of the GNU General Public License as published by | ||
137 | 6 | # the Free Software Foundation; either version 2 of the License, or | ||
138 | 7 | # (at your option) any later version. | ||
139 | 8 | # | ||
140 | 9 | # This program is distributed in the hope that it will be useful, | ||
141 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
142 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
143 | 12 | # GNU General Public License for more details. | ||
144 | 13 | # | ||
145 | 14 | # You should have received a copy of the GNU General Public License | ||
146 | 15 | # along with this program; if not, write to the Free Software | ||
147 | 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
148 | 17 | # | ||
149 | 18 | |||
150 | 19 | from loggerhead.controllers.view_ui import ViewUI | ||
151 | 20 | from loggerhead import util | ||
152 | 21 | |||
153 | 22 | class AnnotateUI(ViewUI): | ||
154 | 23 | |||
155 | 24 | def annotate_file(self, info): | ||
156 | 25 | file_id = info['file_id'] | ||
157 | 26 | revid = info['change'].revid | ||
158 | 27 | |||
159 | 28 | tree = self.tree_for(file_id, revid) | ||
160 | 29 | |||
161 | 30 | change_cache = {} | ||
162 | 31 | last_line_revid = None | ||
163 | 32 | parity = 1 | ||
164 | 33 | for line_revid, text in tree.annotate_iter(file_id): | ||
165 | 34 | if line_revid == last_line_revid: | ||
166 | 35 | # remember which lines have a new revno and which don't | ||
167 | 36 | new_rev = False | ||
168 | 37 | else: | ||
169 | 38 | new_rev = True | ||
170 | 39 | parity ^= 1 | ||
171 | 40 | last_line_revid = line_revid | ||
172 | 41 | if line_revid in change_cache: | ||
173 | 42 | change = change_cache[line_revid] | ||
174 | 43 | else: | ||
175 | 44 | change = self._history.get_changes([line_revid])[0] | ||
176 | 45 | change_cache[line_revid] = change | ||
177 | 46 | |||
178 | 47 | yield util.Container( | ||
179 | 48 | parity=parity, new_rev=new_rev, change=change) | ||
180 | 49 | |||
181 | 50 | def get_values(self, path, kwargs, headers): | ||
182 | 51 | values = super(AnnotateUI, self).get_values(path, kwargs, headers) | ||
183 | 52 | values['annotated'] = self.annotate_file(values) | ||
184 | 53 | |||
185 | 54 | return values | ||
186 | 0 | 55 | ||
187 | === renamed file 'loggerhead/controllers/annotate_ui.py' => 'loggerhead/controllers/view_ui.py' | |||
188 | --- loggerhead/controllers/annotate_ui.py 2009-10-17 06:35:33 +0000 | |||
189 | +++ loggerhead/controllers/view_ui.py 2010-12-01 08:41:33 +0000 | |||
190 | @@ -35,20 +35,18 @@ | |||
191 | 35 | from loggerhead import util | 35 | from loggerhead import util |
192 | 36 | 36 | ||
193 | 37 | 37 | ||
203 | 38 | class AnnotateUI(TemplatedBranchView): | 38 | class ViewUI(TemplatedBranchView): |
204 | 39 | 39 | ||
205 | 40 | template_path = 'loggerhead.templates.annotate' | 40 | template_path = 'loggerhead.templates.view' |
206 | 41 | 41 | ||
207 | 42 | def annotate_file(self, file_id, revid): | 42 | def tree_for(self, file_id, revid): |
199 | 43 | z = time.time() | ||
200 | 44 | lineno = 1 | ||
201 | 45 | parity = 0 | ||
202 | 46 | |||
208 | 47 | file_revid = self._history.get_inventory(revid)[file_id].revision | 43 | file_revid = self._history.get_inventory(revid)[file_id].revision |
210 | 48 | tree = self._history._branch.repository.revision_tree(file_revid) | 44 | return self._history._branch.repository.revision_tree(file_revid) |
211 | 49 | 45 | ||
212 | 46 | def text_lines(self, file_id, revid): | ||
213 | 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)) |
215 | 51 | 48 | ||
216 | 49 | tree = self.tree_for(file_id, revid) | ||
217 | 52 | file_text = tree.get_file_text(file_id) | 50 | file_text = tree.get_file_text(file_id) |
218 | 53 | encoding = 'utf-8' | 51 | encoding = 'utf-8' |
219 | 54 | try: | 52 | try: |
220 | @@ -58,44 +56,27 @@ | |||
221 | 58 | file_text = file_text.decode(encoding) | 56 | file_text = file_text.decode(encoding) |
222 | 59 | 57 | ||
223 | 60 | file_lines = bzrlib.osutils.split_lines(file_text) | 58 | file_lines = bzrlib.osutils.split_lines(file_text) |
224 | 59 | # This can throw bzrlib.errors.BinaryFile (which our caller catches). | ||
225 | 60 | bzrlib.textfile.check_text_lines(file_lines) | ||
226 | 61 | |||
227 | 62 | if highlight is not None: | ||
228 | 63 | hl_lines = highlight(file_name, file_text, encoding) | ||
229 | 64 | # highlight strips off extra newlines at the end of the file. | ||
230 | 65 | extra_lines = len(file_lines) - len(hl_lines) | ||
231 | 66 | hl_lines.extend([u''] * extra_lines) | ||
232 | 67 | else: | ||
233 | 68 | hl_lines = map(cgi.escape, file_lines) | ||
234 | 69 | |||
235 | 70 | return hl_lines; | ||
236 | 61 | 71 | ||
237 | 72 | def file_contents(self, file_id, revid): | ||
238 | 62 | try: | 73 | try: |
240 | 63 | bzrlib.textfile.check_text_lines(file_lines) | 74 | file_lines = self.text_lines(file_id, revid) |
241 | 64 | except bzrlib.errors.BinaryFile: | 75 | except bzrlib.errors.BinaryFile: |
242 | 65 | # bail out; this isn't displayable text | 76 | # bail out; this isn't displayable text |
276 | 66 | yield util.Container(parity=0, lineno=1, status='same', | 77 | return ['(This is a binary file.)'] |
277 | 67 | text='(This is a binary file.)', | 78 | |
278 | 68 | change=util.Container()) | 79 | return file_lines |
246 | 69 | else: | ||
247 | 70 | if highlight is not None: | ||
248 | 71 | hl_lines = highlight(file_name, file_text, encoding) | ||
249 | 72 | hl_lines.extend([u''] * (len(file_lines) - len(hl_lines))) | ||
250 | 73 | else: | ||
251 | 74 | hl_lines = map(cgi.escape, file_lines) | ||
252 | 75 | |||
253 | 76 | change_cache = {} | ||
254 | 77 | |||
255 | 78 | last_line_revid = None | ||
256 | 79 | for line_revid, text in tree.annotate_iter(file_id): | ||
257 | 80 | if line_revid == last_line_revid: | ||
258 | 81 | # remember which lines have a new revno and which don't | ||
259 | 82 | status = 'same' | ||
260 | 83 | else: | ||
261 | 84 | status = 'changed' | ||
262 | 85 | parity ^= 1 | ||
263 | 86 | last_line_revid = line_revid | ||
264 | 87 | if line_revid in change_cache: | ||
265 | 88 | change = change_cache[line_revid] | ||
266 | 89 | else: | ||
267 | 90 | change = self._history.get_changes([line_revid])[0] | ||
268 | 91 | change_cache[line_revid] = change | ||
269 | 92 | |||
270 | 93 | yield util.Container( | ||
271 | 94 | parity=parity, lineno=lineno, status=status, | ||
272 | 95 | change=change, text=hl_lines[lineno - 1]) | ||
273 | 96 | lineno += 1 | ||
274 | 97 | |||
275 | 98 | self.log.debug('annotate: %r secs' % (time.time() - z,)) | ||
279 | 99 | 80 | ||
280 | 100 | def get_values(self, path, kwargs, headers): | 81 | def get_values(self, path, kwargs, headers): |
281 | 101 | history = self._history | 82 | history = self._history |
282 | @@ -105,7 +86,7 @@ | |||
283 | 105 | file_id = kwargs.get('file_id', None) | 86 | file_id = kwargs.get('file_id', None) |
284 | 106 | if (file_id is None) and (path is None): | 87 | if (file_id is None) and (path is None): |
285 | 107 | raise HTTPBadRequest('No file_id or filename ' | 88 | raise HTTPBadRequest('No file_id or filename ' |
287 | 108 | 'provided to annotate') | 89 | 'provided to view') |
288 | 109 | 90 | ||
289 | 110 | if file_id is None: | 91 | if file_id is None: |
290 | 111 | file_id = history.get_file_id(revid, path) | 92 | file_id = history.get_file_id(revid, path) |
291 | @@ -140,13 +121,17 @@ | |||
292 | 140 | branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files') | 121 | branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files') |
293 | 141 | 122 | ||
294 | 142 | return { | 123 | return { |
295 | 124 | # In AnnotateUI, "annotated" is a generator giving revision | ||
296 | 125 | # numbers per lines, but the template checks if "annotated" is | ||
297 | 126 | # true or not before using it, so we have to define it here also. | ||
298 | 127 | 'annotated': False, | ||
299 | 143 | 'revno_url': revno_url, | 128 | 'revno_url': revno_url, |
300 | 144 | 'file_id': file_id, | 129 | 'file_id': file_id, |
302 | 145 | 'path': path, | 130 | 'file_path': path, |
303 | 146 | 'filename': filename, | 131 | 'filename': filename, |
304 | 147 | 'navigation': navigation, | 132 | 'navigation': navigation, |
305 | 148 | 'change': change, | 133 | 'change': change, |
307 | 149 | 'contents': list(self.annotate_file(file_id, revid)), | 134 | 'contents': self.file_contents(file_id, revid), |
308 | 150 | 'fileview_active': True, | 135 | 'fileview_active': True, |
309 | 151 | 'directory_breadcrumbs': directory_breadcrumbs, | 136 | 'directory_breadcrumbs': directory_breadcrumbs, |
310 | 152 | 'branch_breadcrumbs': branch_breadcrumbs, | 137 | 'branch_breadcrumbs': branch_breadcrumbs, |
311 | 153 | 138 | ||
312 | === modified file 'loggerhead/highlight.py' | |||
313 | --- loggerhead/highlight.py 2010-04-22 03:23:55 +0000 | |||
314 | +++ loggerhead/highlight.py 2010-12-01 08:41:33 +0000 | |||
315 | @@ -16,6 +16,7 @@ | |||
316 | 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
317 | 17 | # | 17 | # |
318 | 18 | 18 | ||
319 | 19 | import bzrlib.osutils | ||
320 | 19 | import cgi | 20 | import cgi |
321 | 20 | 21 | ||
322 | 21 | from pygments import highlight as _highlight_func | 22 | from pygments import highlight as _highlight_func |
323 | @@ -36,7 +37,7 @@ | |||
324 | 36 | """ | 37 | """ |
325 | 37 | 38 | ||
326 | 38 | if len(text) > MAX_HIGHLIGHT_SIZE: | 39 | if len(text) > MAX_HIGHLIGHT_SIZE: |
328 | 39 | return map(cgi.escape, text.split('\n')) | 40 | return map(cgi.escape, bzrlib.osutils.split_lines(text)) |
329 | 40 | 41 | ||
330 | 41 | formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-') | 42 | formatter = HtmlFormatter(style=style, nowrap=True, classprefix='pyg-') |
331 | 42 | 43 | ||
332 | @@ -48,6 +49,7 @@ | |||
333 | 48 | except (ClassNotFound, ValueError): | 49 | except (ClassNotFound, ValueError): |
334 | 49 | lexer = TextLexer(encoding=encoding) | 50 | lexer = TextLexer(encoding=encoding) |
335 | 50 | 51 | ||
337 | 51 | hl_lines = _highlight_func(text, lexer, formatter).split('\n') | 52 | hl_lines = _highlight_func(text, lexer, formatter) |
338 | 53 | hl_lines = bzrlib.osutils.split_lines(hl_lines) | ||
339 | 52 | 54 | ||
340 | 53 | return hl_lines | 55 | return hl_lines |
341 | 54 | 56 | ||
342 | === renamed file 'loggerhead/static/css/annotate.css' => 'loggerhead/static/css/view.css' | |||
343 | --- loggerhead/static/css/annotate.css 2009-04-30 10:39:05 +0000 | |||
344 | +++ loggerhead/static/css/view.css 2010-12-01 08:41:33 +0000 | |||
345 | @@ -1,29 +1,31 @@ | |||
346 | 1 | /*table*/ | 1 | /*table*/ |
349 | 2 | .annoLineTit, .annoLine, .annoRevTit, .annoRev, .annoComm, .annoCommTit, .annoContTit, .annoCont { | 2 | .viewLineTit, .viewLine, .viewRevTit, .viewRev, |
350 | 3 | width:45px; | 3 | .viewContTit, .viewCont |
351 | 4 | { | ||
352 | 4 | border:1px solid #d2d2d2; | 5 | border:1px solid #d2d2d2; |
353 | 5 | } | 6 | } |
355 | 6 | .annoLine, .annoRev, .annoComm, .annoCont { | 7 | .viewLine, .viewRev, .viewComm, .viewCont { |
356 | 7 | border:none; | 8 | border:none; |
357 | 8 | } | 9 | } |
359 | 9 | .annoLine { | 10 | .viewLine, .viewLineTit { |
360 | 11 | padding-right: .2em; | ||
361 | 12 | } | ||
362 | 13 | .viewLine { | ||
363 | 10 | width:37px; | 14 | width:37px; |
364 | 11 | } | 15 | } |
366 | 12 | .annoContTit, .annoCont { | 16 | .viewContTit, .viewCont { |
367 | 13 | width:auto; | 17 | width:auto; |
368 | 18 | padding-left: .3em; | ||
369 | 14 | } | 19 | } |
371 | 15 | .annoRevTit, .annoRev { | 20 | .viewRevTit, .viewRev { |
372 | 16 | width:70px; | 21 | width:70px; |
373 | 17 | text-align:center; | 22 | text-align:center; |
374 | 18 | } | 23 | } |
379 | 19 | .annoComm, .annoCommTit { | 24 | .viewLine, .viewCont { |
376 | 20 | width:200px; | ||
377 | 21 | } | ||
378 | 22 | .annoLine, .annoCont { | ||
380 | 23 | font:normal 12px/normal monospace; | 25 | font:normal 12px/normal monospace; |
381 | 24 | whitespace: pre; | 26 | whitespace: pre; |
382 | 25 | } | 27 | } |
385 | 26 | .annoCont pre { margin: 0; } | 28 | .viewCont pre { margin: 0; } |
386 | 27 | .annoLine { | 29 | .viewLine { |
387 | 28 | text-align:right; | 30 | text-align:right; |
388 | 29 | } | 31 | } |
389 | 30 | 32 | ||
390 | === modified file 'loggerhead/templatefunctions.py' | |||
391 | --- loggerhead/templatefunctions.py 2009-10-17 08:47:38 +0000 | |||
392 | +++ loggerhead/templatefunctions.py 2010-12-01 08:41:33 +0000 | |||
393 | @@ -121,9 +121,9 @@ | |||
394 | 121 | 121 | ||
395 | 122 | 122 | ||
396 | 123 | @templatefunc | 123 | @templatefunc |
398 | 124 | def annotate_link(url, revno, path): | 124 | def view_link(url, revno, path): |
399 | 125 | return '<a href="%s" title="Annotate %s">%s</a>' % ( | 125 | return '<a href="%s" title="Annotate %s">%s</a>' % ( |
401 | 126 | url(['/annotate', revno, path]), cgi.escape(path), cgi.escape(path)) | 126 | url(['/view', revno, path]), cgi.escape(path), cgi.escape(path)) |
402 | 127 | 127 | ||
403 | 128 | @templatefunc | 128 | @templatefunc |
404 | 129 | def revision_link(url, revno, path, frag=''): | 129 | def revision_link(url, revno, path, frag=''): |
405 | 130 | 130 | ||
406 | === modified file 'loggerhead/templates/inventory.pt' | |||
407 | --- loggerhead/templates/inventory.pt 2009-10-17 06:55:25 +0000 | |||
408 | +++ loggerhead/templates/inventory.pt 2010-12-01 08:41:33 +0000 | |||
409 | @@ -89,11 +89,11 @@ | |||
410 | 89 | 89 | ||
411 | 90 | <!-- Show this if it's a symlink --> | 90 | <!-- Show this if it's a symlink --> |
412 | 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'"> |
414 | 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])"> |
415 | 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" /> |
416 | 94 | </a> | 94 | </a> |
417 | 95 | 95 | ||
419 | 96 | <a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath])" | 96 | <a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])" |
420 | 97 | tal:content="file/filename" class="link"></a> | 97 | tal:content="file/filename" class="link"></a> |
421 | 98 | </td> | 98 | </td> |
422 | 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]); |
423 | @@ -113,17 +113,17 @@ | |||
424 | 113 | 113 | ||
425 | 114 | <!-- Show this if it's a regular file --> | 114 | <!-- Show this if it's a regular file --> |
426 | 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'"> |
428 | 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])"> |
429 | 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'); |
431 | 118 | title string:Annotate ${file/filename}" | 118 | title string:View ${file/filename}" |
432 | 119 | tal:condition="python:file.executable is False" /> | 119 | tal:condition="python:file.executable is False" /> |
433 | 120 | <!-- Show a different icon id the file executable --> | 120 | <!-- Show a different icon id the file executable --> |
434 | 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'); |
436 | 122 | title string:Annotate ${file/filename}" | 122 | title string:View ${file/filename}" |
437 | 123 | tal:condition="python:file.executable is True" alt="File" /> | 123 | tal:condition="python:file.executable is True" alt="File" /> |
438 | 124 | </a> | 124 | </a> |
439 | 125 | 125 | ||
441 | 126 | <a tal:attributes="href python:url(['/annotate', revno_url, file.absolutepath])" | 126 | <a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])" |
442 | 127 | tal:content="file/filename" class="link"></a></td> | 127 | tal:content="file/filename" class="link"></a></td> |
443 | 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]); |
444 | 129 | title string:Show revision ${file/change/revno}" | 129 | title string:Show revision ${file/change/revno}" |
445 | @@ -131,8 +131,8 @@ | |||
446 | 131 | </td> | 131 | </td> |
447 | 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> |
448 | 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> |
451 | 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]); |
452 | 135 | title string:Annotate ${file/filename}"> | 135 | title string:View ${file/filename}"> |
453 | 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" /> |
454 | 137 | </a> | 137 | </a> |
455 | 138 | </td> | 138 | </td> |
456 | 139 | 139 | ||
457 | === modified file 'loggerhead/templates/revision.pt' | |||
458 | --- loggerhead/templates/revision.pt 2009-07-21 04:39:33 +0000 | |||
459 | +++ loggerhead/templates/revision.pt 2010-12-01 08:41:33 +0000 | |||
460 | @@ -41,7 +41,7 @@ | |||
461 | 41 | </tal:compare-to> | 41 | </tal:compare-to> |
462 | 42 | </span> | 42 | </span> |
463 | 43 | <span class="breadcrumb" tal:condition="specific_path"> | 43 | <span class="breadcrumb" tal:condition="specific_path"> |
465 | 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)" /> |
466 | 45 | </span> | 45 | </span> |
467 | 46 | </h1> | 46 | </h1> |
468 | 47 | <tal:branch-info replace="structure python:branchinfo(branch)" /> | 47 | <tal:branch-info replace="structure python:branchinfo(branch)" /> |
469 | @@ -54,7 +54,7 @@ | |||
470 | 54 | </a> | 54 | </a> |
471 | 55 | </p> | 55 | </p> |
472 | 56 | <p tal:condition="specific_path"> | 56 | <p tal:condition="specific_path"> |
474 | 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)" /> |
475 | 58 | </p> | 58 | </p> |
476 | 59 | <ul id="submenuTabs"> | 59 | <ul id="submenuTabs"> |
477 | 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]); |
478 | 61 | 61 | ||
479 | === renamed file 'loggerhead/templates/annotate.pt' => 'loggerhead/templates/view.pt' | |||
480 | --- loggerhead/templates/annotate.pt 2009-04-30 10:39:05 +0000 | |||
481 | +++ loggerhead/templates/view.pt 2010-12-01 08:41:33 +0000 | |||
482 | @@ -3,12 +3,12 @@ | |||
483 | 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"> |
484 | 4 | <head> | 4 | <head> |
485 | 5 | <title metal:fill-slot="title" | 5 | <title metal:fill-slot="title" |
487 | 6 | tal:content="string:${branch/friendly_name} : contents of ${path} | 6 | tal:content="string:${branch/friendly_name} : contents of ${file_path} |
488 | 7 | at revision ${change/revno}"> | 7 | at revision ${change/revno}"> |
489 | 8 | </title> | 8 | </title> |
490 | 9 | <metal:block fill-slot="header_extras"> | 9 | <metal:block fill-slot="header_extras"> |
491 | 10 | <link rel="stylesheet" type="text/css" media="all" | 10 | <link rel="stylesheet" type="text/css" media="all" |
493 | 11 | tal:attributes="href python:branch.static_url('/static/css/annotate.css')"/> | 11 | tal:attributes="href python:branch.static_url('/static/css/view.css')"/> |
494 | 12 | <link rel="stylesheet" type="text/css" media="all" | 12 | <link rel="stylesheet" type="text/css" media="all" |
495 | 13 | tal:attributes="href python:branch.static_url('/static/css/highlight.css')"/> | 13 | tal:attributes="href python:branch.static_url('/static/css/highlight.css')"/> |
496 | 14 | </metal:block> | 14 | </metal:block> |
497 | @@ -36,6 +36,14 @@ | |||
498 | 36 | <li id="first"> | 36 | <li id="first"> |
499 | 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> |
500 | 38 | </li> | 38 | </li> |
501 | 39 | <li tal:condition="not:annotated"> | ||
502 | 40 | <a tal:attributes="href python:url(['/annotate', revno_url, file_path], clear=1)" | ||
503 | 41 | >view revision numbers per line</a> | ||
504 | 42 | </li> | ||
505 | 43 | <li tal:condition="annotated"> | ||
506 | 44 | <a tal:attributes="href python:url(['/view', revno_url, file_path], clear=1)" | ||
507 | 45 | >view without revision numbers</a> | ||
508 | 46 | </li> | ||
509 | 39 | <li> | 47 | <li> |
510 | 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> |
511 | 41 | </li> | 49 | </li> |
512 | @@ -50,25 +58,30 @@ | |||
513 | 50 | </li> | 58 | </li> |
514 | 51 | </ul> | 59 | </ul> |
515 | 52 | 60 | ||
517 | 53 | <div class="annotate"> | 61 | <div class="view"> |
518 | 54 | <table id="logentries"> | 62 | <table id="logentries"> |
519 | 55 | <tr class="logheader"> | 63 | <tr class="logheader"> |
523 | 56 | <td class="annoLineTit">Line</td> | 64 | <td class="viewLineTit">Line</td> |
524 | 57 | <td class="annoRevTit">Revision</td> | 65 | <td class="viewRevTit" tal:condition="annotated">Revision</td> |
525 | 58 | <td class="annoContTit">Contents</td> | 66 | <td class="viewContTit">Contents</td> |
526 | 59 | </tr> | 67 | </tr> |
527 | 60 | 68 | ||
539 | 61 | <tr tal:repeat="line contents" | 69 | <tal:rep tal:repeat="line contents"> |
540 | 62 | tal:attributes="class string:blueRow${line/parity}"> | 70 | <tr tal:define="anno python:annotated and annotated.next()" |
541 | 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"> |
542 | 64 | <td class="annoRev"> | 72 | <td class="viewLine"> |
543 | 65 | <a tal:condition="python:line.status=='changed'" | 73 | <a tal:attributes="id string:L${repeat/line/number}; href string:#L${repeat/line/number}" |
544 | 66 | tal:content="python:util.trunc(line.change.revno)" | 74 | tal:content="repeat/line/number">1</a> |
545 | 67 | tal:attributes="href python:url(['/revision', line.change.revno], clear=1); | 75 | </td> |
546 | 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"> |
547 | 69 | </td> | 77 | <a tal:condition="python:anno.new_rev" |
548 | 70 | <td class="annoCont"><pre tal:content="structure line/text"></pre></td> | 78 | tal:content="python:util.trunc(anno.change.revno)" |
549 | 71 | </tr> | 79 | tal:attributes="href python:url(['/revision', anno.change.revno], clear=1); |
550 | 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> | ||
551 | 81 | </td> | ||
552 | 82 | <td class="viewCont"><pre tal:content="structure line"></pre></td> | ||
553 | 83 | </tr> | ||
554 | 84 | </tal:rep> | ||
555 | 72 | </table> | 85 | </table> |
556 | 73 | </div> | 86 | </div> |
557 | 74 | 87 | ||
558 | 75 | 88 | ||
559 | === modified file 'loggerhead/tests/__init__.py' | |||
560 | --- loggerhead/tests/__init__.py 2006-12-11 06:44:19 +0000 | |||
561 | +++ loggerhead/tests/__init__.py 2010-12-01 08:41:33 +0000 | |||
562 | @@ -0,0 +1,26 @@ | |||
563 | 1 | # Copyright 2006, 2010 Canonical Ltd | ||
564 | 2 | # | ||
565 | 3 | # This program is free software; you can redistribute it and/or modify | ||
566 | 4 | # it under the terms of the GNU General Public License as published by | ||
567 | 5 | # the Free Software Foundation; either version 2 of the License, or | ||
568 | 6 | # (at your option) any later version. | ||
569 | 7 | # | ||
570 | 8 | # This program is distributed in the hope that it will be useful, | ||
571 | 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
572 | 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
573 | 11 | # GNU General Public License for more details. | ||
574 | 12 | # | ||
575 | 13 | # You should have received a copy of the GNU General Public License | ||
576 | 14 | # along with this program; if not, write to the Free Software | ||
577 | 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
578 | 16 | |||
579 | 17 | |||
580 | 18 | def load_tests(standard_tests, module, loader): | ||
581 | 19 | standard_tests.addTests(loader.loadTestsFromModuleNames([ | ||
582 | 20 | (__name__ + '.' + x) for x in [ | ||
583 | 21 | 'test_controllers', | ||
584 | 22 | 'test_corners', | ||
585 | 23 | 'test_simple', | ||
586 | 24 | 'test_templating', | ||
587 | 25 | ]])) | ||
588 | 26 | return standard_tests | ||
589 | 0 | 27 | ||
590 | === modified file 'loggerhead/trace.py' | |||
591 | --- loggerhead/trace.py 2008-10-24 02:26:05 +0000 | |||
592 | +++ loggerhead/trace.py 2010-12-01 08:41:33 +0000 | |||
593 | @@ -22,6 +22,7 @@ | |||
594 | 22 | 22 | ||
595 | 23 | import os | 23 | import os |
596 | 24 | import logging | 24 | import logging |
597 | 25 | import logging.handlers | ||
598 | 25 | import sys | 26 | import sys |
599 | 26 | 27 | ||
600 | 27 | 28 |
I approve of this branch, but can't set the mp status. Oh well. Do you want me to merge it too?