Merge lp:~allenap/launchpad/dont-pass-bugwatches-to-externalbugtracker into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~allenap/launchpad/dont-pass-bugwatches-to-externalbugtracker
Merge into: lp:launchpad
Diff against target: 612 lines (+100/-89)
9 files modified
lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt (+17/-15)
lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt (+9/-8)
lib/lp/bugs/doc/externalbugtracker-debbugs.txt (+9/-9)
lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt (+12/-11)
lib/lp/bugs/externalbugtracker/bugzilla.py (+15/-15)
lib/lp/bugs/externalbugtracker/debbugs.py (+7/-7)
lib/lp/bugs/externalbugtracker/trac.py (+9/-9)
lib/lp/bugs/interfaces/externalbugtracker.py (+16/-11)
lib/lp/bugs/scripts/checkwatches.py (+6/-4)
To merge this branch: bzr merge lp:~allenap/launchpad/dont-pass-bugwatches-to-externalbugtracker
Reviewer Review Type Date Requested Status
Michael Nelson (community) code Approve
Review via email: mp+16899@code.launchpad.net

Commit message

Pass only the remote bug ID into providers of ISupportsCommentmport. Previously bug watch objects were passed, but the external bug tracker code is meant to be independent of DB code, only the remotebug attribute was referenced in all cases, and methods in related interfaces all requested remote bug IDs rather than bug watches.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

There were several calls into code in the externalbugtracker module that passed BugWatch objects. Two things:

1. The *only* field of these BugWatch objects ever referenced is `remotebug`. I've changed all methods to accept a `remote_bug_id` parameter instead of `bug_watch`, and all call-sites have been updated accordingly.

2. These are database/model objects. There is a nascent plan to also package and run the externalbugtracker code as a job-running service, outside of the familiar core Launchpad application. It's much easier to pass/serialize a `remote_bug_id` parameter (always a string) into a job spec than a model object.

Lint free.

Test: bin/test -vvt 'checkwatch|bug-?watch|bug-?track|bug-?import|bug-?notification'

Revision history for this message
Michael Nelson (michael.nelson) wrote :

G'day Gavin,

All looks very straight forward. Just one tiny comment below.

> === modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt'
> --- lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2009-12-23 10:49:55 +0000
> +++ lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2010-01-07 12:21:47 +0000
> @@ -406,7 +406,7 @@
> a given remote bug.
>
> >>> bugzilla.xmlrpc_transport.print_method_calls = True
> - >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch)
> + >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch.remotebug)
> CALLED Bug.comments({'ids': [1], 'include_fields': ['id']})
>
> >>> print sorted(bug_comment_ids)
> @@ -415,7 +415,7 @@
> getCommentIds() can only be called if initializeRemoteBugDB() has been
> called and the bug exists locally.
>
> - >>> bugzilla.getCommentIds(bug_watch_broken)
> + >>> bugzilla.getCommentIds(bug_watch_broken.remotebug)
> Traceback (most recent call last):
> ...
> BugNotFound: 42
> @@ -425,11 +425,11 @@
> ---------------
>
> ISupportsCommentImport.fetchComments() is the method used to fetch a
> -given set of comments from the remote bugtracker. It takes a bug watch
> -and a list of the comment IDs to retrieve for that bug watch.
> +given set of comments from the remote bugtracker. It takes a remote
> +bug and a list of the comment IDs to retrieve for that bug watch.

