Merge lp:~pauljnixon/loggerhead/more_columns into lp:loggerhead

Proposed by Paul Nixon
Status: Superseded
Proposed branch: lp:~pauljnixon/loggerhead/more_columns
Merge into: lp:loggerhead
Diff against target: 389 lines (+98/-55)
9 files modified
loggerhead/apps/branch.py (+15/-0)
loggerhead/controllers/directory_ui.py (+6/-6)
loggerhead/controllers/inventory_ui.py (+22/-9)
loggerhead/history.py (+1/-0)
loggerhead/static/css/global.css (+2/-2)
loggerhead/static/css/view.css (+1/-2)
loggerhead/templates/directory.pt (+12/-13)
loggerhead/templates/inventory.pt (+25/-12)
loggerhead/util.py (+14/-11)
To merge this branch: bzr merge lp:~pauljnixon/loggerhead/more_columns
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Needs Fixing
Paul Nixon Pending
Review via email: mp+116497@code.launchpad.net

This proposal has been superseded by a proposal from 2012-08-03.

Description of the change

Added "committer" and "comment" columns to Files and Inventory views.

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) wrote :

Broadly, this looks good, but I have a few concerns. Firstly, comments should be formatted with a space after the hash, and secondly must be complete sentences. You have added some unneeded whitespace on line 29-30 of the diff. And lastly, since this branch does make some UI changes, I'd like to see at least one screenshot of the before and after view.

review: Needs Fixing (code)
478. By Paul Nixon

Fixed comments.

Revision history for this message
Paul Nixon (pauljnixon) wrote :
Revision history for this message
Paul Nixon (pauljnixon) wrote :

Does this need anything else?

479. By Paul Nixon

