コード例 #1
0
def _calculate_bugtask_condition(query_arguments):
    """Return a condition matching importance and status for the bugtasks.

    :param query_arguments: an iterable of (bugtask, target) pairs, as
                            returned by get_structural_subscription_targets.
    """
    # This handles importance and status, which are per bugtask.
    # The `query_arguments` collection has pairs of bugtask, target,
    # where one bugtask may repeat, to be paired with multiple targets.
    # We know it will not be empty, because we already escaped early in
    # _get_structural_subscription_filter_id_query with "if not
    # query_arguments: return None".
    # This approach groups the queries around shared statuses and importances
    # in order to address concerns like those raised in bug 731009.
    # We begin be establishing that grouping. The `statuses` dict maps
    # bugtask statuses to a mapping of bugtask importances to a list of
    # targets. More concisely:
    #   statuses map -> importances map -> list of targets
    statuses = defaultdict(lambda: defaultdict(list))
    for bugtask, target in query_arguments:
        statuses[bugtask.status][bugtask.importance].append(target)
    # Now that they are grouped, we will build our query.  If we only have
    # a single bugtask target, the goal is to produce a query something
    # like this:
    #   And(
    #     Or(filter's importance = bugtask's importance,
    #        filter's importance is null),
    #     And(
    #       Or(filter's status = bugtask's status,
    #          filter's status is null),
    #       subscription matches target))
    # If there are multiple bugtask targets, but the associated bugtasks
    # share the same importance and status, then "subscription matches
    # target" will become something like this:
    #       Or(subscription matches target 1,
    #          subscription matches target 2,
    #          ...)
    # Matching targets is done using the useful
    # IStructuralSubscriptionTargetHelper adapter, which has a "join"
    # attribute on it that tells us how to distinguish that target.
    outer_or_conditions = []
    for status, importances in statuses.items():
        inner_or_conditions = []
        for importance, targets in importances.items():
            target_query = Or(
                *[IStructuralSubscriptionTargetHelper(target).join
                  for target in targets])
            importance_query = Or(
                BugSubscriptionFilterImportance.importance == importance,
                BugSubscriptionFilterImportance.importance == None)
            inner_or_conditions.append(And(target_query, importance_query))
        status_query = Or(
            BugSubscriptionFilterStatus.status == status,
            BugSubscriptionFilterStatus.status == None)
        outer_or_conditions.append(
            And(status_query, Or(*inner_or_conditions)))
    return Or(*outer_or_conditions)
コード例 #2
0
 def test_product(self):
     target = self.factory.makeProduct(owner=self.person)
     helper = IStructuralSubscriptionTargetHelper(target)
     self.assertThat(helper, Provides(IStructuralSubscriptionTargetHelper))
     self.assertEqual("project", helper.target_type_display)
     self.assertEqual(target, helper.target)
     self.assertEqual(None, helper.target_parent)
     self.assertEqual(target, helper.pillar)
     self.assertEqual({"product": target}, helper.target_arguments)
     self.assertEqual(u"StructuralSubscription.product = ?",
                      compile_storm(helper.join))
コード例 #3
0
 def test_distribution_series(self):
     target = self.factory.makeDistroSeries()
     helper = IStructuralSubscriptionTargetHelper(target)
     self.assertThat(helper, Provides(IStructuralSubscriptionTargetHelper))
     self.assertEqual("distribution series", helper.target_type_display)
     self.assertEqual(target, helper.target)
     self.assertEqual(target.distribution, helper.target_parent)
     self.assertEqual({"distroseries": target}, helper.target_arguments)
     self.assertEqual(target.distribution, helper.pillar)
     self.assertEqual(u"StructuralSubscription.distroseries = ?",
                      compile_storm(helper.join))
コード例 #4
0
def get_structural_subscriptions_for_target(target, person):
    """Find the personal and team structural subscriptions to the target.
    """
    # This is here because of a circular import.
    from lp.registry.model.person import Person
    return IStore(StructuralSubscription).find(
        StructuralSubscription,
        IStructuralSubscriptionTargetHelper(target).join,
        StructuralSubscription.subscriber == Person.id,
        TeamParticipation.personID == person.id,
        TeamParticipation.teamID == Person.id)