It seems everywhere else you've referred to it as a remote bug ID, which
I think is clearer (I was at first expecting it to be an object).

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt'
--- lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2009-12-23 10:49:55 +0000
+++ lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2010-01-07 12:59:20 +0000
@@ -406,7 +406,7 @@
406a given remote bug.406a given remote bug.
407407
408 >>> bugzilla.xmlrpc_transport.print_method_calls = True408 >>> bugzilla.xmlrpc_transport.print_method_calls = True
409 >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch)409 >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch.remotebug)
410 CALLED Bug.comments({'ids': [1], 'include_fields': ['id']})410 CALLED Bug.comments({'ids': [1], 'include_fields': ['id']})
411411
412 >>> print sorted(bug_comment_ids)412 >>> print sorted(bug_comment_ids)
@@ -415,7 +415,7 @@
415getCommentIds() can only be called if initializeRemoteBugDB() has been415getCommentIds() can only be called if initializeRemoteBugDB() has been
416called and the bug exists locally.416called and the bug exists locally.
417417
418 >>> bugzilla.getCommentIds(bug_watch_broken)418 >>> bugzilla.getCommentIds(bug_watch_broken.remotebug)
419 Traceback (most recent call last):419 Traceback (most recent call last):
420 ...420 ...
421 BugNotFound: 42421 BugNotFound: 42
@@ -425,11 +425,11 @@
425---------------425---------------
426426
427ISupportsCommentImport.fetchComments() is the method used to fetch a427ISupportsCommentImport.fetchComments() is the method used to fetch a
428given set of comments from the remote bugtracker. It takes a bug watch428given set of comments from the remote bugtracker. It takes a remote
429and a list of the comment IDs to retrieve for that bug watch.429bug ID and a list of the comment IDs to retrieve for that bug watch.
430430
431 >>> bugzilla.xmlrpc_transport.print_method_calls = False431 >>> bugzilla.xmlrpc_transport.print_method_calls = False
432 >>> bugzilla.fetchComments(bug_watch, ['1', '3'])432 >>> bugzilla.fetchComments(bug_watch.remotebug, ['1', '3'])
433433
434The comments will be stored in the bugs dict as a dict of comment id =>434The comments will be stored in the bugs dict as a dict of comment id =>
435comment dict mappings under the key 'comments'.435comment dict mappings under the key 'comments'.
@@ -459,7 +459,7 @@
459fetchComments() will silently ignore them.459fetchComments() will silently ignore them.
460460
461 >>> bugzilla.xmlrpc_transport.print_method_calls = False461 >>> bugzilla.xmlrpc_transport.print_method_calls = False
462 >>> bugzilla.fetchComments(bug_watch, ['1', '4'])462 >>> bugzilla.fetchComments(bug_watch.remotebug, ['1', '4'])
463463
464 >>> comments = bugzilla._bugs[1]['comments']464 >>> comments = bugzilla._bugs[1]['comments']
465 >>> for comment_id in sorted(comments):465 >>> for comment_id in sorted(comments):
@@ -482,8 +482,9 @@
482ISupportsCommentImport.getPosterForComment() returns a tuple of482ISupportsCommentImport.getPosterForComment() returns a tuple of
483(displayname, email) for the author of a remote comment.483(displayname, email) for the author of a remote comment.
484484
485 >>> bugzilla.fetchComments(bug_watch_two, ['2', '4'])485 >>> bugzilla.fetchComments(bug_watch_two.remotebug, ['2', '4'])
486 >>> displayname, email = bugzilla.getPosterForComment(bug_watch_two, '4')486 >>> displayname, email = bugzilla.getPosterForComment(
487 ... bug_watch_two.remotebug, '4')
487 >>> print displayname, email488 >>> print displayname, email
488 Ford Prefect ford.prefect@h2g2.com489 Ford Prefect ford.prefect@h2g2.com
489490
@@ -491,7 +492,8 @@
491address then the method will return displayname = None and will return492address then the method will return displayname = None and will return
492the whole of the author's name in the email field.493the whole of the author's name in the email field.
493494
494 >>> displayname, email = bugzilla.getPosterForComment(bug_watch_two, '2')495 >>> displayname, email = bugzilla.getPosterForComment(
496 ... bug_watch_two.remotebug, '2')
495 >>> print displayname, email497 >>> print displayname, email
496 None trillian498 None trillian
497499
@@ -500,13 +502,13 @@
500----------------------502----------------------
501503
502ISupportsCommentImport.getMessageForComment() returns a Launchpad504ISupportsCommentImport.getMessageForComment() returns a Launchpad
503IMessage instance for a given comment. It takes a bug watch, a comment505IMessage instance for a given comment. It takes a remote bug ID, a
504ID and a Person object generated from the return value of506comment ID and a Person object generated from the return value of
505getPosterForComment(), above. For the sake of this test we'll use507getPosterForComment(), above. For the sake of this test we'll use
506Sample Person as our poster.508Sample Person as our poster.
507509
508 >>> message = bugzilla.getMessageForComment(510 >>> message = bugzilla.getMessageForComment(
509 ... bug_watch_two, '2', sample_person)511 ... bug_watch_two.remotebug, '2', sample_person)
510 >>> print message.text_contents512 >>> print message.text_contents
511 Bring the passengers to the bridge please Marvin.513 Bring the passengers to the bridge please Marvin.
512514
@@ -560,12 +562,12 @@
560The comment will be stored on the remote server with the other comments.562The comment will be stored on the remote server with the other comments.
561563
562 >>> bugzilla.xmlrpc_transport.print_method_calls = False564 >>> bugzilla.xmlrpc_transport.print_method_calls = False
563 >>> print sorted(bugzilla.getCommentIds(bug_watch))565 >>> print sorted(bugzilla.getCommentIds(bug_watch.remotebug))
564 ['1', '3', '5']566 ['1', '3', '5']
565567
566 >>> bugzilla.fetchComments(bug_watch, ['5'])568 >>> bugzilla.fetchComments(bug_watch.remotebug, ['5'])
567 >>> message = bugzilla.getMessageForComment(569 >>> message = bugzilla.getMessageForComment(
568 ... bug_watch, '5', sample_person)570 ... bug_watch.remotebug, '5', sample_person)
569 >>> print message.text_contents571 >>> print message.text_contents
570 This is a new remote comment.572 This is a new remote comment.
571 <BLANKLINE>573 <BLANKLINE>
572574
=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt'
--- lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt 2009-12-23 10:49:55 +0000
+++ lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt 2010-01-07 12:59:20 +0000
@@ -377,7 +377,7 @@
377comment IDs for a given bug on a remote bugtracker.377comment IDs for a given bug on a remote bugtracker.
378378
379 >>> bugzilla.xmlrpc_transport.print_method_calls = True379 >>> bugzilla.xmlrpc_transport.print_method_calls = True
380 >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch)380 >>> bug_comment_ids = bugzilla.getCommentIds(bug_watch.remotebug)
381 CALLED Launchpad.comments({'bug_ids': [1], 'include_fields': ['id']})381 CALLED Launchpad.comments({'bug_ids': [1], 'include_fields': ['id']})
382382
383 >>> print sorted(bug_comment_ids)383 >>> print sorted(bug_comment_ids)
@@ -386,7 +386,7 @@
386getCommentIds() can only be called if initializeRemoteBugDB() has been386getCommentIds() can only be called if initializeRemoteBugDB() has been
387called and the bug exists locally.387called and the bug exists locally.
388388
389 >>> bugzilla.getCommentIds(bug_watch_broken)389 >>> bugzilla.getCommentIds(bug_watch_broken.remotebug)
390 Traceback (most recent call last):390 Traceback (most recent call last):
391 ...391 ...
392 BugNotFound: 42392 BugNotFound: 42
@@ -396,11 +396,11 @@
396---------------396---------------
397397
398ISupportsCommentImport.fetchComments() is the method used to fetch a398ISupportsCommentImport.fetchComments() is the method used to fetch a
399given set of comments from the remote bugtracker. It takes a bug watch399given set of comments from the remote bugtracker. It takes a remote
400and a list of the comment IDs to retrieve for that bug watch.400bug ID and a list of the comment IDs to retrieve for that bug watch.
401401
402 >>> bugzilla.xmlrpc_transport.print_method_calls = False402 >>> bugzilla.xmlrpc_transport.print_method_calls = False
403 >>> bugzilla.fetchComments(bug_watch, ['1', '3'])403 >>> bugzilla.fetchComments(bug_watch.remotebug, ['1', '3'])
404404
405The comments will be stored in the bugs dict as a dict of comment id =>405The comments will be stored in the bugs dict as a dict of comment id =>
406comment dict mappings under the key 'comments'.406comment dict mappings under the key 'comments'.
@@ -466,11 +466,12 @@
466The comment will be stored on the remote server with the other comments.466The comment will be stored on the remote server with the other comments.
467467
468 >>> bugzilla.xmlrpc_transport.print_method_calls = False468 >>> bugzilla.xmlrpc_transport.print_method_calls = False
469 >>> print sorted(bugzilla.getCommentIds(bug_watch))469 >>> print sorted(bugzilla.getCommentIds(bug_watch.remotebug))
470 ['1', '3', '5']470 ['1', '3', '5']
471471
472 >>> bugzilla.fetchComments(bug_watch, ['5'])472 >>> bugzilla.fetchComments(bug_watch.remotebug, ['5'])
473 >>> message = bugzilla.getMessageForComment(bug_watch, '5', sample_person)473 >>> message = bugzilla.getMessageForComment(
474 ... bug_watch.remotebug, '5', sample_person)
474 >>> print message.text_contents475 >>> print message.text_contents
475 This is a new remote comment.476 This is a new remote comment.
476 <BLANKLINE>477 <BLANKLINE>
477478
=== modified file 'lib/lp/bugs/doc/externalbugtracker-debbugs.txt'
--- lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2009-10-08 03:44:20 +0000
+++ lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-01-07 12:59:20 +0000
@@ -361,7 +361,7 @@
361getCommentIds() will return a list of the comment IDs for a given remote361getCommentIds() will return a list of the comment IDs for a given remote
362bug. DebBugs comment IDs are RFC822 message IDs.362bug. DebBugs comment IDs are RFC822 message IDs.
363363
364 >>> comment_ids = external_debbugs.getCommentIds(bug_watch)364 >>> comment_ids = external_debbugs.getCommentIds(bug_watch.remotebug)
365 >>> print comment_ids365 >>> print comment_ids
366 ['<20040309081430.98BF411EE67@tux>']366 ['<20040309081430.98BF411EE67@tux>']
367367
@@ -371,7 +371,7 @@
371 >>> external_debbugs.debbugs_db._data_file = (371 >>> external_debbugs.debbugs_db._data_file = (
372 ... 'debbugs-comment-with-no-date.txt')372 ... 'debbugs-comment-with-no-date.txt')
373373
374 >>> comment_ids = external_debbugs.getCommentIds(bug_watch)374 >>> comment_ids = external_debbugs.getCommentIds(bug_watch.remotebug)
375 >>> print comment_ids375 >>> print comment_ids
376 []376 []
377377
@@ -396,7 +396,7 @@
396396
397However, getCommentIds() will only return the comment ID once.397However, getCommentIds() will only return the comment ID once.
398398
399 >>> comment_ids = external_debbugs.getCommentIds(bug_watch)399 >>> comment_ids = external_debbugs.getCommentIds(bug_watch.remotebug)
400 >>> print comment_ids400 >>> print comment_ids
401 ['<20040309081430.98BF411EE67@tux>']401 ['<20040309081430.98BF411EE67@tux>']
402402
@@ -412,7 +412,7 @@
412412
413 >>> comment_id = comment_ids[0]413 >>> comment_id = comment_ids[0]
414 >>> poster_name, poster_email = external_debbugs.getPosterForComment(414 >>> poster_name, poster_email = external_debbugs.getPosterForComment(
415 ... bug_watch, comment_id)415 ... bug_watch.remotebug, comment_id)
416 >>> print "%s <%s>" % (poster_name, poster_email)416 >>> print "%s <%s>" % (poster_name, poster_email)
417 Teun Vink <teun@tux.office.luna.net>417 Teun Vink <teun@tux.office.luna.net>
418418
@@ -427,7 +427,7 @@
427 ... comment='when importing comments for %s.' % bug_watch.title)427 ... comment='when importing comments for %s.' % bug_watch.title)
428428
429 >>> message = external_debbugs.getMessageForComment(429 >>> message = external_debbugs.getMessageForComment(
430 ... bug_watch, comment_id, poster)430 ... bug_watch.remotebug, comment_id, poster)
431431
432 >>> print message.owner.displayname432 >>> print message.owner.displayname
433 Teun Vink433 Teun Vink
@@ -445,13 +445,13 @@
445 >>> external_debbugs.debbugs_db._data_file = (445 >>> external_debbugs.debbugs_db._data_file = (
446 ... 'debbugs-comment-with-received-date.txt')446 ... 'debbugs-comment-with-received-date.txt')
447447
448 >>> comment_ids = external_debbugs.getCommentIds(bug_watch)448 >>> comment_ids = external_debbugs.getCommentIds(bug_watch.remotebug)
449 >>> print comment_ids449 >>> print comment_ids
450 ['<yetanothermessageid@launchpad>']450 ['<yetanothermessageid@launchpad>']
451451
452 >>> external_debbugs.fetchComments(bug_watch, comment_ids)452 >>> external_debbugs.fetchComments(bug_watch, comment_ids)
453 >>> message = external_debbugs.getMessageForComment(453 >>> message = external_debbugs.getMessageForComment(
454 ... bug_watch, comment_ids[0], poster)454 ... bug_watch.remotebug, comment_ids[0], poster)
455455
456 >>> print message.datecreated456 >>> print message.datecreated
457 2008-05-30 21:18:12+00:00457 2008-05-30 21:18:12+00:00
@@ -477,11 +477,11 @@
477 >>> external_debbugs.debbugs_db._data_file = (477 >>> external_debbugs.debbugs_db._data_file = (
478 ... 'debbugs-comment-with-no-useful-received-date.txt')478 ... 'debbugs-comment-with-no-useful-received-date.txt')
479479
480 >>> comment_ids = external_debbugs.getCommentIds(bug_watch)480 >>> comment_ids = external_debbugs.getCommentIds(bug_watch.remotebug)
481481
482 >>> external_debbugs.fetchComments(bug_watch, comment_ids)482 >>> external_debbugs.fetchComments(bug_watch, comment_ids)
483 >>> message = external_debbugs.getMessageForComment(483 >>> message = external_debbugs.getMessageForComment(
484 ... bug_watch, comment_ids[0], poster)484 ... bug_watch.remotebug, comment_ids[0], poster)
485485
486 >>> print message.datecreated486 >>> print message.datecreated
487 2007-12-14 18:54:30+00:00487 2007-12-14 18:54:30+00:00
488488
=== modified file 'lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt'
--- lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt 2010-01-07 12:59:20 +0000
@@ -362,7 +362,7 @@
362 >>> commit()362 >>> commit()
363 >>> LaunchpadZopelessLayer.switchDbUser(config.checkwatches.dbuser)363 >>> LaunchpadZopelessLayer.switchDbUser(config.checkwatches.dbuser)
364364
365getCommentIds() returns all the comment IDs for a given bug watch.365getCommentIds() returns all the comment IDs for a given remote bug.
366bug_watch is against remote bug 1, which has one comment.366bug_watch is against remote bug 1, which has one comment.
367367
368 >>> test_transport.expireCookie(test_transport.auth_cookie)368 >>> test_transport.expireCookie(test_transport.auth_cookie)
@@ -371,23 +371,23 @@
371 Using XML-RPC to generate token.371 Using XML-RPC to generate token.
372 Successfully validated the token.372 Successfully validated the token.
373373
374 >>> trac.getCommentIds(bug_watch)374 >>> trac.getCommentIds(bug_watch.remotebug)
375 ['1-1']375 ['1-1']
376376
377bug_watch_two is against remote bug 2, which has two comments.377bug_watch_two is against remote bug 2, which has two comments.
378378
379 >>> trac.getCommentIds(bug_watch_two)379 >>> trac.getCommentIds(bug_watch_two.remotebug)
380 ['2-1', '2-2']380 ['2-1', '2-2']
381381
382bug_watch_three is against bug 3, which has no comments.382bug_watch_three is against bug 3, which has no comments.
383383
384 >>> trac.getCommentIds(bug_watch_three)384 >>> trac.getCommentIds(bug_watch_three.remotebug)
385 []385 []
386386
387Trying to call getCommentIds() on a bug that doesn't exist will raise a387Trying to call getCommentIds() on a bug that doesn't exist will raise a
388BugNotFound error.388BugNotFound error.
389389
390 >>> trac.getCommentIds(bug_watch_broken)390 >>> trac.getCommentIds(bug_watch_broken.remotebug)
391 Traceback (most recent call last):391 Traceback (most recent call last):
392 ...392 ...
393 BugNotFound: 123393 BugNotFound: 123
@@ -406,7 +406,7 @@
406parsed.406parsed.
407407
408 >>> test_transport.expireCookie(test_transport.auth_cookie)408 >>> test_transport.expireCookie(test_transport.auth_cookie)
409 >>> trac.fetchComments(bug_watch, ['1-1'])409 >>> trac.fetchComments(bug_watch.remotebug, ['1-1'])
410 Using XML-RPC to generate token.410 Using XML-RPC to generate token.
411 Successfully validated the token.411 Successfully validated the token.
412412
@@ -422,7 +422,7 @@
422getPosterForComment() returns a tuple of (displayname, emailaddress) for422getPosterForComment() returns a tuple of (displayname, emailaddress) for
423the poster of a given comment.423the poster of a given comment.
424424
425 >>> trac.getPosterForComment(bug_watch, '1-1')425 >>> trac.getPosterForComment(bug_watch.remotebug, '1-1')
426 ('Test', 'test@canonical.com')426 ('Test', 'test@canonical.com')
427427
428getPosterForComment() handles situations in which only an email address428getPosterForComment() handles situations in which only an email address
@@ -430,8 +430,8 @@
430displayname. When this is passed to IPersonSet.ensurePerson() a display430displayname. When this is passed to IPersonSet.ensurePerson() a display
431name will be generated for the user from their email address.431name will be generated for the user from their email address.
432432
433 >>> trac.fetchComments(bug_watch_two, ['2-1', '2-2'])433 >>> trac.fetchComments(bug_watch_two.remotebug, ['2-1', '2-2'])
434 >>> trac.getPosterForComment(bug_watch_two, '2-1')434 >>> trac.getPosterForComment(bug_watch_two.remotebug, '2-1')
435 (None, 'test@canonical.com')435 (None, 'test@canonical.com')
436436
437getPosterForComment() will also return displayname, email tuples in437getPosterForComment() will also return displayname, email tuples in
@@ -439,7 +439,7 @@
439However, in these cases it is the email address that will be set to439However, in these cases it is the email address that will be set to
440None.440None.
441441
442 >>> trac.getPosterForComment(bug_watch_two, '2-2')442 >>> trac.getPosterForComment(bug_watch_two.remotebug, '2-2')
443 ('foo.bar', None)443 ('foo.bar', None)
444444
445Finally, getMessageForComment() will return a Message instance for a445Finally, getMessageForComment() will return a Message instance for a
@@ -448,7 +448,8 @@
448448
449 >>> from zope.component import getUtility449 >>> from zope.component import getUtility
450 >>> poster = getUtility(IPersonSet).getByEmail('test@canonical.com')450 >>> poster = getUtility(IPersonSet).getByEmail('test@canonical.com')
451 >>> message_one = trac.getMessageForComment(bug_watch, '1-1', poster)451 >>> message_one = trac.getMessageForComment(
452 ... bug_watch.remotebug, '1-1', poster)
452453
453The Message returned by getMessageForComment() contains the full text of454The Message returned by getMessageForComment() contains the full text of
454the original comment.455the original comment.
455456
=== modified file 'lib/lp/bugs/externalbugtracker/bugzilla.py'
--- lib/lp/bugs/externalbugtracker/bugzilla.py 2009-12-23 10:49:55 +0000
+++ lib/lp/bugs/externalbugtracker/bugzilla.py 2010-01-07 12:59:20 +0000
@@ -626,13 +626,13 @@
626626
627 return bug_products627 return bug_products
628628
629 def getCommentIds(self, bug_watch):629 def getCommentIds(self, remote_bug_id):
630 """See `ISupportsCommentImport`."""630 """See `ISupportsCommentImport`."""
631 actual_bug_id = self._getActualBugId(bug_watch.remotebug)631 actual_bug_id = self._getActualBugId(remote_bug_id)
632632
633 # Check that the bug exists, first.633 # Check that the bug exists, first.
634 if actual_bug_id not in self._bugs:634 if actual_bug_id not in self._bugs:
635 raise BugNotFound(bug_watch.remotebug)635 raise BugNotFound(remote_bug_id)
636636
637 # Get only the remote comment IDs and store them in the637 # Get only the remote comment IDs and store them in the
638 # 'comments' field of the bug.638 # 'comments' field of the bug.
@@ -648,9 +648,9 @@
648648
649 return [str(comment['id']) for comment in bug_comments]649 return [str(comment['id']) for comment in bug_comments]
650650
651 def fetchComments(self, bug_watch, comment_ids):651 def fetchComments(self, remote_bug_id, comment_ids):
652 """See `ISupportsCommentImport`."""652 """See `ISupportsCommentImport`."""
653 actual_bug_id = self._getActualBugId(bug_watch.remotebug)653 actual_bug_id = self._getActualBugId(remote_bug_id)
654654
655 # We need to cast comment_ids to integers, since655 # We need to cast comment_ids to integers, since
656 # BugWatchUpdater.importBugComments() will pass us a list of656 # BugWatchUpdater.importBugComments() will pass us a list of
@@ -664,7 +664,7 @@
664 comments = return_dict['comments']664 comments = return_dict['comments']
665665
666 # As a sanity check, drop any comments that don't belong to the666 # As a sanity check, drop any comments that don't belong to the
667 # bug in bug_watch.667 # bug in remote_bug_id.
668 for comment_id, comment in comments.items():668 for comment_id, comment in comments.items():
669 if int(comment['bug_id']) != actual_bug_id:669 if int(comment['bug_id']) != actual_bug_id:
670 del comments[comment_id]670 del comments[comment_id]
@@ -674,9 +674,9 @@
674 (int(id), comments[id]) for id in comments)674 (int(id), comments[id]) for id in comments)
675 self._bugs[actual_bug_id]['comments'] = comments_with_int_ids675 self._bugs[actual_bug_id]['comments'] = comments_with_int_ids
676676
677 def getPosterForComment(self, bug_watch, comment_id):677 def getPosterForComment(self, remote_bug_id, comment_id):
678 """See `ISupportsCommentImport`."""678 """See `ISupportsCommentImport`."""
679 actual_bug_id = self._getActualBugId(bug_watch.remotebug)679 actual_bug_id = self._getActualBugId(remote_bug_id)
680680
681 # We need to cast comment_id to integers, since681 # We need to cast comment_id to integers, since
682 # BugWatchUpdater.importBugComments() will pass us a string (see682 # BugWatchUpdater.importBugComments() will pass us a string (see
@@ -693,9 +693,9 @@
693693
694 return (display_name, email)694 return (display_name, email)
695695
696 def getMessageForComment(self, bug_watch, comment_id, poster):696 def getMessageForComment(self, remote_bug_id, comment_id, poster):
697 """See `ISupportsCommentImport`."""697 """See `ISupportsCommentImport`."""
698 actual_bug_id = self._getActualBugId(bug_watch.remotebug)698 actual_bug_id = self._getActualBugId(remote_bug_id)
699699
700 # We need to cast comment_id to integers, since700 # We need to cast comment_id to integers, since
701 # BugWatchUpdater.importBugComments() will pass us a string (see701 # BugWatchUpdater.importBugComments() will pass us a string (see
@@ -845,13 +845,13 @@
845 server_utc_time = time_dict['utc_time']845 server_utc_time = time_dict['utc_time']
846 return server_utc_time.replace(tzinfo=pytz.timezone('UTC'))846 return server_utc_time.replace(tzinfo=pytz.timezone('UTC'))
847847
848 def getCommentIds(self, bug_watch):848 def getCommentIds(self, remote_bug_id):
849 """See `ISupportsCommentImport`."""849 """See `ISupportsCommentImport`."""
850 actual_bug_id = self._getActualBugId(bug_watch.remotebug)850 actual_bug_id = self._getActualBugId(remote_bug_id)
851851
852 # Check that the bug exists, first.852 # Check that the bug exists, first.
853 if actual_bug_id not in self._bugs:853 if actual_bug_id not in self._bugs:
854 raise BugNotFound(bug_watch.remotebug)854 raise BugNotFound(remote_bug_id)
855855
856 # Get only the remote comment IDs and store them in the856 # Get only the remote comment IDs and store them in the
857 # 'comments' field of the bug.857 # 'comments' field of the bug.
@@ -871,9 +871,9 @@
871 # bug 248938).871 # bug 248938).
872 return [str(comment['id']) for comment in bug_comments]872 return [str(comment['id']) for comment in bug_comments]
873873
874 def fetchComments(self, bug_watch, comment_ids):874 def fetchComments(self, remote_bug_id, comment_ids):
875 """See `ISupportsCommentImport`."""875 """See `ISupportsCommentImport`."""
876 actual_bug_id = self._getActualBugId(bug_watch.remotebug)876 actual_bug_id = self._getActualBugId(remote_bug_id)
877877
878 # We need to cast comment_ids to integers, since878 # We need to cast comment_ids to integers, since
879 # BugWatchUpdater.importBugComments() will pass us a list of879 # BugWatchUpdater.importBugComments() will pass us a list of
880880
=== modified file 'lib/lp/bugs/externalbugtracker/debbugs.py'
--- lib/lp/bugs/externalbugtracker/debbugs.py 2009-10-06 07:38:29 +0000
+++ lib/lp/bugs/externalbugtracker/debbugs.py 2010-01-07 12:59:20 +0000
@@ -221,9 +221,9 @@
221 debian_bug = self._findBug(remote_bug)221 debian_bug = self._findBug(remote_bug)
222 return debian_bug.subject, debian_bug.description222 return debian_bug.subject, debian_bug.description
223223
224 def getCommentIds(self, bug_watch):224 def getCommentIds(self, remote_bug_id):
225 """See `ISupportsCommentImport`."""225 """See `ISupportsCommentImport`."""
226 debian_bug = self._findBug(bug_watch.remotebug)226 debian_bug = self._findBug(remote_bug_id)
227 self._loadLog(debian_bug)227 self._loadLog(debian_bug)
228228
229 comment_ids = []229 comment_ids = []
@@ -244,16 +244,16 @@
244244
245 return comment_ids245 return comment_ids
246246
247 def fetchComments(self, bug_watch, comment_ids):247 def fetchComments(self, remote_bug_id, comment_ids):
248 """See `ISupportsCommentImport`."""248 """See `ISupportsCommentImport`."""
249 # This method does nothing since DebBugs bugs are stored locally249 # This method does nothing since DebBugs bugs are stored locally
250 # and their comments don't need to be pre-fetched. It exists250 # and their comments don't need to be pre-fetched. It exists
251 # purely to ensure that BugWatchUpdater doesn't choke on it.251 # purely to ensure that BugWatchUpdater doesn't choke on it.
252 pass252 pass
253253
254 def getPosterForComment(self, bug_watch, comment_id):254 def getPosterForComment(self, remote_bug_id, comment_id):
255 """See `ISupportsCommentImport`."""255 """See `ISupportsCommentImport`."""
256 debian_bug = self._findBug(bug_watch.remotebug)256 debian_bug = self._findBug(remote_bug_id)
257 self._loadLog(debian_bug)257 self._loadLog(debian_bug)
258258
259 for comment in debian_bug.comments:259 for comment in debian_bug.comments:
@@ -304,9 +304,9 @@
304304
305 return msg_date305 return msg_date
306306
307 def getMessageForComment(self, bug_watch, comment_id, poster):307 def getMessageForComment(self, remote_bug_id, comment_id, poster):
308 """See `ISupportsCommentImport`."""308 """See `ISupportsCommentImport`."""
309 debian_bug = self._findBug(bug_watch.remotebug)309 debian_bug = self._findBug(remote_bug_id)
310 self._loadLog(debian_bug)310 self._loadLog(debian_bug)
311311
312 for comment in debian_bug.comments:312 for comment in debian_bug.comments:
313313
=== modified file 'lib/lp/bugs/externalbugtracker/trac.py'
--- lib/lp/bugs/externalbugtracker/trac.py 2009-06-25 00:40:31 +0000
+++ lib/lp/bugs/externalbugtracker/trac.py 2010-01-07 12:59:20 +0000
@@ -378,17 +378,17 @@
378378
379 return [bug['id'] for bug in modified_bugs]379 return [bug['id'] for bug in modified_bugs]
380380
381 def getCommentIds(self, bug_watch):381 def getCommentIds(self, remote_bug_id):
382 """See `ISupportsCommentImport`."""382 """See `ISupportsCommentImport`."""
383 try:383 try:
384 bug = self.bugs[int(bug_watch.remotebug)]384 bug = self.bugs[int(remote_bug_id)]
385 except KeyError:385 except KeyError:
386 raise BugNotFound(bug_watch.remotebug)386 raise BugNotFound(remote_bug_id)
387 else:387 else:
388 return [comment_id for comment_id in bug['comments']]388 return [comment_id for comment_id in bug['comments']]
389389
390 @needs_authentication390 @needs_authentication
391 def fetchComments(self, bug_watch, comment_ids):391 def fetchComments(self, remote_bug_id, comment_ids):
392 """See `ISupportsCommentImport`."""392 """See `ISupportsCommentImport`."""
393 bug_comments = {}393 bug_comments = {}
394394
@@ -402,11 +402,11 @@
402 # Finally, we overwrite the bug's comments field with the402 # Finally, we overwrite the bug's comments field with the
403 # bug_comments dict. The nice upshot of this is that we can403 # bug_comments dict. The nice upshot of this is that we can
404 # still loop over the dict and get IDs back.404 # still loop over the dict and get IDs back.
405 self.bugs[int(bug_watch.remotebug)]['comments'] = bug_comments405 self.bugs[int(remote_bug_id)]['comments'] = bug_comments
406406
407 def getPosterForComment(self, bug_watch, comment_id):407 def getPosterForComment(self, remote_bug_id, comment_id):
408 """See `ISupportsCommentImport`."""408 """See `ISupportsCommentImport`."""
409 bug = self.bugs[int(bug_watch.remotebug)]409 bug = self.bugs[int(remote_bug_id)]
410 comment = bug['comments'][comment_id]410 comment = bug['comments'][comment_id]
411411
412 display_name, email = parseaddr(comment['user'])412 display_name, email = parseaddr(comment['user'])
@@ -424,9 +424,9 @@
424 else:424 else:
425 return display_name, email425 return display_name, email
426426
427 def getMessageForComment(self, bug_watch, comment_id, poster):427 def getMessageForComment(self, remote_bug_id, comment_id, poster):
428 """See `ISupportsCommentImport`."""428 """See `ISupportsCommentImport`."""
429 bug = self.bugs[int(bug_watch.remotebug)]429 bug = self.bugs[int(remote_bug_id)]
430 comment = bug['comments'][comment_id]430 comment = bug['comments'][comment_id]
431431
432 comment_datecreated = datetime.fromtimestamp(432 comment_datecreated = datetime.fromtimestamp(
433433
=== modified file 'lib/lp/bugs/interfaces/externalbugtracker.py'
--- lib/lp/bugs/interfaces/externalbugtracker.py 2009-12-18 16:37:11 +0000
+++ lib/lp/bugs/interfaces/externalbugtracker.py 2010-01-07 12:59:20 +0000
@@ -103,36 +103,41 @@
103class ISupportsCommentImport(IExternalBugTracker):103class ISupportsCommentImport(IExternalBugTracker):
104 """An external bug tracker that supports comment imports."""104 """An external bug tracker that supports comment imports."""
105105
106 def fetchComments(bug_watch, comment_ids):106 def fetchComments(remote_bug_id, comment_ids):
107 """Load a given set of remote comments, ready for parsing.107 """Load a given set of remote comments, ready for parsing.
108108
109 :param bug_watch: The bug watch for which to fetch the comments.109 :param remote_bug_id: The ID of the remote bug from which to
110 fetch comments.
111 :type remote_bug_id: See `IBugWatch.remotebug`.
110 :param comment_ids: A list of the IDs of the comments to load.112 :param comment_ids: A list of the IDs of the comments to load.
111 """113 """
112114
113 def getCommentIds(bug_watch):115 def getCommentIds(remote_bug_id):
114 """Return all the comment IDs for a given remote bug.116 """Return all the comment IDs for a given remote bug.
115117
116 :param bug_watch: An `IBugWatch` pointing to the remote bug from118 :param remote_bug_id: The ID of the remote bug from which
117 which comments should be imported.119 comments should be imported.
120 :type remote_bug_id: See `IBugWatch.remotebug`.
118 :return: A list of strings, each of which is the ID of one121 :return: A list of strings, each of which is the ID of one
119 comment on the remote bug.122 comment on the remote bug.
120 """123 """
121124
122 def getPosterForComment(bug_watch, comment_id):125 def getPosterForComment(remote_bug_id, comment_id):
123 """Return a tuple of (name, emailaddress) for a comment's poster.126 """Return a tuple of (name, emailaddress) for a comment's poster.
124127
125 :param bug_watch: An `IBugWatch` pointing to the remote bug from128 :param remote_bug_id: The ID of the remote bug from which
126 which comments should be imported.129 comments have been imported.
130 :type remote_bug_id: See `IBugWatch.remotebug`.
127 :param comment_id: A string representing the remote comment ID131 :param comment_id: A string representing the remote comment ID
128 from which the poster's details should be extracted.132 from which the poster's details should be extracted.
129 """133 """
130134
131 def getMessageForComment(bug_watch, comment_id, poster):135 def getMessageForComment(remote_bug_id, comment_id, poster):
132 """Return an `IMessage` instance for a comment.136 """Return an `IMessage` instance for a comment.
133137
134 :param bug_watch: An `IBugWatch` pointing to the remote bug from138 :param remote_bug_id: The ID of the remote bug from which
135 which comments should be imported.139 comments have been imported.
140 :type remote_bug_id: See `IBugWatch.remotebug`.
136 :param comment_id: A string representing the remote comment ID141 :param comment_id: A string representing the remote comment ID
137 from which the returned `IMessage` should be created.142 from which the returned `IMessage` should be created.
138 """143 """
139144
=== modified file 'lib/lp/bugs/scripts/checkwatches.py'
--- lib/lp/bugs/scripts/checkwatches.py 2010-01-05 16:09:00 +0000
+++ lib/lp/bugs/scripts/checkwatches.py 2010-01-07 12:59:20 +0000
@@ -951,19 +951,21 @@
951 """951 """
952 # Construct a list of the comment IDs we want to import; i.e.952 # Construct a list of the comment IDs we want to import; i.e.
953 # those which we haven't already imported.953 # those which we haven't already imported.
954 all_comment_ids = external_bugtracker.getCommentIds(bug_watch)954 all_comment_ids = external_bugtracker.getCommentIds(
955 bug_watch.remotebug)
955 comment_ids_to_import = [956 comment_ids_to_import = [
956 comment_id for comment_id in all_comment_ids957 comment_id for comment_id in all_comment_ids
957 if not bug_watch.hasComment(comment_id)]958 if not bug_watch.hasComment(comment_id)]
958959
959 external_bugtracker.fetchComments(bug_watch, comment_ids_to_import)960 external_bugtracker.fetchComments(
961 bug_watch.remotebug, comment_ids_to_import)
960962
961 previous_imported_comments = bug_watch.getImportedBugMessages()963 previous_imported_comments = bug_watch.getImportedBugMessages()
962 is_initial_import = previous_imported_comments.count() == 0964 is_initial_import = previous_imported_comments.count() == 0
963 imported_comments = []965 imported_comments = []
964 for comment_id in comment_ids_to_import:966 for comment_id in comment_ids_to_import:
965 displayname, email = external_bugtracker.getPosterForComment(967 displayname, email = external_bugtracker.getPosterForComment(
966 bug_watch, comment_id)968 bug_watch.remotebug, comment_id)
967969
968 if displayname is None and email is None:970 if displayname is None and email is None:
969 # If we don't have a displayname or an email address971 # If we don't have a displayname or an email address
@@ -981,7 +983,7 @@
981 "when importing comments for %s." % bug_watch.title)983 "when importing comments for %s." % bug_watch.title)
982984
983 comment_message = external_bugtracker.getMessageForComment(985 comment_message = external_bugtracker.getMessageForComment(
984 bug_watch, comment_id, poster)986 bug_watch.remotebug, comment_id, poster)
985987
986 bug_message = bug_watch.addComment(comment_id, comment_message)988 bug_message = bug_watch.addComment(comment_id, comment_message)
987 imported_comments.append(bug_message)989 imported_comments.append(bug_message)