Exemplo n.º 1
0
    def initialize(self):
        super(ChooseProductStep, self).initialize()
        if (self.widgets['product'].hasInput() or
            not IDistributionSourcePackage.providedBy(self.context.target)):
            return

        self.maybeAddNotificationOrTeleport()
Exemplo n.º 2
0
    def show_details_portlet(self):
        """Show details portlet?

        Returns `True` if the portlet details is available
        and should be shown for the context.
        """
        return IDistributionSourcePackage.providedBy(self.context)
Exemplo n.º 3
0
    def __init__(self, context, request):
        super(PillarInvolvementView, self).__init__(context, request)
        self.official_malone = False
        self.answers_usage = ServiceUsage.UNKNOWN
        self.blueprints_usage = ServiceUsage.UNKNOWN
        self.translations_usage = ServiceUsage.UNKNOWN
        self.codehosting_usage = ServiceUsage.UNKNOWN
        pillar = nearest(self.context, IPillar)

        self._set_official_launchpad(pillar)
        if IDistroSeries.providedBy(self.context):
            distribution = self.context.distribution
            self.codehosting_usage = distribution.codehosting_usage
            self.answers_usage = ServiceUsage.NOT_APPLICABLE
        elif IDistributionSourcePackage.providedBy(self.context):
            self.blueprints_usage = ServiceUsage.UNKNOWN
            self.translations_usage = ServiceUsage.UNKNOWN
        elif IProjectGroup.providedBy(pillar):
            # XXX: 2010-10-07 EdwinGrubbs bug=656292
            # Fix _set_official_launchpad().

            # Project groups do not support submit code, override the
            # default.
            self.codehosting_usage = ServiceUsage.NOT_APPLICABLE
        else:
            # The context is used by all apps.
            pass