コード例 #5
0
    def __helper(self):
        """A `IStructuralSubscriptionTargetHelper` for this object.

        Eventually this helper object could become *the* way to work with
        structural subscriptions. For now it just provides a few bits that
        vary with the context.

        It is cached in a pseudo-private variable because this is a mixin
        class.
        """
        return IStructuralSubscriptionTargetHelper(self)
コード例 #6
0
 def test_milestone(self):
     target = self.factory.makeMilestone()
     helper = IStructuralSubscriptionTargetHelper(target)
     self.assertThat(helper, Provides(IStructuralSubscriptionTargetHelper))
     self.assertEqual("milestone", helper.target_type_display)
     self.assertEqual(target, helper.target)
     self.assertEqual(target.target, helper.target_parent)
     self.assertThat(helper.target_parent,
                     Provides(IStructuralSubscriptionTarget))
     self.assertEqual(target.target, helper.pillar)
     self.assertEqual({"milestone": target}, helper.target_arguments)
     self.assertEqual(u"StructuralSubscription.milestone = ?",
                      compile_storm(helper.join))
コード例 #7
0
    def _enabled(self):
        """Should the link be enabled?

        True if the target uses Launchpad for bugs and the user can alter the
        bug subscriptions.
        """
        sst = self._getSST()
        # ProjectGroup milestones aren't really structural subscription
        # targets as they're not real milestones, so you can't subscribe to
        # them.
        if IProjectGroupMilestone.providedBy(sst):
            return False
        pillar = IStructuralSubscriptionTargetHelper(sst).pillar
        return (pillar.bug_tracking_usage == ServiceUsage.LAUNCHPAD
                and sst.userCanAlterBugSubscription(self.user, self.user))
コード例 #8
0
def _get_structural_subscriptions(find, targets, *conditions):
    """Find the structural subscriptions for the given targets.

    :param find: what to find (typically StructuralSubscription or
                 StructuralSubscription.id).
    :param targets: an iterable of (bugtask, target) pairs, as returned by
                    get_structural_subscription_targets.
    :param conditions: additional conditions to filter the results.
    """
    targets = set(target for bugtask, target in targets)
    target_descriptions = [
        IStructuralSubscriptionTargetHelper(bugtarget).join
        for bugtarget in targets]
    return IStore(StructuralSubscription).find(
        find, Or(*target_descriptions), *conditions)
コード例 #9
0
 def test_distribution(self):
     target = self.factory.makeDistribution(owner=self.person)
     helper = IStructuralSubscriptionTargetHelper(target)
     self.assertThat(helper, Provides(IStructuralSubscriptionTargetHelper))
     self.assertEqual(target, helper.target)
     self.assertEqual("distribution", helper.target_type_display)
     self.assertEqual(None, helper.target_parent)
     self.assertEqual(target, helper.pillar)
     self.assertEqual({
         "distribution": target,
         "sourcepackagename": None
     }, helper.target_arguments)
     self.assertEqual(
         u"StructuralSubscription.distribution = ? AND "
         u"StructuralSubscription.sourcepackagename IS NULL",
         compile_storm(helper.join))
コード例 #10
0
 def test_distribution_source_package(self):
     target = self.factory.makeDistributionSourcePackage()
     helper = IStructuralSubscriptionTargetHelper(target)
     self.assertThat(helper, Provides(IStructuralSubscriptionTargetHelper))
     self.assertEqual("package", helper.target_type_display)
     self.assertEqual(target, helper.target)
     self.assertEqual(target.distribution, helper.target_parent)
     self.assertThat(helper.target_parent,
                     Provides(IStructuralSubscriptionTarget))
     self.assertEqual(target.distribution, helper.pillar)
     self.assertEqual(
         {
             "distribution": target.distribution,
             "sourcepackagename": target.sourcepackagename
         }, helper.target_arguments)
     self.assertEqual(
         u"StructuralSubscription.distribution = ? AND "
         u"StructuralSubscription.sourcepackagename = ?",
         compile_storm(helper.join))