Merge lp:~kfogel/launchpad/cc-script-new-world into lp:launchpad
- cc-script-new-world
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Jonathan Lange |
Approved revision: | not available |
Merge reported by: | Karl Fogel |
Merged at revision: | not available |
Proposed branch: | lp:~kfogel/launchpad/cc-script-new-world |
Merge into: | lp:launchpad |
Diff against target: |
513 lines (+274/-131) 1 file modified
utilities/community-contributions.py (+274/-131) |
To merge this branch: | bzr merge lp:~kfogel/launchpad/cc-script-new-world |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonathan Lange (community) | Approve | ||
Karl Fogel (community) | Needs Resubmitting | ||
Review via email: mp+19060@code.launchpad.net |
Commit message
[r=jml][ui=none][bug=432742] Improve the community-
Description of the change
Karl Fogel (kfogel) wrote : | # |
Jonathan Lange (jml) wrote : | # |
On Wed, Feb 10, 2010 at 10:49 PM, Karl Fogel <email address hidden> wrote:
> Karl Fogel has proposed merging lp:~kfogel/launchpad/cc-script-new-world into lp:launchpad/devel.
>
> Requested reviews:
> Jonathan Lange (jml)
>
Hey Karl,
The change looks great. Most of my comments on the code are related to
Python idioms.
If this were application code, I might push a bit harder on whether
the ExCon data structure is the best way of thinking about the
problem. As it is, it's not application code and I've run out of
neurons for the morning :)
>
> Various improvements to utilities/
>
> 1. Show Canonical developers too (those not on the Launchpad team)
> 2. Don't show huge commit blocks; just elide and link to the top rev.
> 3. Finally clean up various utf-8 encoding issues (bug #432742)
> 4. Add a '--draft-run' option for testing.
>
> You can see the results here:
>
> https:/
>
> (Compare with https:/
>
The new output is much better.
> === modified file 'utilities/
> --- utilities/
> +++ utilities/
...
> @@ -56,85 +57,133 @@
> sys.exit(1)
>
>
> -# While anyone with "@canonical.com" in their email address will be
> -# counted as a Canonical contributor, sometimes Canonical people
> -# submit from personal addresses, so we still need a list.
> +# The output contains two classes of contributors: people who don't
> +# work for Canonical at all, and people who do work for Canonical but
> +# not on the Launchpad team.
As wgrant hinted on IRC, it's worth being explicit about what we do
with Launchpad team alumnists (e.g. Carlos & Daniel Silverstone).
> #
> # XXX: Karl Fogel 2009-09-10 bug=513608: We should use launchpadlib
> -# to consult Launchpad itself to find out who's a Canonical developer.
> -known_
> - u'Aaron Bentley',
> - u'Abel Deuring',
> - u'Adam Conrad',
> - u'Andrew Bennetts',
> - u'Anthony Lenton',
> - u'Barry Warsaw',
> - u'Brad Crittenden',
> - u'Carlos Perello Marin',
> - u'Carlos Perelló Marín',
> - u'Celso Providelo',
> - u'Christian Robottom Reis',
> - u'Cody Somerville',
> - u'Curtis Hovey',
> - u'Dafydd Harries',
> - u'Daniel Silverstone',
> - u'Danilo Šegan',
> - u'Данило Шеган',
> - u'данило шеган',
> - u'David Allouche',
> - u'Deryck Hodge',
> - u'Diogo Matsubara',
> - u'Elliot Murphy',
> - u'Francis J. Lacoste',
> - u'Gabriel Neuman <email address hidden>',
> - u'Gary Poster',
> - u'Guilherme Salgado',
> - u'Gustavo Niemeyer',
> - u'Henning Eggers',
> - u'Herb McNew',
> - u'James Henstridge',
> - u'Jelmer Vernooij',
> - u'Jeroen Vermeulen',
> - u'Jonathan Knowles',
> - u'Jonathan Lange',
> - u'Julian Edwards',
> - u'Karl Fogel',
> - u'Kees Cook',
> - u'Launch Pad',
> - u'Launchpad Developers',
> - u'LaMont Jones',
> - u'Leonard Richardson',
> - u'Malcolm Cleaton',
> - u'Maris Fogels',
> - u'Martin...
Jonathan Lange (jml) : | # |
Karl Fogel (kfogel) wrote : | # |
Thanks for the thorough review, Jono. All comments addressed; please see the latest.
Jonathan Lange (jml) wrote : | # |
Thanks Karl. Looks good to me.
Preview Diff
1 | === modified file 'utilities/community-contributions.py' |
2 | --- utilities/community-contributions.py 2010-02-08 14:38:31 +0000 |
3 | +++ utilities/community-contributions.py 2010-02-22 15:15:33 +0000 |
4 | @@ -18,9 +18,10 @@ |
5 | have it, the error message will tell you where to get it). |
6 | |
7 | Options: |
8 | - -q Print no non-essential messages. |
9 | - -h, --help Print this help. |
10 | - --dry-run Don't update the wiki, just print the new wiki page to stdout. |
11 | + -q Print no non-essential messages. |
12 | + -h, --help Print this help. |
13 | + --dry-run Don't update the wiki, just print the new wiki page to stdout. |
14 | + --draft-run Update the wiki "/Draft" page instead of the real page. |
15 | """ |
16 | |
17 | # General notes: |
18 | @@ -56,85 +57,160 @@ |
19 | sys.exit(1) |
20 | |
21 | |
22 | -# While anyone with "@canonical.com" in their email address will be |
23 | -# counted as a Canonical contributor, sometimes Canonical people |
24 | -# submit from personal addresses, so we still need a list. |
25 | +def wiki_encode(x): |
26 | + """Encode a Unicode string for display on the wiki.""" |
27 | + return x.encode('utf-8', 'xmlcharrefreplace') |
28 | + |
29 | + |
30 | + |
31 | +# The output contains two classes of contributors: people who don't |
32 | +# work for Canonical at all, and people who do work for Canonical but |
33 | +# not on the Launchpad team. |
34 | +# |
35 | +# People who used to work for Canonical on the Launchpad team are not |
36 | +# shown in the output, since they don't help us from a "contributions |
37 | +# from outside the team" perspective, so they are listed as known |
38 | +# Canonical Launchpad developers even though they aren't actually on |
39 | +# the team anymore. There may be a few former Canonicalites who |
40 | +# didn't work on the Launchpad team but who still contributed to |
41 | +# Launchpad; most of them would have done so before Launchpad was open |
42 | +# sourced in July 2009, though, and since this script is really about |
43 | +# showing things that have happened since Launchpad was open sourced, |
44 | +# they may be listed as Launchpad team members anyway just to ensure |
45 | +# they don't appear in the output. |
46 | +# |
47 | +# (As time goes on, that assumption will be less and less correct, of |
48 | +# course, and eventually we may wish to do something about it. Also, |
49 | +# there are some people, e.g. Jelmer Vernooij, who made contributions |
50 | +# to Launchpad before working at Canonical, but who now work on the |
51 | +# Launchpad team at Canonical. Ideally, each potentially listable |
52 | +# contributor could have a set of roles, and a date range associated |
53 | +# with each role... but that would be overkill for this script. That |
54 | +# last 2% of correctness would cost way too much to achieve.) |
55 | # |
56 | # XXX: Karl Fogel 2009-09-10 bug=513608: We should use launchpadlib |
57 | -# to consult Launchpad itself to find out who's a Canonical developer. |
58 | -known_canonical_devs = ( |
59 | - u'Aaron Bentley', |
60 | - u'Abel Deuring', |
61 | - u'Adam Conrad', |
62 | - u'Andrew Bennetts', |
63 | - u'Anthony Lenton', |
64 | - u'Barry Warsaw', |
65 | - u'Brad Crittenden', |
66 | - u'Carlos Perello Marin', |
67 | - u'Carlos Perelló Marín', |
68 | - u'Celso Providelo', |
69 | - u'Christian Robottom Reis', |
70 | - u'Cody Somerville', |
71 | - u'Curtis Hovey', |
72 | - u'Dafydd Harries', |
73 | - u'Daniel Silverstone', |
74 | - u'Danilo Šegan', |
75 | - u'Данило Шеган', |
76 | - u'данило шеган', |
77 | - u'David Allouche', |
78 | - u'Deryck Hodge', |
79 | - u'Diogo Matsubara', |
80 | - u'Elliot Murphy', |
81 | - u'Francis J. Lacoste', |
82 | - u'Gabriel Neuman gneuman@async.com', |
83 | - u'Gary Poster', |
84 | - u'Guilherme Salgado', |
85 | - u'Gustavo Niemeyer', |
86 | - u'Henning Eggers', |
87 | - u'Herb McNew', |
88 | - u'James Henstridge', |
89 | - u'Jelmer Vernooij', |
90 | - u'Jeroen Vermeulen', |
91 | - u'Jonathan Knowles', |
92 | - u'Jonathan Lange', |
93 | - u'Julian Edwards', |
94 | - u'Karl Fogel', |
95 | - u'Kees Cook', |
96 | - u'Launch Pad', |
97 | - u'Launchpad Developers', |
98 | - u'LaMont Jones', |
99 | - u'Leonard Richardson', |
100 | - u'Malcolm Cleaton', |
101 | - u'Maris Fogels', |
102 | - u'Martin Albisetti', |
103 | - u'Martin Pool', |
104 | - u'Matt Zimmerman', |
105 | - u'Matthew Revell', |
106 | - u'Michael Hudson', |
107 | - u'Michael Nelson', |
108 | - u'Muharem Hrnjadovic', |
109 | - u'Patch Queue Manager', |
110 | - u'Paul Hummer', |
111 | - u'Robert Collins', |
112 | - u'Sidnei', |
113 | - u'Sidnei da Silva', |
114 | - u'Steve Kowalik', |
115 | - u'Steve McInerney', |
116 | - u'Stuart Bishop', |
117 | - u'Tom Berger', |
118 | - u'david', |
119 | - u'jml@mumak.net', |
120 | - u'kiko@beetle', |
121 | - ) |
122 | +# to consult Launchpad itself to find out who's a Canonical developer, |
123 | +# and within that who's a Launchpad developer. |
124 | + |
125 | + |
126 | +# If a contributor's address contains this, then they are or were a |
127 | +# Canonical developer -- maybe on the Launchpad team, maybe not. |
128 | +CANONICAL_ADDR = wiki_encode(u" {_AT_} canonical.com") |
129 | + |
130 | +# People on the Canonical Launchpad team. |
131 | +known_canonical_lp_devs = \ |
132 | + [wiki_encode(x) for x in (u'Aaron Bentley', |
133 | + u'Abel Deuring', |
134 | + u'Andrew Bennetts', |
135 | + u'Barry Warsaw', |
136 | + u'Bjorn Tillenius', |
137 | + u'Björn Tillenius', |
138 | + u'Brad Crittenden', |
139 | + u'Brian Fromme', |
140 | + u'Carlos Perello Marin', |
141 | + u'Carlos Perelló Marín', |
142 | + u'Celso Providelo', |
143 | + u'Christian Reis', |
144 | + u'kiko {_AT_} beetle', |
145 | + u'Curtis Hovey', |
146 | + u'Dafydd Harries', |
147 | + u'Danilo Šegan', |
148 | + u'Данило Шеган', |
149 | + u'данило шеган', |
150 | + u'Daniel Silverstone', |
151 | + u'David Allouche', |
152 | + u'Deryck Hodge', |
153 | + u'Diogo Matsubara', |
154 | + u'Edwin Grubbs', |
155 | + u'Francis Lacoste', |
156 | + u'Francis J. Lacoste', |
157 | + u'Gary Poster', |
158 | + u'Gavin Panella', |
159 | + u'Graham Binns', |
160 | + u'Guilherme Salgado', |
161 | + u'Henning Eggers', |
162 | + u'James Henstridge', |
163 | + u'Jelmer Vernooij', |
164 | + u'Jeroen Vermeulen', |
165 | + u'Jeroen T. Vermeulen', |
166 | + u'Joey Stanford', |
167 | + u'Jonathan Lange', |
168 | + u'jml {_AT_} canonical.com', |
169 | + u'jml {_AT_} mumak.net', |
170 | + u'Jonathan Knowles', |
171 | + u'Julian Edwards', |
172 | + u'Karl Fogel', |
173 | + u'Launchpad APA', |
174 | + u'Launchpad Patch Queue Manager', |
175 | + u'Launchpad PQM Bot', |
176 | + u'Leonard Richardson', |
177 | + u'Malcolm Cleaton', |
178 | + u'Maris Fogels', |
179 | + u'Mark Shuttleworth', |
180 | + u'Martin Albisetti', |
181 | + u'Martin Pool', |
182 | + u'Matt Zimmerman', |
183 | + u'Matthew Paul Thomas', |
184 | + u'Matthew Revell', |
185 | + u'matthew.revell {_AT_} canonical.com', |
186 | + u'Michael Hudson', |
187 | + u'Michael Nelson', |
188 | + u'Muharem Hrnjadovic', |
189 | + u'muharem {_AT_} canonical.com', |
190 | + u'Paul Hummer', |
191 | + u'Robert Collins', |
192 | + u'Stuart Bishop', |
193 | + u'Steve McInerney', |
194 | + u'<steve {_AT_} stedee.id.au>', |
195 | + u'Tom Haddon', |
196 | + u'Tim Penhey', |
197 | + u'Tom Berger', |
198 | + u'Ursula Junque', |
199 | + )] |
200 | + |
201 | +# People known to work for Canonical but not on the Launchpad team. |
202 | +# Anyone with "@canonical.com" in their email address is considered to |
203 | +# work for Canonical, but some people occasionally submit changes from |
204 | +# their personal email addresses; this list contains people known to |
205 | +# do that, so we can treat them appropriately in the output. |
206 | +known_canonical_non_lp_devs = \ |
207 | + [wiki_encode(x) for x in (u'Adam Conrad', |
208 | + u'Andrew Bennetts', |
209 | + u'Anthony Lenton', |
210 | + u'Cody Somerville', |
211 | + u'Cody A.W. Somerville', |
212 | + u'David Murphy', |
213 | + u'Elliot Murphy', |
214 | + u'Gabriel Neuman gneuman {_AT_} async.com', |
215 | + u'Gustavo Niemeyer', |
216 | + u'James Henstridge', |
217 | + u'John Lenton', |
218 | + u'Kees Cook', |
219 | + u'LaMont Jones', |
220 | + u'Martin Pool', |
221 | + u'Matt Zimmerman', |
222 | + u'Michael Casadevall', |
223 | + u'Michael Vogt', |
224 | + u'Sidnei da Silva', |
225 | + u'Steve Kowalik', |
226 | + )] |
227 | |
228 | # Some people have made commits using various names and/or email |
229 | # addresses, so this map will be used to merge them accordingly. |
230 | -merge_names_map = { |
231 | - u'Jamal Fanaian <jfanaian@gmail.com>': |
232 | - u'Jamal Fanaian <jamal.fanaian@gmail.com>', |
233 | - u'Jamal Fanaian <jamal@jfvm1>': |
234 | - u'Jamal Fanaian <jamal.fanaian@gmail.com>', |
235 | - } |
236 | +# The map is initialized from this list of pairs, where each pair is |
237 | +# of the form (CONTRIBUTOR_AS_SEEN, UNIFYING_IDENTITY_FOR_CONTRIBUTOR). |
238 | +merge_names_pairs = ( |
239 | + (u'Jamal Fanaian <jfanaian {_AT_} gmail.com>', |
240 | + u'Jamal Fanaian <jamal.fanaian {_AT_} gmail.com>'), |
241 | + (u'Jamal Fanaian <jamal {_AT_} jfvm1>', |
242 | + u'Jamal Fanaian <jamal.fanaian {_AT_} gmail.com>'), |
243 | + (u'LaMont Jones <lamont {_AT_} rover3>', |
244 | + u'LaMont Jones <lamont {_AT_} debian.org>'), |
245 | + ) |
246 | +# Then put it in dictionary form with the correct encodings. |
247 | +merge_names_map = dict((wiki_encode(a), wiki_encode(b)) |
248 | + for a, b in merge_names_pairs) |
249 | + |
250 | |
251 | class ContainerRevision(): |
252 | """A wrapper for a top-level LogRevision containing child LogRevisions.""" |
253 | @@ -187,14 +263,22 @@ |
254 | # will give you some information about it before you click |
255 | # (because a rev id often identifies the committer). |
256 | rev_id_url = rev_url_base + rev_id |
257 | + |
258 | + if len(self.contained_revs) <= 10: |
259 | + commits_block = "\n ".join( |
260 | + ["[[%s|%s]]" % (rev_url_base + lr.rev.revision_id, lr.revno) |
261 | + for lr in self.contained_revs]) |
262 | + else: |
263 | + commits_block = ("''see the [[%s|full revision]] for details " |
264 | + "(it contains %d commits)''" |
265 | + % (rev_id_url, len(self.contained_revs))) |
266 | + |
267 | text = [ |
268 | " * [[%s|r%s]] -- %s\n" % (rev_id_url, self.top_rev.revno, |
269 | date_str), |
270 | " {{{\n%s\n}}}\n" % message, |
271 | " '''Commits:'''\n ", |
272 | - "\n ".join(["[[%s|%s]]" % (rev_url_base + lr.rev.revision_id, |
273 | - lr.revno) |
274 | - for lr in self.contained_revs]), |
275 | + commits_block, |
276 | "\n", |
277 | ] |
278 | return ''.join(text) |
279 | @@ -202,14 +286,17 @@ |
280 | |
281 | # "ExternalContributor" is too much to type, so I guess we'll just use this. |
282 | class ExCon(): |
283 | - """A contributor to Launchpad from outside Canonical.""" |
284 | - |
285 | - def __init__(self, name): |
286 | - """Create a new external contributor named NAME. NAME is usually |
287 | - e.g. "Veronica Random <veronica@example.com>", but any "@"-sign |
288 | - will be disguised in the new object.""" |
289 | - |
290 | - self.name = name.replace("@", " {_AT_} ") |
291 | + """A contributor to Launchpad from outside Canonical's Launchpad team.""" |
292 | + |
293 | + def __init__(self, name, is_canonical=False): |
294 | + """Create a new external contributor named 'name'. |
295 | + |
296 | + If 'is_canonical' is True, then this is a contributor from |
297 | + within Canonical, but not on the Launchpad team at Canonical. |
298 | + 'name' is something like "Veronica Random <vr {_AT_} example.com>". |
299 | + """ |
300 | + self.name = name |
301 | + self.is_canonical = is_canonical |
302 | # If name is "Veronica Random <veronica {_AT_} example.com>", |
303 | # then name_as_anchor will be "veronica_random". |
304 | self.name_as_anchor = \ |
305 | @@ -231,10 +318,13 @@ |
306 | def show_contributions(self): |
307 | "Return a wikified string showing this contributor's contributions." |
308 | plural = "s" |
309 | + name = self.name |
310 | + if self.is_canonical: |
311 | + name = name + " (Canonical developer)" |
312 | if self.num_landings() == 1: |
313 | plural = "" |
314 | text = [ |
315 | - "== %s ==\n\n" % self.name, |
316 | + "=== %s ===\n\n" % name, |
317 | "''%d top-level landing%s:''\n\n" % (self.num_landings(), plural), |
318 | ''.join(map(str, sorted(self._landings, |
319 | key=lambda x: x.top_rev.revno, |
320 | @@ -253,29 +343,47 @@ |
321 | the bzr logs, i.e., with email address undisguised) to ExCon objects. |
322 | """ |
323 | ex_cons_this_rev = [] |
324 | - for a in authors: |
325 | - known = False |
326 | - for name_fragment in known_canonical_devs: |
327 | - if u"@canonical.com" in a or name_fragment in a: |
328 | - known = True |
329 | + for author in authors: |
330 | + known_canonical_lp_dev = False |
331 | + known_canonical_non_lp_dev = False |
332 | + # The authors we list in the source code have their addresses |
333 | + # disguised (since this source code is public). We must |
334 | + # disguise the ones coming from the Bazaar logs in the same way, |
335 | + # so string matches will work. |
336 | + author = wiki_encode(author) |
337 | + author = author.replace("@", " {_AT_} ") |
338 | + |
339 | + # If someone works/worked for Canonical on the Launchpad team, |
340 | + # then skip them -- we don't want to show them in the output. |
341 | + for name_fragment in known_canonical_lp_devs: |
342 | + if name_fragment in author: |
343 | + known_canonical_lp_dev = True |
344 | break |
345 | - if not known: |
346 | - # Use the merge names map to merge contributions from the same |
347 | - # person using alternate names and/or emails. |
348 | - if a in merge_names_map: |
349 | - a = merge_names_map[a] |
350 | - |
351 | - ### There's a variant of the Singleton pattern that could be |
352 | - ### used for this, whereby instantiating an ExCon object would |
353 | - ### just get back an existing object if such has already been |
354 | - ### instantiated for this name. But that would make this code |
355 | - ### non-reentrant, and that's just not cool. |
356 | - if a in all_ex_cons: |
357 | - ec = all_ex_cons[a] |
358 | - else: |
359 | - ec = ExCon(a) |
360 | - all_ex_cons[a] = ec |
361 | - ex_cons_this_rev.append(ec) |
362 | + if known_canonical_lp_dev: |
363 | + continue |
364 | + |
365 | + # Use the merge names map to merge contributions from the same |
366 | + # person using alternate names and/or emails. |
367 | + author = merge_names_map.get(author, author) |
368 | + |
369 | + if CANONICAL_ADDR in author: |
370 | + known_canonical_non_lp_dev = True |
371 | + else: |
372 | + for name_fragment in known_canonical_non_lp_devs: |
373 | + if name_fragment in author: |
374 | + known_canonical_non_lp_dev = True |
375 | + break |
376 | + |
377 | + # There's a variant of the Singleton pattern that could be |
378 | + # used for this, whereby instantiating an ExCon object would |
379 | + # just get back an existing object if such has already been |
380 | + # instantiated for this name. But that would make this code |
381 | + # non-reentrant, and that's just not cool. |
382 | + ec = all_ex_cons.get(author, None) |
383 | + if ec is None: |
384 | + ec = ExCon(author, is_canonical=known_canonical_non_lp_dev) |
385 | + all_ex_cons[author] = ec |
386 | + ex_cons_this_rev.append(ec) |
387 | return ex_cons_this_rev |
388 | |
389 | |
390 | @@ -296,26 +404,55 @@ |
391 | # top-level rev. |
392 | current_top_level_rev = None |
393 | |
394 | + def _toc(self, contributors): |
395 | + toc_text = [] |
396 | + for val in contributors: |
397 | + plural = "s" |
398 | + if val.num_landings() == 1: |
399 | + plural = "" |
400 | + toc_text.extend(" 1. [[#%s|%s]] ''(%d top-level landing%s)''\n" |
401 | + % (val.name_as_anchor, val.name, |
402 | + val.num_landings(), plural)) |
403 | + return toc_text |
404 | + |
405 | def result(self): |
406 | "Return a moin-wiki-syntax string with TOC followed by contributions." |
407 | + |
408 | + # Divide contributors into non-Canonical and Canonical. |
409 | + non_canonical_contributors = [x for x in self.all_ex_cons.values() |
410 | + if not x.is_canonical] |
411 | + canonical_contributors = [x for x in self.all_ex_cons.values() |
412 | + if x.is_canonical] |
413 | + # Sort them. |
414 | + non_canonical_contributors = sorted(non_canonical_contributors, |
415 | + key=lambda x: x.num_landings(), |
416 | + reverse=True) |
417 | + canonical_contributors = sorted(canonical_contributors, |
418 | + key=lambda x: x.num_landings(), |
419 | + reverse=True) |
420 | + |
421 | text = [ |
422 | "-----\n\n", |
423 | - "= Who =\n\n", |
424 | + "= Who =\n\n" |
425 | + "== Contributors (from outside Canonical) ==\n\n", |
426 | ] |
427 | - sorted_contributors = sorted(self.all_ex_cons.values(), |
428 | - key=lambda x: x.num_landings(), |
429 | - reverse=True) |
430 | - for val in sorted_contributors: |
431 | - plural = "s" |
432 | - if val.num_landings() == 1: |
433 | - plural = "" |
434 | - text.extend(" 1. [[#%s|%s]] ''(%d top-level landing%s)''\n" |
435 | - % (val.name_as_anchor, val.name, |
436 | - val.num_landings(), plural)) |
437 | + text.extend(self._toc(non_canonical_contributors)) |
438 | + text.extend([ |
439 | + "== Contributors (from Canonical, but outside " |
440 | + "the Launchpad team) ==\n\n", |
441 | + ]) |
442 | + text.extend(self._toc(canonical_contributors)) |
443 | text.extend(["\n-----\n\n", |
444 | "= What =\n\n", |
445 | - ]) |
446 | - for val in sorted_contributors: |
447 | + "== Contributions (from outside Canonical) ==\n\n", |
448 | + ]) |
449 | + for val in non_canonical_contributors: |
450 | + text.extend("<<Anchor(%s)>>\n" % val.name_as_anchor) |
451 | + text.extend(val.show_contributions()) |
452 | + text.extend(["== Contributions (from Canonical, but outside " |
453 | + "the Launchpad team) ==\n\n", |
454 | + ]) |
455 | + for val in canonical_contributors: |
456 | text.extend("<<Anchor(%s)>>\n" % val.name_as_anchor) |
457 | text.extend(val.show_contributions()) |
458 | return ''.join(text) |
459 | @@ -343,11 +480,14 @@ |
460 | print __doc__ |
461 | |
462 | |
463 | +# Use backslashes to suppress newlines because this is wiki syntax, |
464 | +# not HTML, so newlines would be rendered as line breaks. |
465 | page_intro = """This page shows contributions to Launchpad from \ |
466 | -outside Canonical. It only lists changes that have landed in the \ |
467 | -Launchpad ''devel'' tree, so changes that land in ''db-devel'' first \ |
468 | -may take a while to show up (see the [[Trunk|trunk explanation]] for \ |
469 | -more). |
470 | +developers not on the Launchpad team at Canonical. |
471 | + |
472 | +It only lists changes that have landed in the Launchpad ''devel'' \ |
473 | +tree, so changes that land in ''db-devel'' first may take a while to \ |
474 | +show up (see the [[Trunk|trunk explanation]] for more). |
475 | |
476 | ~-''Note for maintainers: this page is updated every 10 minutes by a \ |
477 | cron job running as kfogel on devpad (though if there are no new \ |
478 | @@ -363,13 +503,15 @@ |
479 | target = None |
480 | dry_run = False |
481 | |
482 | + wiki_dest = "https://dev.launchpad.net/Contributions" |
483 | + |
484 | if len(sys.argv) < 2: |
485 | usage() |
486 | sys.exit(1) |
487 | |
488 | try: |
489 | opts, args = getopt.getopt(sys.argv[1:], '?hq', |
490 | - ['help', 'usage', 'dry-run']) |
491 | + ['help', 'usage', 'dry-run', 'draft-run']) |
492 | except getopt.GetoptError, e: |
493 | sys.stderr.write("ERROR: " + str(e) + '\n\n') |
494 | usage() |
495 | @@ -383,6 +525,8 @@ |
496 | quiet = True |
497 | elif opt == '--dry-run': |
498 | dry_run = True |
499 | + elif opt == '--draft-run': |
500 | + wiki_dest += "/Draft" |
501 | |
502 | # Ensure we have the arguments we need. |
503 | if len(args) < 1: |
504 | @@ -419,8 +563,7 @@ |
505 | if not quiet: |
506 | print "Updating wiki..." |
507 | # Not sure how to get editmoin to obey our quiet flag. |
508 | - editshortcut("https://dev.launchpad.net/Contributions", |
509 | - editfile_func=update_if_modified) |
510 | + editshortcut(wiki_dest, editfile_func=update_if_modified) |
511 | if not quiet: |
512 | print "Done updating wiki." |
513 | else: |
Various improvements to utilities/ community- contributions. py. Namely:
1. Show Canonical developers too (those not on the Launchpad team)
2. Don't show huge commit blocks; just elide and link to the top rev.
3. Finally clean up various utf-8 encoding issues (bug #432742)
4. Add a '--draft-run' option for testing.
You can see the results here:
https:/ /dev.launchpad. net/Contributio ns/Draft
(Compare with https:/ /dev.launchpad. net/Contributio ns for old output.)