Exemplo n.º 4
0
 def getInputValue(self):
     """See zope.formlib.interfaces.IInputWidget."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == 'product':
         try:
             return self.product_widget.getInputValue()
         except MissingInputError:
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError('Please enter a project name'))
             raise self._error
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.product" %
                                                        self.name)
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in"
                     " Launchpad" % entered_name))
             raise self._error
     elif form_value == 'package':
         try:
             distribution = self.distribution_widget.getInputValue()
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.distribution" %
                                                        self.name)
             self._error = WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no distribution named '%s' registered in"
                     " Launchpad" % entered_name))
             raise self._error
         if self.package_widget.hasInput():
             try:
                 package_name = self.package_widget.getInputValue()
                 if package_name is None:
                     return distribution
                 if IDistributionSourcePackage.providedBy(package_name):
                     dsp = package_name
                 else:
                     source_name = (
                         distribution.guessPublishedSourcePackageName(
                             package_name.name))
                     dsp = distribution.getSourcePackage(source_name)
             except (ConversionError, NotFoundError):
                 entered_name = self.request.form_ng.getOne('%s.package' %
                                                            self.name)
                 self._error = WidgetInputError(
                     self.name, self.label,
                     LaunchpadValidationError(
                         "There is no package named '%s' published in %s." %
                         (entered_name, distribution.displayname)))
                 raise self._error
             return dsp
         else:
             return distribution
     else:
         raise UnexpectedFormData("No valid option was selected.")
Exemplo n.º 5
0
 def render(self):
     for bugtask in IBug(self.context).bugtasks:
         if (IDistributionSourcePackage.providedBy(bugtask.target) and
             (not self.widgets['sourcepackagename'].hasInput())):
             self.widgets['sourcepackagename'].setRenderedValue(
                 bugtask.sourcepackagename)
             break
     return super(DistroBugTaskCreationStep, self).render()
Exemplo n.º 6
0
 def __eq__(self, other):
     """See `IGitNamespace`."""
     # We may have different DSP objects that are functionally the same.
     self_dsp = self.distro_source_package
     other_dsp = IDistributionSourcePackage(other.target)
     return (
         self_dsp.distribution == other_dsp.distribution and
         self_dsp.sourcepackagename == other_dsp.sourcepackagename)
 def test_admin_can_edit(self):
     admin = getUtility(IPersonSet).getByEmail('*****@*****.**')
     login_person(admin)
     view = create_initialized_view(self.target, '+edit')
     if IDistributionSourcePackage.providedBy(self.target):
         self.assertTrue(check_permission('launchpad.BugSupervisor', view))
     else:
         self.assertTrue(check_permission('launchpad.Edit', view))
Exemplo n.º 8
0
 def _validateTargetAndGetTemplates(self, data):
     """Return a POTemplateSubset corresponding to the chosen target."""
     sourcepackagename = data.get('sourcepackagename',
                                  self.context.sourcepackagename)
     if IDistributionSourcePackage.providedBy(sourcepackagename):
         sourcepackagename = sourcepackagename.sourcepackagename
     return getUtility(IPOTemplateSet).getSubset(
         distroseries=self.context.distroseries,
         sourcepackagename=sourcepackagename,
         productseries=self.context.productseries)
 def userIsDriver(self):
     """Has the current user driver permissions?"""
     # We only want to look at this if the target is a
     # distribution source package, in order to maintain
     # compatibility with the obsolete bug contacts feature.
     if IDistributionSourcePackage.providedBy(self.context):
         return check_permission("launchpad.Driver",
                                 self.context.distribution)
     else:
         return False
Exemplo n.º 10
0
def get_git_namespace(target, owner):
    if IProduct.providedBy(target):
        return getUtility(IGitNamespaceSet).get(owner, project=target)
    elif IDistributionSourcePackage.providedBy(target):
        return getUtility(IGitNamespaceSet).get(
            owner, distribution=target.distribution,
            sourcepackagename=target.sourcepackagename)
    elif target is None or IPerson.providedBy(target):
        return getUtility(IGitNamespaceSet).get(owner)
    else:
        raise AssertionError("No Git namespace defined for %s" % target)
Exemplo n.º 11
0
    def validateStep(self, data):
        """Check that

        1. there's no bug_url if the target uses malone;
        2. there is a package with the given name;
        3. it's possible to create a new task for the given package/distro.
        """
        target = self.getTarget(data)
        bug_url = data.get('bug_url')
        if bug_url and target.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
            self.addError(
                "Bug watches can not be added for %s, as it uses Launchpad"
                " as its official bug tracker. Alternatives are to add a"
                " watch for another project, or a comment containing a"
                " URL to the related bug report." % target.displayname)

        distribution = data.get('distribution')
        sourcepackagename = data.get('sourcepackagename')
        entered_package = self.request.form.get(
            self.widgets['sourcepackagename'].name)
        if sourcepackagename is None and entered_package:
            # The entered package doesn't exist.
            if distribution.has_published_binaries:
                binary_tracking = ''
            else:
                binary_tracking = structured(
                    ' Launchpad does not track binary package names '
                    'in %s.', distribution.displayname)
            error = structured(
                'There is no package in %s named "%s".%s',
                distribution.displayname, entered_package,
                binary_tracking)
            self.setFieldError('sourcepackagename', error)
        elif not IDistributionSourcePackage.providedBy(sourcepackagename):
            try:
                target = distribution
                if sourcepackagename:
                    target = target.getSourcePackage(sourcepackagename)
                # The validity of the source package has already been checked
                # by the bug target widget.
                validate_new_target(
                    self.context.bug, target, check_source_package=False)
                if sourcepackagename:
                    data['sourcepackagename'] = target
            except IllegalTarget as e:
                if sourcepackagename:
                    self.setFieldError('sourcepackagename', e[0])
                else:
                    self.setFieldError('distribution', e[0])

        super(DistroBugTaskCreationStep, self).validateStep(data)
Exemplo n.º 12
0
 def setRenderedValue(self, value):
     """See IWidget."""
     self.setUpSubWidgets()
     if IProduct.providedBy(value):
         self.default_option = 'product'
         self.product_widget.setRenderedValue(value)
     elif IDistribution.providedBy(value):
         self.default_option = 'package'
         self.distribution_widget.setRenderedValue(value)
     elif IDistributionSourcePackage.providedBy(value):
         self.default_option = 'package'
         self.distribution_widget.setRenderedValue(value.distribution)
         self.package_widget.setRenderedValue(value.sourcepackagename)
     else:
         raise AssertionError('Not a valid value: %r' % value)
Exemplo n.º 13
0
 def continue_action(self, action, data):
     # set the packaging record for this productseries in the current
     # ubuntu series. if none exists, one will be created
     distroseries = self._getSubmittedSeries(data)
     sourcepackagename = data['sourcepackagename']
     if IDistributionSourcePackage.providedBy(sourcepackagename):
         sourcepackagename = sourcepackagename.sourcepackagename
     if getUtility(IPackagingUtil).packagingEntryExists(
             sourcepackagename, distroseries, productseries=self.context):
         # There is no change.
         return
     try:
         self.context.setPackaging(distroseries, sourcepackagename,
                                   self.user)
     except CannotPackageProprietaryProduct as e:
         self.request.response.addErrorNotification(str(e))
Exemplo n.º 14
0
def milestone_matches_bugtask(milestone, bugtask):
    """ Return True if the milestone can be set against this bugtask."""
    bug_target = bugtask.target
    naked_milestone = removeSecurityProxy(milestone)

    if IProduct.providedBy(bug_target):
        return bugtask.product.id == naked_milestone.productID
    elif IProductSeries.providedBy(bug_target):
        return bugtask.productseries.product.id == naked_milestone.productID
    elif (IDistribution.providedBy(bug_target)
          or IDistributionSourcePackage.providedBy(bug_target)):
        return bugtask.distribution.id == naked_milestone.distributionID
    elif (IDistroSeries.providedBy(bug_target)
          or ISourcePackage.providedBy(bug_target)):
        return bugtask.distroseries.id == naked_milestone.distroseriesID
    return False
Exemplo n.º 15
0
 def setRenderedValue(self, value):
     """See `IWidget`."""
     self.setUpSubWidgets()
     if value is None or IPerson.providedBy(value):
         self.default_option = "personal"
         return
     elif IProduct.providedBy(value):
         self.default_option = "project"
         self.project_widget.setRenderedValue(value)
         return
     elif IDistributionSourcePackage.providedBy(value):
         self.default_option = "package"
         self.distribution_widget.setRenderedValue(value.distribution)
         self.package_widget.setRenderedValue(value.sourcepackagename)
     else:
         raise AssertionError("Not a valid value: %r" % value)
Exemplo n.º 16
0
    def setTarget(self, target):
        """Constrain the search to only return items in target.

        This is equivalent to calling setProduct etc but the type of target
        does not need to be known to the caller.

        :param target: A `IHasBug`, or some search term like all/any/none on
            `IHasBug`. If using all/any all the targets must be of the
            same type due to implementation limitations. Currently only
            distroseries and productseries `IHasBug` implementations are
            supported.
        """
        # Yay circular deps.
        from lp.registry.interfaces.distribution import IDistribution
        from lp.registry.interfaces.distroseries import IDistroSeries
        from lp.registry.interfaces.product import IProduct
        from lp.registry.interfaces.productseries import IProductSeries
        from lp.registry.interfaces.milestone import IMilestone
        from lp.registry.interfaces.projectgroup import IProjectGroup
        from lp.registry.interfaces.sourcepackage import ISourcePackage
        from lp.registry.interfaces.distributionsourcepackage import \
            IDistributionSourcePackage
        if isinstance(target, (any, all)):
            assert len(target.query_values), \
                'cannot determine target with no targets'
            instance = target.query_values[0]
        else:
            instance = target
        if IDistribution.providedBy(instance):
            self.setDistribution(target)
        elif IDistroSeries.providedBy(instance):
            self.setDistroSeries(target)
        elif IProduct.providedBy(instance):
            self.setProduct(target)
        elif IProductSeries.providedBy(instance):
            self.setProductSeries(target)
        elif IMilestone.providedBy(instance):
            self.milestone = target
        elif ISourcePackage.providedBy(instance):
            self.setSourcePackage(target)
        elif IDistributionSourcePackage.providedBy(instance):
            self.setSourcePackage(target)
        elif IProjectGroup.providedBy(instance):
            self.setProjectGroup(target)
        else:
            raise AssertionError("unknown target type %r" % target)
    def validate(self, data):
        """Extra validations for the given fields."""
        # Without a file type we cannot do anything
        file_type = data.get('file_type')
        if file_type not in (TranslationFileType.PO, TranslationFileType.POT):
            self.setFieldError('file_type', 'Please specify the file type')
            return

        sourcepackagename = data.get('sourcepackagename')
        if IDistributionSourcePackage.providedBy(sourcepackagename):
            data['sourcepackagename'] = sourcepackagename.sourcepackagename

        self.path_changed = self._validatePath(file_type, data.get('path'))

        self.man_potemplate = None
        if file_type == TranslationFileType.POT:
            self._validatePOT(data)
        if file_type == TranslationFileType.PO:
            self.man_potemplate = self._validatePO(data)
Exemplo n.º 18
0
 def getRepositoryDefaults(self):
     """See `IGitRepository`."""
     defaults = []
     if self.target_default:
         defaults.append(ICanHasDefaultGitRepository(self.target))
     if self.owner_default:
         if IProduct.providedBy(self.target):
             factory = getUtility(IPersonProductFactory)
             default = factory.create(self.owner, self.target)
         elif IDistributionSourcePackage.providedBy(self.target):
             factory = getUtility(IPersonDistributionSourcePackageFactory)
             default = factory.create(self.owner, self.target)
         else:
             # Also enforced by database constraint.
             raise AssertionError(
                 "Only projects or packages can have owner-target default "
                 "repositories.")
         defaults.append(ICanHasDefaultGitRepository(default))
     return sorted(defaults)
Exemplo n.º 19
0
    def userCanAlterSubscription(self, subscriber, subscribed_by):
        """See `IStructuralSubscriptionTarget`."""
        # A Launchpad administrator or the user can subscribe a user.
        # A Launchpad or team admin can subscribe a team.

        # Nobody else can, unless the context is a IDistributionSourcePackage,
        # in which case the drivers or owner can.

        if IDistributionSourcePackage.providedBy(self):
            for driver in self.distribution.drivers:
                if subscribed_by.inTeam(driver):
                    return True
            if subscribed_by.inTeam(self.distribution.owner):
                return True

        admins = getUtility(ILaunchpadCelebrities).admin
        return (subscriber == subscribed_by or
                subscriber in subscribed_by.getAdministratedTeams() or
                subscribed_by.inTeam(admins))
Exemplo n.º 20
0
 def _getAffiliation(self, person, pillars):
     super_instance = super(QuestionPillarAffiliation, self)
     result = super_instance._getAffiliation(person, pillars)
     target = self.context.target
     if IDistributionSourcePackage.providedBy(target):
         question_targets = (target, target.distribution)
     else:
         question_targets = (target, )
     questions_person = IQuestionsPerson(person)
     for target in questions_person.getDirectAnswerQuestionTargets():
         if target in question_targets:
             result.append(
                 BadgeDetails(self.getIconUrl(pillars[0]),
                              target.displayname, 'answer contact'))
     for target in questions_person.getTeamAnswerQuestionTargets():
         if target in question_targets:
             result.append(
                 BadgeDetails(self.getIconUrl(pillars[0]),
                              target.displayname, 'answer contact'))
     return result
Exemplo n.º 21
0
 def change_action(self, action, data):
     context = self.context
     iscurrent = data.get('iscurrent', context.iscurrent)
     context.setActive(iscurrent)
     old_description = context.description
     old_translation_domain = context.translation_domain
     for field in ('sourcepackagename', 'from_sourcepackagename'):
         if IDistributionSourcePackage.providedBy(data.get(field)):
             data[field] = data[field].sourcepackagename
     self.updateContextFromData(data)
     if old_description != context.description:
         self.user.assignKarma('translationtemplatedescriptionchanged',
                               product=context.product,
                               distribution=context.distribution,
                               sourcepackagename=context.sourcepackagename)
     if old_translation_domain != context.translation_domain:
         # We only change date_last_updated when the translation_domain
         # field is changed because it is the only relevant field we
         # care about regarding the date of last update.
         naked_context = removeSecurityProxy(context)
         naked_context.date_last_updated = datetime.datetime.now(pytz.UTC)
Exemplo n.º 22
0
    def validate(self, data):
        name = data.get('name', None)
        if name is None or not valid_name(name):
            self.setFieldError(
                'name',
                'Template name can only start with lowercase letters a-z '
                'or digits 0-9, and other than those characters, can only '
                'contain "-", "+" and "." characters.')

        distroseries = data.get('distroseries', self.context.distroseries)
        sourcepackagename = data.get('sourcepackagename',
                                     self.context.sourcepackagename)
        if IDistributionSourcePackage.providedBy(sourcepackagename):
            sourcepackagename = sourcepackagename.sourcepackagename
        productseries = data.get('productseries', None)
        sourcepackage_changed = (
            distroseries is not None
            and (distroseries != self.context.distroseries
                 or sourcepackagename != self.context.sourcepackagename))
        productseries_changed = (productseries is not None and
                                 productseries != self.context.productseries)
        similar_templates = self._validateTargetAndGetTemplates(data)
        if similar_templates is not None:
            self.validateName(name, similar_templates, sourcepackage_changed,
                              productseries_changed)
            self.validateDomain(data.get('translation_domain'),
                                similar_templates, sourcepackage_changed,
                                productseries_changed)

        priority = data.get('priority')
        if priority is None:
            return

        if (priority < self.PRIORITY_MIN_VALUE
                or priority > self.PRIORITY_MAX_VALUE):
            self.setFieldError(
                'priority', 'The priority value must be between %s and %s.' %
                (self.PRIORITY_MIN_VALUE, self.PRIORITY_MAX_VALUE))
Exemplo n.º 23
0
    def validate(self, data):
        productseries = self.context
        sourcepackagename = data.get('sourcepackagename', None)
        if IDistributionSourcePackage.providedBy(sourcepackagename):
            sourcepackagename = sourcepackagename.sourcepackagename
        distroseries = self._getSubmittedSeries(data)

        packaging_util = getUtility(IPackagingUtil)
        if packaging_util.packagingEntryExists(
                productseries=productseries,
                sourcepackagename=sourcepackagename,
                distroseries=distroseries):
            # The package already exists. Don't display an error. The
            # action method will let this go by.
            return

        # Do not allow users to create links to unpublished Ubuntu packages.
        if (sourcepackagename is not None
                and distroseries.distribution.official_packages):
            source_package = distroseries.getSourcePackage(sourcepackagename)
            if source_package.currentrelease is None:
                message = ("The source package is not published in %s." %
                           distroseries.displayname)
                self.setFieldError('sourcepackagename', message)

        if packaging_util.packagingEntryExists(
                sourcepackagename=sourcepackagename,
                distroseries=distroseries):
            # The series package conflicts with another series.
            sourcepackage = distroseries.getSourcePackage(
                sourcepackagename.name)
            message = structured(
                'The <a href="%s">%s</a> package in %s is already linked to '
                'another series.' %
                (canonical_url(sourcepackage), sourcepackagename.name,
                 distroseries.displayname))
            self.setFieldError('sourcepackagename', message)
Exemplo n.º 24
0
 def review(self, user, permission, context=None, date_expires=None):
     """See `IOAuthRequestToken`."""
     if self.is_reviewed:
         raise OAuthValidationError(
             "Request tokens can be reviewed only once.")
     if self.is_expired:
         raise OAuthValidationError(
             'This request token has expired and can no longer be '
             'reviewed.')
     self.date_reviewed = datetime.now(pytz.timezone('UTC'))
     self.date_expires = date_expires
     self.person = user
     self.permission = permission
     if IProduct.providedBy(context):
         self.product = context
     elif IProjectGroup.providedBy(context):
         self.project = context
     elif IDistribution.providedBy(context):
         self.distribution = context
     elif IDistributionSourcePackage.providedBy(context):
         self.sourcepackagename = context.sourcepackagename
         self.distribution = context.distribution
     else:
         assert context is None, ("Unknown context type: %r." % context)
Exemplo n.º 25
0
    def _validateTargetAndGetTemplates(self, data):
        """Return a POTemplateSubset corresponding to the chosen target."""
        distroseries = data.get('distroseries')
        sourcepackagename = data.get('sourcepackagename')
        if IDistributionSourcePackage.providedBy(sourcepackagename):
            sourcepackagename = sourcepackagename.sourcepackagename
        productseries = data.get('productseries')

        if distroseries is not None and productseries is not None:
            message = ("Choose a distribution release series or a project "
                       "release series, but not both.")
        elif distroseries is None and productseries is None:
            message = ("Choose either a distribution release series or a "
                       "project release series.")
        else:
            message = None

        if message is not None:
            self.addError(message)
            return None
        return getUtility(IPOTemplateSet).getSubset(
            distroseries=distroseries,
            sourcepackagename=sourcepackagename,
            productseries=productseries)
Exemplo n.º 26
0
 def can_link_package(self):
     bugtask = self.context
     is_package_bugtask = IDistributionSourcePackage.providedBy(
         bugtask.target)
     return is_package_bugtask and bugtask.target.upstream_product is None
Exemplo n.º 27
0
 def getInputValue(self):
     """See `zope.formlib.interfaces.IInputWidget`."""
     self.setUpSubWidgets()
     form_value = self.request.form_ng.getOne(self.name)
     if form_value == "project":
         try:
             return self.project_widget.getInputValue()
         except MissingInputError:
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError("Please enter a project name"))
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.project" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no project named '%s' registered in "
                     "Launchpad" % entered_name))
     elif form_value == "package":
         try:
             distribution = self.distribution_widget.getInputValue()
         except ConversionError:
             entered_name = self.request.form_ng.getOne("%s.distribution" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no distribution named '%s' registered in "
                     "Launchpad" % entered_name))
         try:
             if self.package_widget.hasInput():
                 if bool(getFeatureFlag('disclosure.dsp_picker.enabled')):
                     self.package_widget.vocabulary.setDistribution(
                         distribution)
                 package_name = self.package_widget.getInputValue()
             else:
                 package_name = None
             if package_name is None:
                 raise WidgetInputError(
                     self.name, self.label,
                     LaunchpadValidationError(
                         "Please enter a package name"))
             if IDistributionSourcePackage.providedBy(package_name):
                 dsp = package_name
             else:
                 source_name = distribution.guessPublishedSourcePackageName(
                     package_name.name)
                 dsp = distribution.getSourcePackage(source_name)
         except (ConversionError, NotFoundError):
             entered_name = self.request.form_ng.getOne("%s.package" %
                                                        self.name)
             raise WidgetInputError(
                 self.name, self.label,
                 LaunchpadValidationError(
                     "There is no package named '%s' published in %s." %
                     (entered_name, distribution.displayname)))
         return dsp
     elif form_value == "personal":
         return None
     else:
         raise UnexpectedFormData("No valid option was selected.")
Exemplo n.º 28
0
    def execute(self, bug, bug_event):
        """See IEmailCommand."""
        if bug is None:
            raise EmailProcessingError(get_error_message(
                'command-with-no-bug.txt', error_templates=error_templates),
                                       stop_processing=True)

        string_args = list(self.string_args)
        try:
            path = string_args.pop(0)
        except IndexError:
            raise EmailProcessingError(get_error_message(
                'affects-no-arguments.txt', error_templates=error_templates),
                                       stop_processing=True)
        try:
            bug_target = self.getBugTarget(path)
        except BugTargetNotFound as error:
            raise EmailProcessingError(unicode(error), stop_processing=True)
        event = None

        if isinstance(bug, CreateBugParams):
            # Enough information has been gathered to create a new bug.
            # If a series task is requested, create the non-series
            # equivalent here. The series will be nominated/targeted in
            # the remainder of the method.
            if ISeriesBugTarget.providedBy(bug_target):
                bug.target = bug_target.bugtarget_parent
            else:
                bug.target = bug_target
            bug, bug_event = getUtility(IBugSet).createBug(bug,
                                                           notify_event=False)
            event = ObjectCreatedEvent(bug.bugtasks[0])
            # Continue because the bug_target may be a subordinate bugtask.

        bugtask = bug.getBugTask(bug_target)
        if (bugtask is None
                and IDistributionSourcePackage.providedBy(bug_target)):
            # If there's a distribution task with no source package, use
            # that one.
            bugtask = bug.getBugTask(bug_target.distribution)
            if bugtask is not None:
                bugtask_before_edit = Snapshot(bugtask, providing=IBugTask)
                bugtask.transitionToTarget(bug_target,
                                           getUtility(ILaunchBag).user)
                event = ObjectModifiedEvent(bugtask, bugtask_before_edit,
                                            ['sourcepackagename'])

        if bugtask is None:
            try:
                bugtask = self._create_bug_task(bug, bug_target)
            except IllegalTarget as e:
                raise EmailProcessingError(get_error_message(
                    'cannot-add-task.txt',
                    error_templates=error_templates,
                    bug_id=bug.id,
                    target_name=bug_target.name,
                    reason=e[0]),
                                           stop_processing=True)
            event = ObjectCreatedEvent(bugtask)

        return bugtask, event, bug_event
 def __eq__(self, other):
     """See `IDistributionSourcePackage`."""
     return ((IDistributionSourcePackage.providedBy(other))
             and (self.distribution.id == other.distribution.id)
             and (self.sourcepackagename.id == other.sourcepackagename.id))
 def target_label(self):
     """Return the target label for the portlet."""
     if IDistributionSourcePackage.providedBy(self.context):
         return "To all bugs in %s" % self.context.displayname
     else:
         return "To all %s bugs" % self.context.title