Re-added support for future dates in _approximatedate.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'loggerhead/apps/branch.py'
2--- loggerhead/apps/branch.py 2012-02-08 01:50:02 +0000
3+++ loggerhead/apps/branch.py 2012-07-25 14:53:24 +0000
4@@ -93,6 +93,20 @@
5 return History(
6 self.branch, self.graph_cache,
7 revinfo_disk_cache=revinfo_disk_cache, cache_key=self.friendly_name)
8+
9+ # Before the addition of this method, clicking to sort by date from
10+ # within a branch caused a jump up to the top of that branch.
11+ def sort_url(self, *args, **kw):
12+ if isinstance(args[0], list):
13+ args = args[0]
14+ qs = []
15+ for k, v in kw.iteritems():
16+ if v is not None:
17+ qs.append('%s=%s' % (k, urllib.quote(v)))
18+ qs = '&'.join(qs)
19+ path_info = self._path_info.strip('/').split('?')[0]
20+ path_info += '?' + qs
21+ return self._url_base + '/' + path_info
22
23 def url(self, *args, **kw):
24 if isinstance(args[0], list):
25@@ -155,6 +169,7 @@
26 if self.branch.get_config().get_user_option('http_serve') == 'False':
27 raise httpexceptions.HTTPNotFound()
28 self._url_base = environ['SCRIPT_NAME']
29+ self._path_info = environ['PATH_INFO']
30 self._static_url_base = environ.get('loggerhead.static.url')
31 if self._static_url_base is None:
32 self._static_url_base = self._url_base
33
34=== modified file 'loggerhead/controllers/directory_ui.py'
35--- loggerhead/controllers/directory_ui.py 2012-02-08 01:50:02 +0000
36+++ loggerhead/controllers/directory_ui.py 2012-07-25 14:53:24 +0000
37@@ -19,6 +19,7 @@
38 import datetime
39 import logging
40 import stat
41+import urllib
42
43 from bzrlib import branch, errors
44
45@@ -29,18 +30,17 @@
46 class DirEntry(object):
47
48 def __init__(self, dirname, parity, branch):
49- self.dirname = dirname
50+ self.dirname = urllib.unquote(dirname)
51 self.parity = parity
52 self.branch = branch
53 if branch is not None:
54 # If a branch is empty, bzr raises an exception when trying this
55 try:
56- self.last_change = datetime.datetime.utcfromtimestamp(
57- branch.repository.get_revision(
58- branch.last_revision()).timestamp)
59+ self.last_revision = branch.repository.get_revision(branch.last_revision())
60+ self.last_change_time = datetime.datetime.utcfromtimestamp(self.last_revision.timestamp)
61 except:
62- self.last_change = None
63-
64+ self.last_revision = None
65+ self.last_change_time = None
66
67 class DirectoryUI(TemplatedBranchView):
68 """
69
70=== modified file 'loggerhead/controllers/inventory_ui.py'
71--- loggerhead/controllers/inventory_ui.py 2012-02-08 01:50:02 +0000
72+++ loggerhead/controllers/inventory_ui.py 2012-07-25 14:53:24 +0000
73@@ -70,15 +70,27 @@
74 change_dict[change.revid] = change
75
76 for filename, entry in dir_ie.children.iteritems():
77+ revid = entry.revision
78+ file_timestamp = change_dict[revid].timestamp
79 pathname = filename
80- if entry.kind == 'directory':
81- pathname += '/'
82+ contents_changed_rev = None
83 if path == '':
84 absolutepath = pathname
85 else:
86 absolutepath = path + '/' + pathname
87- revid = entry.revision
88-
89+ if entry.kind == 'directory':
90+ # determine the last time something in the folder was changed
91+ pathname += '/'
92+ sub_dir_id = inv.path2id(absolutepath)
93+ sub_dir_ie = inv[sub_dir_id]
94+ sub_revid_set = set()
95+ for sub_filename, sub_entry in sub_dir_ie.children.iteritems():
96+ sub_revid_set.add(sub_entry.revision)
97+ for change in self._history.get_changes(list(sub_revid_set)):
98+ change_dict[change.revid] = change
99+ if(change.timestamp > file_timestamp):
100+ revid = change.revid
101+ file_timestamp = change.timestamp
102 # TODO: For the JSON rendering, this inlines the "change" aka
103 # revision information attached to each file. Consider either
104 # pulling this out as a separate changes dict, or possibly just
105@@ -88,7 +100,7 @@
106 filename=filename, executable=entry.executable,
107 kind=entry.kind, absolutepath=absolutepath,
108 file_id=entry.file_id, size=entry.text_size, revid=revid,
109- change=change_dict[revid])
110+ change=change_dict[revid], contents_changed=contents_changed_rev)
111 file_list.append(file)
112
113 if sort_type == 'filename':
114@@ -96,10 +108,11 @@
115 elif sort_type == 'size':
116 file_list.sort(key=lambda x: x.size)
117 elif sort_type == 'date':
118- file_list.sort(key=lambda x: x.change.date)
119-
120- # Always sort directories first.
121- file_list.sort(key=lambda x: x.kind != 'directory')
122+ file_list.sort(key=lambda x: x.change.date, reverse=True)
123+
124+ if sort_type != 'date':
125+ # Don't always sort directories first.
126+ file_list.sort(key=lambda x: x.kind != 'directory')
127
128 return file_list
129
130
131=== modified file 'loggerhead/history.py'
132--- loggerhead/history.py 2012-02-08 01:50:02 +0000
133+++ loggerhead/history.py 2012-07-25 14:53:24 +0000
134@@ -722,6 +722,7 @@
135 'revid': revision.revision_id,
136 'date': datetime.datetime.fromtimestamp(revision.timestamp),
137 'utc_date': datetime.datetime.utcfromtimestamp(revision.timestamp),
138+ 'timestamp': revision.timestamp,
139 'committer': revision.committer,
140 'authors': revision.get_apparent_authors(),
141 'branch_nick': revision.properties.get('branch-nick', None),
142
143=== modified file 'loggerhead/static/css/global.css'
144--- loggerhead/static/css/global.css 2011-11-23 17:21:39 +0000
145+++ loggerhead/static/css/global.css 2012-07-25 14:53:24 +0000
146@@ -228,11 +228,11 @@
147 }
148 th.datecell,
149 td.date {
150- width: 180px;
151+ width: 100px;
152 }
153 th.timedate,
154 td.timedate2 {
155- width: 80px;
156+ width: 60px;
157 }
158 th.downloadcell,
159 td.downr {
160
161=== modified file 'loggerhead/static/css/view.css'
162--- loggerhead/static/css/view.css 2012-03-19 04:37:07 +0000
163+++ loggerhead/static/css/view.css 2012-07-25 14:53:24 +0000
164@@ -5,8 +5,7 @@
165 }
166 .viewRev {
167 border-right: none;
168- white-space: nowrap;
169- width: 1px;
170+ width: 20%;
171 padding: .3em .6em;
172 }
173 .viewComm,
174
175=== modified file 'loggerhead/templates/directory.pt'
176--- loggerhead/templates/directory.pt 2011-02-17 19:51:25 +0000
177+++ loggerhead/templates/directory.pt 2012-07-25 14:53:24 +0000
178@@ -17,16 +17,16 @@
179 <div >
180 <table id="logentries">
181 <tr class="logheader">
182- <th class="summarycell" colspan="2">Filename</th>
183- <th class="datecell">Latest Rev</th>
184+ <th class="datecell">Filename</th>
185+ <th class="timedate">Latest Rev</th>
186 <th class="datecell">Last Changed</th>
187+ <th class="datecell">Committer</th>
188+ <th class="summarycell">Comment</th>
189 </tr>
190
191 <tr class="blueRow0" tal:condition="python:name != '/'">
192- <td class="icocell">
193+ <td class="summcell" colspan="5">
194 <a href="../"><img tal:attributes="src python:static_url('/static/images/ico_folder_up.gif')" /></a>
195- </td>
196- <td class="summcell" colspan="3">
197 <a href="../">..</a>
198 </td>
199 </tr>
200@@ -34,32 +34,31 @@
201
202 <tal:branch-row tal:condition="dir/branch">
203 <tr tal:attributes="class string:blueRow${dir/parity}">
204- <td class="icocell">
205+ <td class="date">
206 <a tal:attributes="href string:${dir/dirname}/files">
207 <img tal:attributes="src python:static_url('/static/images/ico_branch.gif')" alt="Branch" />
208 </a>
209- </td>
210- <td class="autcell">
211 <a tal:attributes="href string:${dir/dirname}/files" tal:content="dir/dirname" /></td>
212 <td class="date">
213 <a tal:attributes="href string:${dir/dirname}/revision/${dir/branch/revno};
214 title string:Show revision ${dir/branch/revno}"
215 tal:content="dir/branch/revno"></a>
216 </td>
217- <td class="date" tal:content="python:util.date_time(dir.last_change)"></td>
218+ <td class="date" tal:content="python:util._approximatedate(dir.last_change_time)"></td>
219+ <td class="date" tal:content="python:util.hide_email(dir.last_revision.committer) if dir.last_revision is not None else 'Nobody'"></td>
220+ <td class="autcell" tal:content="python:dir.last_revision.message[:50] if dir.last_revision is not None else ''"></td>
221 </tr>
222+
223 </tal:branch-row>
224 <tal:non-branch-row tal:condition="not:dir/branch">
225 <tr tal:attributes="class string:blueRow${dir/parity}">
226- <td class="icocell">
227+ <td class="date">
228 <a tal:attributes="href string:${dir/dirname}/">
229 <img tal:attributes="src python:static_url('/static/images/ico_folder.gif')" alt="Folder" />
230 </a>
231- </td>
232- <td class="autcell">
233 <a tal:attributes="href string:${dir/dirname}/" tal:content="dir/dirname" /></td>
234 <td class="date"></td>
235- <td class="date" tal:content="dir/last_change"></td>
236+ <td class="date" colspan="4" tal:content="dir/last_change"></td>
237 </tr>
238 </tal:non-branch-row>
239 </tal:block>
240
241=== modified file 'loggerhead/templates/inventory.pt'
242--- loggerhead/templates/inventory.pt 2012-02-02 07:42:24 +0000
243+++ loggerhead/templates/inventory.pt 2012-07-25 14:53:24 +0000
244@@ -30,7 +30,7 @@
245 <tal:no-link condition="not: branch/branch_link">
246 <span metal:use-macro="breadcrumbs/directory"></span>
247 </tal:no-link>
248- <span>: <span metal:use-macro="breadcrumbs/branch" /> (revision <tal:revno content="change/revno"></tal:revno>)</span>
249+ <span>: <span metal:use-macro="breadcrumbs/branch" /> (Revision <tal:revno content="change/revno"></tal:revno>)</span>
250 </div>
251 </tal:block>
252
253@@ -54,10 +54,12 @@
254
255 <table id="logentries">
256 <tr class="logheader">
257- <th class="summarycell"><a tal:attributes="href python:url(['/files', revid], sort='filename')">Filename</a></th>
258- <th class="datecell">Latest Rev</th>
259- <th class="datecell"><a tal:attributes="href python:url(['/files', revid], sort='date')">Last Changed</a></th>
260- <th class="timedate"><a tal:attributes="href python:url(['/files', revid], sort='size')">Size</a></th>
261+ <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='filename')">Filename</a></th>
262+ <th class="timedate">Latest Rev</th>
263+ <th class="datecell"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='date')">Last Changed</a></th>
264+ <th class="datecell">Committer</th>
265+ <th class="summarycell">Comment</th>
266+ <th class="timedate"><a tal:attributes="href python:branch.sort_url(['/files', revid], sort='size')">Size</a></th>
267 <th class="expandcell"></th>
268 <th class="expandcell"></th>
269 </tr>
270@@ -68,11 +70,15 @@
271 <img tal:attributes="src python:branch.static_url('/static/images/ico_folder_up.gif')" />..</a>
272 </td>
273 </tr>
274+ <tr class="blueRow0" tal:condition="python:updir is None and name != '/'">
275+ <td class="summcell" colspan="6">
276+ <a tal:attributes="href python:'/'.join(branch.friendly_name.split('/')[:-1])"><img tal:attributes="src python:static_url('/static/images/ico_folder_up.gif')" />..</a></td>
277+ </tr>
278
279 <!-- Show this if it's a directory -->
280 <tal:block repeat="file filelist">
281 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='directory'">
282- <td class="autcell"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])">
283+ <td class="date"><a tal:attributes="href python:url(['/files', revno_url, file.absolutepath])">
284 <img tal:attributes="src python:branch.static_url('/static/images/ico_folder.gif');
285 title string:Go to ${file/filename}" />
286 </a>
287@@ -84,8 +90,10 @@
288 title string:Show revision ${file/change/revno}"
289 tal:content="file/change/revno"></a>
290 </td>
291- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
292- <td class="timedate2"></td>
293+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
294+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
295+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
296+ <td class="timedate2"></td><!-- not showing sizes of folders -->
297 <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id);
298 title string:Show revision ${file/change/revno}">
299 <img tal:attributes="src python:branch.static_url('/static/images/ico_planilla.gif')" alt="Diff" />
300@@ -96,7 +104,7 @@
301
302 <!-- Show this if it's a symlink -->
303 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='symlink'">
304- <td class="autcell"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])">
305+ <td class="date"><a tal:attributes="href python:url(['/view', change.revno, file.absolutepath])">
306 <img tal:attributes="src python:branch.static_url('/static/images/ico_file_flecha.gif')" alt="Symlink" />
307 </a>
308
309@@ -107,7 +115,9 @@
310 title string:Show revision ${file/change/revno}"
311 tal:content="file/change/revno"></a>
312 </td>
313- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
314+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
315+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
316+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
317 <td class="timedate2">.</td>
318 <td class="expcell"><a tal:attributes="href python:url(['/changes'], start_revid=start_revid, filter_file_id=file.file_id);
319 title string:Show revision ${file/change/revno}">
320@@ -120,7 +130,7 @@
321
322 <!-- Show this if it's a regular file -->
323 <tr tal:attributes="class string:blueRow${repeat/file/even}" tal:condition="python:file.kind=='file'">
324- <td class="autcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])">
325+ <td class="date"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath])">
326 <img tal:attributes="src python:branch.static_url('/static/images/ico_file.gif');
327 title string:View ${file/filename}"
328 tal:condition="python:file.executable is False" />
329@@ -136,7 +146,10 @@
330 title string:Show revision ${file/change/revno}"
331 tal:content="file/change/revno"></a>
332 </td>
333- <td class="date" tal:content="python:util.date_time(file.change.utc_date)"></td>
334+ <td class="date" tal:content="python:util._approximatedate(file.change.utc_date)"></td>
335+ <td class="date" tal:content="python:util.hide_email(file.change.committer)"></td>
336+ <td class="autcell" tal:content="python:file.change.comment[:50]"></td>
337+
338 <td class="timedate2" tal:content="python:util.human_size(file.size)"></td>
339 <td class="expcell"><a tal:attributes="href python:url(['/view', revno_url, file.absolutepath]);
340 title string:View ${file/filename}">
341
342=== modified file 'loggerhead/util.py'
343--- loggerhead/util.py 2012-04-25 23:39:35 +0000
344+++ loggerhead/util.py 2012-07-25 14:53:24 +0000
345@@ -73,20 +73,24 @@
346
347
348 def _approximatedate(date):
349- delta = datetime.datetime.now() - date
350- if abs(delta) > datetime.timedelta(1, 0, 0):
351- # far in the past or future, display the date
352- return date_day(date)
353- future = delta < datetime.timedelta(0, 0, 0)
354+ if date is None:
355+ return 'Never'
356+ delta = datetime.datetime.utcnow() - date
357 delta = abs(delta)
358+ years = delta.days / 365
359+ months = delta.days / 30 # This is approximate.
360 days = delta.days
361 hours = delta.seconds / 3600
362 minutes = (delta.seconds - (3600*hours)) / 60
363 seconds = delta.seconds % 60
364 result = ''
365- if future:
366- result += 'in '
367- if days != 0:
368+ if years != 0:
369+ amount = years
370+ unit = 'year'
371+ elif months != 0:
372+ amount = months
373+ unit = 'month'
374+ elif days != 0:
375 amount = days
376 unit = 'day'
377 elif hours != 0:
378@@ -101,9 +105,8 @@
379 if amount != 1:
380 unit += 's'
381 result += '%s %s' % (amount, unit)
382- if not future:
383- result += ' ago'
384- return result
385+ result += ' ago'
386+ return result
387
388
389 def _wrap_with_date_time_title(date, formatted_date):

Subscribers

People subscribed via source and target branches