~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/model/bug.py

[r=gmb][bug=772609] The mute link will now appear for members of
        teams that are structurally subscribed to a bug or its duplicates

Show diffs side-by-side

added added

removed removed

Lines of Context:
951
951
        See the comment in getDirectSubscribers for a description of the
952
952
        recipients argument.
953
953
        """
 
954
        if self.private:
 
955
            # We short-circuit for private bugs, since actually
 
956
            # returning something non-empty here causes things to break
 
957
            # in fun and interesting ways (see bug 780248).
 
958
            return []
 
959
 
954
960
        if level is None:
955
961
            level = BugNotificationLevel.NOTHING
956
962
        info = self.getSubscriptionInfo(level)
957
963
 
958
964
        if recipients is not None:
959
 
            # Pre-load duplicate bugs.
 
965
            # Pre-load duplicates
960
966
            list(self.duplicates)
961
967
            for subscription in info.duplicate_only_subscriptions:
962
968
                recipients.addDupeSubscriber(
963
969
                    subscription.person, subscription.bug)
 
970
            for subscription in info.structural_subscriptions_from_duplicates:
 
971
                recipients.addDupeSubscriber(
 
972
                    subscription.subscriber)
964
973
 
965
 
        return info.duplicate_only_subscriptions.subscribers.sorted
 
974
        unified_subscribers = (
 
975
            info.duplicate_only_subscriptions.subscribers.union(
 
976
                info.structural_subscriptions_from_duplicates.subscribers))
 
977
        return unified_subscribers.sorted
966
978
 
967
979
    def getSubscribersForPerson(self, person):
968
980
        """See `IBug."""
1027
1039
                                     include_master_dupe_subscribers=False):
1028
1040
        """See `IBug`."""
1029
1041
        recipients = BugNotificationRecipients(duplicateof=duplicateof)
 
1042
        # Call getDirectSubscribers to update the recipients list with direct
 
1043
        # subscribers.  The results of the method call are not used.
1030
1044
        self.getDirectSubscribers(recipients, level=level)
1031
1045
        if self.private:
1032
1046
            assert self.getIndirectSubscribers() == [], (
1033
1047
                "Indirect subscribers found on private bug. "
1034
1048
                "A private bug should never have implicit subscribers!")
1035
1049
        else:
 
1050
            # Call getIndirectSubscribers to update the recipients list with direct
 
1051
            # subscribers.  The results of the method call are not used.
1036
1052
            self.getIndirectSubscribers(recipients, level=level)
1037
1053
            if include_master_dupe_subscribers and self.duplicateof:
1038
1054
                # This bug is a public duplicate of another bug, so include
1899
1915
 
1900
1916
    def personIsAlsoNotifiedSubscriber(self, person):
1901
1917
        """See `IBug`."""
 
1918
        # This is here to avoid circular imports.
 
1919
        from lp.bugs.mail.bugnotificationrecipients import (
 
1920
            BugNotificationRecipients,
 
1921
            )
 
1922
 
 
1923
        def check_person_in_team(person, list_of_people):
 
1924
            """Is the person in one of the teams?
 
1925
 
 
1926
            Given a person and a list of people/teams, see if the person
 
1927
            belongs to one of the teams.
 
1928
            """
 
1929
            for subscriber in list_of_people:
 
1930
                if subscriber.is_team and person.inTeam(subscriber):
 
1931
                    return True
 
1932
            return False
 
1933
 
1902
1934
        # We have to use getAlsoNotifiedSubscribers() here and iterate
1903
1935
        # over what it returns because "also notified subscribers" is
1904
1936
        # actually a composite of bug contacts, structural subscribers
1909
1941
            return True
1910
1942
        # Otherwise check to see if the person is a member of any of the
1911
1943
        # subscribed teams.
1912
 
        for subscriber in also_notified_subscribers:
1913
 
            if subscriber.is_team and person.inTeam(subscriber):
1914
 
                return True
 
1944
        if check_person_in_team(person, also_notified_subscribers):
 
1945
            return True
 
1946
 
 
1947
        direct_subscribers = self.getDirectSubscribers()
 
1948
        if check_person_in_team(person, direct_subscribers):
 
1949
            return True
 
1950
        duplicate_subscribers = self.getSubscribersFromDuplicates(
 
1951
            recipients=BugNotificationRecipients())
 
1952
        if check_person_in_team(person, duplicate_subscribers):
 
1953
            return True
1915
1954
        return False
1916
1955
 
1917
1956
    def personIsSubscribedToDuplicate(self, person):
2271
2310
        return get_structural_subscriptions_for_bug(self.bug)
2272
2311
 
2273
2312
    @cachedproperty
 
2313
    @freeze(StructuralSubscriptionSet)
 
2314
    def structural_subscriptions_from_duplicates(self):
 
2315
        """Structural subscriptions from the bug's duplicates."""
 
2316
        self.duplicate_subscriptions.subscribers # Pre-load subscribers.
 
2317
        higher_precedence = (
 
2318
            self.direct_subscriptions.subscribers.union(
 
2319
                self.also_notified_subscribers))
 
2320
        all_duplicate_structural_subscriptions = list()
 
2321
        for duplicate in self.bug.duplicates:
 
2322
            duplicate_struct_subs = get_structural_subscriptions_for_bug(
 
2323
                duplicate)
 
2324
            all_duplicate_structural_subscriptions += duplicate_struct_subs
 
2325
        return (
 
2326
            subscription for subscription in
 
2327
                all_duplicate_structural_subscriptions
 
2328
                if subscription.subscriber not in higher_precedence)
 
2329
 
 
2330
    @cachedproperty
2274
2331
    @freeze(BugSubscriberSet)
2275
2332
    def all_assignees(self):
2276
2333
        """Assignees of the bug's tasks."""