443
442
def getSubscribedAddresses(self):
444
443
"""See `IMailingList`."""
445
store = Store.of(self)
446
# In order to handle the case where the preferred email address is
447
# used (i.e. where MailingListSubscription.email_address is NULL), we
448
# need to UNION, those using a specific address and those using the
452
LeftJoin(Account, Account.id == EmailAddress.accountID),
453
LeftJoin(MailingListSubscription,
454
MailingListSubscription.personID
455
== EmailAddress.personID),
456
# pylint: disable-msg=C0301
459
MailingList.id == MailingListSubscription.mailing_listID),
460
LeftJoin(TeamParticipation,
461
TeamParticipation.personID
462
== MailingListSubscription.personID),
464
preferred = store.using(*tables).find(
466
And(MailingListSubscription.mailing_list == self,
467
TeamParticipation.team == self.team,
468
MailingList.status != MailingListStatus.INACTIVE,
469
MailingListSubscription.email_addressID == None,
470
EmailAddress.status == EmailAddressStatus.PREFERRED,
471
Account.status == AccountStatus.ACTIVE))
474
LeftJoin(Account, Account.id == EmailAddress.accountID),
475
LeftJoin(MailingListSubscription,
476
MailingListSubscription.email_addressID
478
# pylint: disable-msg=C0301
481
MailingList.id == MailingListSubscription.mailing_listID),
482
LeftJoin(TeamParticipation,
483
TeamParticipation.personID
484
== MailingListSubscription.personID),
486
explicit = store.using(*tables).find(
488
And(MailingListSubscription.mailing_list == self,
489
TeamParticipation.team == self.team,
490
MailingList.status != MailingListStatus.INACTIVE,
491
Account.status == AccountStatus.ACTIVE))
492
# Union the two queries together to give us the complete list of email
493
# addresses allowed to post. Note that while we're retrieving both
494
# the EmailAddress and Person records, this method is defined as only
495
# returning EmailAddresses. The reason why we include the Person in
496
# the query is because the consumer of this method will access
497
# email_address.person.displayname, so the prejoin to Person is
498
# critical to acceptable performance. Indeed, without the prejoin, we
499
# were getting tons of timeout OOPSes. See bug 259440.
500
for email_address in preferred.union(explicit):
445
address for (name, address) in
446
getUtility(IMailingListSet).getSubscribedAddresses(
447
[self.team.name]).get(self.team.name, [])]
503
449
def getSenderAddresses(self):
504
450
"""See `IMailingList`."""
505
store = Store.of(self)
506
# First, we need to find all the members of the team this mailing list
507
# is associated with. Find all of their validated and preferred email
508
# addresses of those team members. Every one of those email addresses
509
# are allowed to post to the mailing list.
512
Join(Account, Account.id == Person.accountID),
513
Join(EmailAddress, EmailAddress.personID == Person.id),
514
Join(TeamParticipation, TeamParticipation.personID == Person.id),
515
Join(MailingList, MailingList.teamID == TeamParticipation.teamID),
517
team_members = store.using(*tables).find(
519
And(TeamParticipation.team == self.team,
520
MailingList.status != MailingListStatus.INACTIVE,
521
Person.teamowner == None,
522
EmailAddress.status.is_in(EMAIL_ADDRESS_STATUSES),
523
Account.status == AccountStatus.ACTIVE,
525
# Second, find all of the email addresses for all of the people who
526
# have been explicitly approved for posting to this mailing list.
527
# This occurs as part of first post moderation, but since they've
528
# already been approved for this list, we don't need to wait for three
532
Join(Account, Account.id == Person.accountID),
533
Join(EmailAddress, EmailAddress.personID == Person.id),
534
Join(MessageApproval, MessageApproval.posted_byID == Person.id),
536
approved_posters = store.using(*tables).find(
538
And(MessageApproval.mailing_list == self,
539
MessageApproval.status.is_in(MESSAGE_APPROVAL_STATUSES),
540
EmailAddress.status.is_in(EMAIL_ADDRESS_STATUSES),
541
Account.status == AccountStatus.ACTIVE,
543
# Union the two queries together to give us the complete list of email
544
# addresses allowed to post. Note that while we're retrieving both
545
# the EmailAddress and Person records, this method is defined as only
546
# returning EmailAddresses. The reason why we include the Person in
547
# the query is because the consumer of this method will access
548
# email_address.person.displayname, so the prejoin to Person is
549
# critical to acceptable performance. Indeed, without the prejoin, we
550
# were getting tons of timeout OOPSes. See bug 259440.
551
return team_members.union(approved_posters)
452
address for (name, address) in
453
getUtility(IMailingListSet).getSenderAddresses(
454
[self.team.name]).get(self.team.name, [])]
553
456
def holdMessage(self, message):
554
457
"""See `IMailingList`."""
686
589
Team = ClassAlias(Person)
689
LeftJoin(Account, Account.id == EmailAddress.accountID),
690
LeftJoin(MailingListSubscription,
691
MailingListSubscription.personID
692
== EmailAddress.personID),
693
# pylint: disable-msg=C0301
592
Join(Person, Person.id == EmailAddress.personID),
593
Join(Account, Account.id == Person.accountID),
594
Join(TeamParticipation, TeamParticipation.personID == Person.id),
596
MailingListSubscription,
597
MailingListSubscription.personID == Person.id),
696
600
MailingList.id == MailingListSubscription.mailing_listID),
697
LeftJoin(TeamParticipation,
698
TeamParticipation.personID
699
== MailingListSubscription.personID),
701
Person.id == TeamParticipation.personID),
703
Team.id == MailingList.teamID),
601
Join(Team, Team.id == MailingList.teamID),
705
603
team_ids, list_ids = self._getTeamIdsAndMailingListIds(team_names)
706
604
# Find all the people who are subscribed with their preferred address.
720
618
'Unexpected team name in results: %s' % team_name)
721
619
value = (display_name, email)
722
620
by_team[team_name].add(value)
725
LeftJoin(Account, Account.id == EmailAddress.accountID),
726
LeftJoin(MailingListSubscription,
727
MailingListSubscription.email_addressID
729
# pylint: disable-msg=C0301
732
MailingList.id == MailingListSubscription.mailing_listID),
733
LeftJoin(TeamParticipation,
734
TeamParticipation.personID
735
== MailingListSubscription.personID),
737
Person.id == TeamParticipation.personID),
739
Team.id == MailingList.teamID),
741
621
explicit = store.using(*tables).find(
742
622
(EmailAddress.email, Person.displayname, Team.name),
743
623
And(MailingListSubscription.mailing_listID.is_in(list_ids),
744
624
TeamParticipation.teamID.is_in(team_ids),
745
625
MailingList.status != MailingListStatus.INACTIVE,
626
EmailAddress.id == MailingListSubscription.email_addressID,
746
627
Account.status == AccountStatus.ACTIVE))
747
628
for email, display_name, team_name in explicit:
748
629
assert team_name in team_names, (