Merge lp:~lifeless/launchpad/registry into lp:launchpad

Proposed by Robert Collins
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 11573
Proposed branch: lp:~lifeless/launchpad/registry
Merge into: lp:launchpad
Diff against target: 107 lines (+36/-13)
3 files modified
lib/lp/registry/browser/team.py (+17/-4)
lib/lp/registry/interfaces/mailinglist.py (+3/-1)
lib/lp/registry/model/mailinglist.py (+16/-8)
To merge this branch: bzr merge lp:~lifeless/launchpad/registry
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Launchpad code reviewers Pending
Review via email: mp+35774@code.launchpad.net

Commit message

Fix mailing list moderation UFD's.

Description of the change

Fix unexpected form data in mailing list moderation.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

Note, this is tested by the tests for moderation; specific tests could be added but I don't think they'll add any coverage or value. (migrating the higher level tests down would add value, but only if we /move/ not /add/.

Revision history for this message
Curtis Hovey (sinzui) wrote :

This looks good to land.

review: Approve (code)
Revision history for this message
Brad Crittenden (bac) wrote :

Robert,

Per our shiny new multi-line import rule, could you fix line 9 please?

:)

--Brad

Revision history for this message
Robert Collins (lifeless) wrote :

The thing is Brad, that line 9 is actually ok in bzr, which is what I was referencing ;)

I will change it anyhow, but I think we can easily spend a lot of cycles on trivial stuff.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/team.py'
2--- lib/lp/registry/browser/team.py 2010-09-14 00:21:04 +0000
3+++ lib/lp/registry/browser/team.py 2010-09-17 18:36:33 +0000
4@@ -25,7 +25,10 @@
5
6 from datetime import datetime
7 import math
8-from urllib import quote
9+from urllib import (
10+ quote,
11+ unquote,
12+ )
13
14 import pytz
15 from zope.app.form.browser import TextAreaWidget
16@@ -838,9 +841,19 @@
17 # won't be in data. Instead, get it out of the request.
18 reviewable = self.hold_count
19 disposed_count = 0
20- for message in self.held_messages.currentBatch():
21- action_name = self.request.form_ng.getOne(
22- 'field.' + quote(message.message_id))
23+ actions = {}
24+ form = self.request.form_ng
25+ for field_name in form:
26+ if (field_name.startswith('field.') and
27+ field_name.endswith('')):
28+ # A moderated message.
29+ quoted_id = field_name[len('field.'):]
30+ message_id = unquote(quoted_id)
31+ actions[message_id] = form.getOne(field_name)
32+ messages = self.mailing_list.getReviewableMessages(
33+ message_id_filter=actions)
34+ for message in messages:
35+ action_name = actions[message.message_id]
36 # This essentially acts like a switch statement or if/elifs. It
37 # looks the action up in a map of allowed actions, watching out
38 # for bogus input.
39
40=== modified file 'lib/lp/registry/interfaces/mailinglist.py'
41--- lib/lp/registry/interfaces/mailinglist.py 2010-08-20 20:31:18 +0000
42+++ lib/lp/registry/interfaces/mailinglist.py 2010-09-17 18:36:33 +0000
43@@ -431,9 +431,11 @@
44 :return: The IMessageApproval representing the held message.
45 """
46
47- def getReviewableMessages():
48+ def getReviewableMessages(message_id_filter=None):
49 """Return the set of all held messages for this list requiring review.
50
51+ :param message_id_filter: If supplied only messages with message ids in
52+ the filter are returned.
53 :return: A sequence of `IMessageApproval`s for this mailing list,
54 where the status is `PostedMessageStatus.NEW`. The returned set
55 is ordered first by the date the message was posted, then by
56
57=== modified file 'lib/lp/registry/model/mailinglist.py'
58--- lib/lp/registry/model/mailinglist.py 2010-09-03 03:12:39 +0000
59+++ lib/lp/registry/model/mailinglist.py 2010-09-17 18:36:33 +0000
60@@ -21,6 +21,7 @@
61 make_header,
62 )
63 from itertools import repeat
64+import operator
65 from socket import getfqdn
66 from string import Template
67
68@@ -63,8 +64,10 @@
69 sqlvalues,
70 )
71 from canonical.launchpad import _
72+from canonical.launchpad.components.decoratedresultset import DecoratedResultSet
73 from canonical.launchpad.database.account import Account
74 from canonical.launchpad.database.emailaddress import EmailAddress
75+from canonical.launchpad.database.message import Message
76 from canonical.launchpad.interfaces.account import AccountStatus
77 from canonical.launchpad.interfaces.emailaddress import (
78 EmailAddressStatus,
79@@ -557,15 +560,20 @@
80 notify(ObjectCreatedEvent(held_message))
81 return held_message
82
83- def getReviewableMessages(self):
84+ def getReviewableMessages(self, message_id_filter=None):
85 """See `IMailingList`."""
86- return MessageApproval.select("""
87- MessageApproval.mailing_list = %s AND
88- MessageApproval.status = %s AND
89- MessageApproval.message = Message.id
90- """ % sqlvalues(self, PostedMessageStatus.NEW),
91- clauseTables=['Message'],
92- orderBy=['posted_date', 'Message.rfc822msgid'])
93+ store = Store.of(self)
94+ clauses = [
95+ MessageApproval.mailing_listID==self.id,
96+ MessageApproval.status==PostedMessageStatus.NEW,
97+ MessageApproval.messageID==Message.id,
98+ ]
99+ if message_id_filter is not None:
100+ clauses.append(Message.rfc822msgid.is_in(message_id_filter))
101+ results = store.find((MessageApproval, Message),
102+ *clauses)
103+ results.order_by(MessageApproval.posted_date, Message.rfc822msgid)
104+ return DecoratedResultSet(results, operator.itemgetter(0))
105
106 def purge(self):
107 """See `IMailingList`."""