← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jcsackett/launchpad/deprecate-official_malone into lp:launchpad/devel

 

j.c.sackett has proposed merging lp:~jcsackett/launchpad/deprecate-official_malone into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #623408 Offiical_* booleans must be deprecated in favor of usage enums
  https://bugs.launchpad.net/bugs/623408


= Summary =

Replaces, where possible, usage of official_malone with the bug_tracking_usage property.

== Proposed fix ==

Where code uses official_malone to drive a decision regarding presentation or action,
update the code to use bug_tracking_usage instead, so we can use the richer data
provided by the usage enums.

== Pre-implementation notes ==

Spoke with Curtis Hovey (sinzui) and Brad Crittenden (bac).

== Implementation details ==

As in Proposed fix.

SQL queries using official_malone have been left alone until data migration occurs.

Instances where an assignment is made to official_malone, no replacement is made as the official_malone
boolean is part of the data driving bug_tracking_usage.

== Tests ==

No new tests written.

To fully test the refactor:

bin/test -m lib.lp.registry
bin/test -m lib.lp.bugs

== Demo and Q/A ==

In Launchpad.dev, nothing should crash when reviewing bugs or performing bug related actions.

There are no changes to the UX or UI, I believe everything should function in the same fashion.

= Launchpad lint =

This touched enough old files that the lint output is huge. I will fix all valid lint errors before committing, but I didn't want to pollute the diff too much nor make this MP a wall of text.
-- 
https://code.launchpad.net/~jcsackett/launchpad/deprecate-official_malone/+merge/33694
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jcsackett/launchpad/deprecate-official_malone into lp:launchpad/devel.
=== modified file 'lib/canonical/launchpad/doc/vocabularies.txt'
--- lib/canonical/launchpad/doc/vocabularies.txt	2010-02-17 11:13:06 +0000
+++ lib/canonical/launchpad/doc/vocabularies.txt	2010-08-25 20:33:46 +0000
@@ -251,9 +251,9 @@
 
     >>> mozilla_project = getUtility(IProjectGroupSet).getByName('mozilla')
     >>> for product in mozilla_project.products:
-    ...     print "%s: %s" % (product.name, product.official_malone)
-    firefox: True
-    thunderbird: False
+    ...     print "%s: %s" % (product.name, product.bug_tracking_usage.name)
+    firefox: LAUNCHPAD
+    thunderbird: UNKNOWN
 
     >>> mozilla_products_vocabulary = vocabulary_registry.get(
     ...     mozilla_project,'ProjectProductsUsingMalone')

=== modified file 'lib/canonical/launchpad/vocabularies/dbobjects.py'
--- lib/canonical/launchpad/vocabularies/dbobjects.py	2010-08-20 20:31:18 +0000
+++ lib/canonical/launchpad/vocabularies/dbobjects.py	2010-08-25 20:33:46 +0000
@@ -87,6 +87,7 @@
     SQLObjectVocabularyBase,
     )
 from lp.app.browser.stringformatter import FormattersAPI
+from lp.app.enums import ServiceUsage
 from lp.blueprints.interfaces.specification import SpecificationFilter
 from lp.blueprints.model.specification import Specification
 from lp.blueprints.model.sprint import Sprint
@@ -234,6 +235,7 @@
     These are branches that the user is guaranteed to be able to push
     to.
     """
+
     def __init__(self, context=None):
         """Pass a Person as context, or anything else for the current user."""
         super(HostedBranchRestrictedOnOwnerVocabulary, self).__init__(context)
@@ -341,6 +343,7 @@
     This vocabulary contains all the languages known to Launchpad,
     excluding English and non-visible languages.
     """
+
     def __contains__(self, language):
         """See `IVocabulary`.
 
@@ -382,7 +385,7 @@
     return SimpleVocabulary([
         SimpleTerm(product, product.name, title=product.displayname)
         for product in project.products
-        if product.official_malone])
+        if product.bug_tracking_usage == ServiceUsage.LAUNCHPAD])
 
 
 class TranslationGroupVocabulary(NamedSQLObjectVocabulary):
@@ -741,7 +744,8 @@
         return Distribution.selectBy(official_malone=True).count()
 
     def __contains__(self, obj):
-        return IDistribution.providedBy(obj) and obj.official_malone
+        return (IDistribution.providedBy(obj)
+                and obj.bug_tracking_usage == ServiceUsage.LAUNCHPAD)
 
     def getQuery(self):
         return None

=== modified file 'lib/lp/bugs/browser/bugalsoaffects.py'
--- lib/lp/bugs/browser/bugalsoaffects.py	2010-08-20 20:31:18 +0000
+++ lib/lp/bugs/browser/bugalsoaffects.py	2010-08-25 20:33:46 +0000
@@ -56,6 +56,7 @@
 from canonical.widgets.itemswidgets import LaunchpadRadioWidget
 from canonical.widgets.popup import SearchForUpstreamPopupWidget
 from canonical.widgets.textwidgets import StrippedTextWidget
+from lp.app.enums import ServiceUsage
 from lp.bugs.interfaces.bug import IBug
 from lp.bugs.interfaces.bugtask import (
     BugTaskImportance,
@@ -319,10 +320,11 @@
             if bug_watch is None:
                 bug_watch = task_added.bug.addWatch(
                     extracted_bugtracker, extracted_bug, self.user)
-            if not target.official_malone:
+            if target.bug_tracking_usage != ServiceUsage.LAUNCHPAD:
                 task_added.bugwatch = bug_watch
 
-        if (not target.official_malone and task_added.bugwatch is not None
+        if (target.bug_tracking_usage != ServiceUsage.LAUNCHPAD 
+            and task_added.bugwatch is not None
             and (task_added.bugwatch.bugtracker.bugtrackertype !=
                  BugTrackerType.EMAILADDRESS)):
             # A remote bug task gets its status from a bug watch, so
@@ -371,7 +373,7 @@
 
         if (not bug_url and
             not self.request.get('ignore_missing_remote_bug') and
-            not target.official_malone):
+            target.bug_tracking_usage != ServiceUsage.LAUNCHPAD):
             # We have no URL for the remote bug and the target does not use
             # Launchpad for bug tracking, so we warn the user this is not
             # optimal and ask for his confirmation.
@@ -404,7 +406,7 @@
         """
         target = self.getTarget(data)
         bug_url = data.get('bug_url')
-        if bug_url and target.official_malone:
+        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"

=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py	2010-08-22 18:31:30 +0000
+++ lib/lp/bugs/browser/bugtarget.py	2010-08-25 20:33:46 +0000
@@ -96,7 +96,11 @@
     NotFoundError,
     UnexpectedFormData,
     )
-from lp.app.interfaces.launchpad import ILaunchpadUsage
+from lp.app.enums import ServiceUsage
+from lp.app.interfaces.launchpad import (
+    ILaunchpadUsage,
+    IServiceUsage,
+    )
 from lp.bugs.browser.bugrole import BugRoleMixin
 from lp.bugs.browser.bugtask import BugTaskSearchListingView
 from lp.bugs.interfaces.apportjob import IProcessApportBlobJobSource
@@ -384,7 +388,7 @@
         # actually uses Malone for its bug tracking.
         product_or_distro = self.getProductOrDistroFromContext()
         if (product_or_distro is not None and
-            not product_or_distro.official_malone):
+            product_or_distro.bug_tracking_usage != ServiceUsage.LAUNCHPAD):
             self.setFieldError(
                 'bugtarget',
                 "%s does not use Launchpad as its bug tracker " %
@@ -421,15 +425,18 @@
         self.form_fields = self.form_fields.omit('security_related')
         self.form_fields += formlib.form.Fields(security_related_field)
 
+    # XXX jcsackett 2010-08-23: Calls to contextUsesMalone should be updated
+    # to take advantage of the extra data provided by the service usage
+    # enums.
     def contextUsesMalone(self):
         """Does the context use Malone as its official bugtracker?"""
         if IProjectGroup.providedBy(self.context):
             products_using_malone = [
                 product for product in self.context.products
-                if product.official_malone]
+                if product.bug_tracking_usage == ServiceUsage.LAUNCHPAD]
             return len(products_using_malone) > 0
         else:
-            return self.getMainContext().official_malone
+            return self.getMainContext().bug_tracking_usage == ServiceUsage.LAUNCHPAD
 
     def getMainContext(self):
         if IDistributionSourcePackage.providedBy(self.context):
@@ -1084,7 +1091,7 @@
     def products_using_malone(self):
         return [
             product for product in self.context.products
-            if product.official_malone]
+            if product.bug_tracking_usage == ServiceUsage.LAUNCHPAD]
 
     @property
     def default_product(self):
@@ -1252,8 +1259,8 @@
 
         :returns: boolean
         """
-        launchpad_usage = ILaunchpadUsage(self.context)
-        return launchpad_usage.official_malone
+        service_usage = IServiceUsage(self.context)
+        return service_usage.bug_tracking_usage == ServiceUsage.LAUNCHPAD
 
     @property
     def external_bugtracker(self):

=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py	2010-08-22 18:31:30 +0000
+++ lib/lp/bugs/browser/bugtask.py	2010-08-25 20:33:46 +0000
@@ -193,6 +193,7 @@
     )
 from canonical.widgets.project import ProjectScopeWidget
 from lp.answers.interfaces.questiontarget import IQuestionTarget
+from lp.app.enums import ServiceUsage
 from lp.app.errors import (
     NotFoundError,
     UnexpectedFormData,
@@ -1668,7 +1669,7 @@
 
         new_product = data.get('product')
         if (old_product is None or old_product == new_product or
-            not bugtask.pillar.official_malone):
+            bugtask.pillar.bug_tracking_usage != ServiceUsage.LAUNCHPAD):
             # Either the product wasn't changed, we're dealing with a #
             # distro task, or the bugtask's product doesn't use Launchpad,
             # which means the product can't be changed.
@@ -1994,7 +1995,7 @@
         """
         if not IProduct.providedBy(self.context):
             return None
-        if self.context.official_malone:
+        if self.context.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
             return None
         return "%s?field.status_upstream=pending_bugwatch" % (
             canonical_url(self.context, view_name='+bugs'))
@@ -2081,7 +2082,7 @@
         """
         if not IProduct.providedBy(self.context):
             return None
-        if self.context.official_malone:
+        if self.context.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
             return None
         params = get_default_search_params(self.user)
         params.pending_bugwatch_elsewhere = True
@@ -2997,7 +2998,7 @@
         """Is the context a Product that does not use Malone?"""
         return (
             IProduct.providedBy(self.context)
-            and not self.context.official_malone)
+            and self.context.bug_tracking_usage != ServiceUsage.LAUNCHPAD)
 
     def _upstreamContext(self):
         """Is this page being viewed in an upstream context?

=== modified file 'lib/lp/bugs/browser/distribution_upstream_bug_report.py'
--- lib/lp/bugs/browser/distribution_upstream_bug_report.py	2010-08-20 20:31:18 +0000
+++ lib/lp/bugs/browser/distribution_upstream_bug_report.py	2010-08-25 20:33:46 +0000
@@ -17,6 +17,7 @@
     LaunchpadView,
     )
 from canonical.launchpad.webapp.url import urlappend
+from lp.app.enums import ServiceUsage
 from lp.bugs.browser.bugtask import get_buglisting_search_filter_url
 
 # TODO: fix column sorting to work for the different colspans, or
@@ -145,7 +146,8 @@
         - dssp: an IDistributionSeriesSourcepackage
         - product: an IProduct
         - bugtracker: convenience holder for the product's bugtracker
-        - official_malone: convenience boolean for IProduct.official_malone
+        - bug_tracking_usage: convenience enum for 
+            IProduct.bug_tracking_usage
         - *_url: convenience URLs
     """
     def __init__(self, dsp, dssp, product, open_bugs, triaged_bugs,
@@ -162,11 +164,8 @@
         self.open_bugs_url = urlappend(
             dsp_bugs_url, get_buglisting_search_filter_url())
 
-        self.official_malone = bool(product and product.official_malone)
-        self.branch = (
-            product and product.development_focus.branch)
+        self.bug_tracking_usage = product.bug_tracking_usage
 
-        # If a product is specified, build some convenient links to
         # pages which allow filling out required information. The
         # template ensures they are only visible to people who can
         # actually change the product.
@@ -180,7 +179,7 @@
             # Create a 'bugtracker_name' attribute for searching.
             if self.bugtracker is not None:
                 self.bugtracker_name = self.bugtracker.title
-            elif self.product.official_malone:
+            elif self.product.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
                 self.bugtracker_name = 'Launchpad'
             else:
                 self.bugtracker_name = None

=== modified file 'lib/lp/bugs/browser/tests/bugtask-adding-views.txt'
--- lib/lp/bugs/browser/tests/bugtask-adding-views.txt	2010-07-26 12:49:23 +0000
+++ lib/lp/bugs/browser/tests/bugtask-adding-views.txt	2010-08-25 20:33:46 +0000
@@ -224,8 +224,8 @@
 offical bug tracker.
 
     >>> evolution_task = bug_four.bugtasks[0]
-    >>> evolution_task.target.official_malone
-    True
+    >>> evolution_task.target.bug_tracking_usage
+    <DBItem ServiceUsage.LAUNCHPAD, (20) Launchpad>
 
     >>> transaction.commit()
 
@@ -275,8 +275,8 @@
 are set to the default values.
 
     >>> alsa_task = bug_four.bugtasks[0]
-    >>> alsa_task.target.official_malone
-    False
+    >>> alsa_task.target.bug_tracking_usage
+    <DBItem ServiceUsage.UNKNOWN, (10) Unknown>
     >>> alsa_task.status.title
     'New'
     >>> alsa_task.importance.title
@@ -368,8 +368,8 @@
     >>> alsa_task = bug_four.bugtasks[0]
     >>> alsa_task.bugtargetname
     u'alsa-utils'
-    >>> alsa_task.product.official_malone
-    False
+    >>> alsa_task.product.bug_tracking_usage
+    <DBItem ServiceUsage.UNKNOWN, (10) Unknown>
     >>> alsa_task.bugwatch == bug_four.watches[0]
     True
 

=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_configure.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_configure.py	2010-08-20 20:31:18 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_configure.py	2010-08-25 20:33:46 +0000
@@ -6,6 +6,7 @@
 __metaclass__ = type
 
 from canonical.testing import DatabaseFunctionalLayer
+from lp.app.enums import ServiceUsage
 from lp.testing import (
     login_person,
     TestCaseWithFactory,
@@ -59,7 +60,9 @@
         self.assertEqual([], view.errors)
         self.assertEqual(self.owner, self.product.bug_supervisor)
         self.assertEqual(self.owner, self.product.security_contact)
-        self.assertTrue(self.product.official_malone)
+        self.assertEqual(
+            ServiceUsage.LAUNCHPAD,
+            self.product.bug_tracking_usage)
         self.assertTrue(self.product.enable_bug_expiration)
         self.assertEqual('sf-boing', self.product.remote_product)
         self.assertEqual('guidelines', self.product.bug_reporting_guidelines)

=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py	2010-08-25 14:41:20 +0000
+++ lib/lp/bugs/model/bug.py	2010-08-25 20:33:46 +0000
@@ -106,6 +106,7 @@
     MAIN_STORE,
     )
 from lp.answers.interfaces.questiontarget import IQuestionTarget
+from lp.app.enums import ServiceUsage
 from lp.app.errors import (
     NotFoundError,
     UserCannotUnsubscribePerson,
@@ -1168,7 +1169,7 @@
         if len(non_invalid_bugtasks) != 1:
             return None
         [valid_bugtask] = non_invalid_bugtasks
-        if valid_bugtask.pillar.official_malone:
+        if valid_bugtask.pillar.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
             return valid_bugtask
         else:
             return None

=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py	2010-08-22 18:31:30 +0000
+++ lib/lp/bugs/model/bugtask.py	2010-08-25 20:33:46 +0000
@@ -92,6 +92,7 @@
     MAIN_STORE,
     SLAVE_FLAVOR,
     )
+from lp.app.enums import ServiceUsage
 from lp.app.errors import NotFoundError
 from lp.bugs.interfaces.bug import IBugSet
 from lp.bugs.interfaces.bugattachment import BugAttachmentType
@@ -840,7 +841,7 @@
         """See `IBugTask`"""
         # XXX sinzui 2007-10-04 bug=149009:
         # This property is not needed. Code should inline this implementation.
-        return self.pillar.official_malone
+        return (self.pillar.bug_tracking_usage == ServiceUsage.LAUNCHPAD)
 
     def transitionToMilestone(self, new_milestone, user):
         """See `IBugTask`."""

=== modified file 'lib/lp/bugs/templates/bug-create-question.pt'
--- lib/lp/bugs/templates/bug-create-question.pt	2009-08-31 09:58:28 +0000
+++ lib/lp/bugs/templates/bug-create-question.pt	2010-08-25 20:33:46 +0000
@@ -17,7 +17,7 @@
                 A question was already created from this bug.
               </tal:question>
               <tal:uses-malone
-                condition="not: context/pillar/official_malone">
+                condition="not: context/pillar/bug_tracking_usage/enumvalue:LAUNCHPAD">
                 <tal:target
                   replace="context/target/displayname">Firefox</tal:target>
                 does not use Launchpad to track bugs.

=== modified file 'lib/lp/bugs/templates/bugtarget-macros-filebug.pt'
--- lib/lp/bugs/templates/bugtarget-macros-filebug.pt	2010-07-01 06:14:05 +0000
+++ lib/lp/bugs/templates/bugtarget-macros-filebug.pt	2010-08-25 20:33:46 +0000
@@ -298,7 +298,7 @@
           </p>
         </tal:singular>
         <ul class="product-bug-options" tal:repeat="product context/products">
-          <li condition="product/official_malone">
+          <li condition="product/bug_tracking_usage/enumvalue:LAUNCHPAD">
             <tal:link replace="structure product/fmt:link" />
             <ul class="bulleted">
               <tal:external-tracker

=== modified file 'lib/lp/bugs/templates/bugtask-requestfix-upstream.pt'
--- lib/lp/bugs/templates/bugtask-requestfix-upstream.pt	2010-07-23 16:00:36 +0000
+++ lib/lp/bugs/templates/bugtask-requestfix-upstream.pt	2010-08-25 20:33:46 +0000
@@ -50,7 +50,7 @@
         </div>
       </div>
 
-      <div id="upstream-text" tal:condition="not: product/official_malone"
+      <div id="upstream-text" tal:condition="not: product/bug_tracking_usage/enumvalue:LAUNCHPAD"
           tal:define="widgets view/bugwatch_widgets;
                       bugtracker product/getExternalBugTracker">
         <p tal:condition="bugtracker">
@@ -156,14 +156,14 @@
       </p>
 
       <tal:no_bug_supervisor tal:condition="not:product/bug_supervisor">
-        <p tal:condition="product/official_malone">
+        <p tal:condition="product/bug_tracking_usage/enumvalue:LAUNCHPAD">
           <a tal:replace="structure product/owner/fmt:link">Sample Person</a>, the
              <tal:product tal:replace="product/displayname">Firefox</tal:product>
              registrant, will be notified about this bug.
 
         </p>
 
-        <p tal:condition="not: product/official_malone">
+        <p tal:condition="not: product/bug_tracking_usage/enumvalue:LAUNCHPAD">
           There is no bug supervisor for
           <tal:product tal:replace="product/displayname">Firefox</tal:product>.
           This means that there is nobody upstream we can notify about

=== modified file 'lib/lp/bugs/templates/distribution-upstream-bug-report.pt'
--- lib/lp/bugs/templates/distribution-upstream-bug-report.pt	2010-02-16 17:59:59 +0000
+++ lib/lp/bugs/templates/distribution-upstream-bug-report.pt	2010-08-25 20:33:46 +0000
@@ -166,10 +166,10 @@
                 </td>
               </tal:has-bugtracker>
               <tal:has-no-bugtracker condition="not: item/bugtracker">
-                <td tal:condition="item/official_malone" align="center">
+                <td tal:condition="item/bug_tracking_usage/enumvalue:LAUNCHPAD" align="center">
                     <img src="/@@/yes" title="Launchpad" />
                 </td>
-                <td tal:condition="not: item/official_malone" align="center">
+                <td tal:condition="not: item/bug_tracking_usage/enumvalue:LAUNCHPAD" align="center">
                     <img src="/@@/no" title="Unknown" />
                     <a tal:condition="item/product/required:launchpad.Edit"
                        tal:attributes="href item/product_edit_url">
@@ -225,11 +225,11 @@
                  tal:content="item/upstream_bugs_delta"></a>
             </td>
             <tal:upstream-in-launchpad
-                condition="item/official_malone">
+                condition="item/bug_tracking_usage/enumvalue:LAUNCHPAD">
                 <td colspan="4" class="good">&nbsp;</td>
             </tal:upstream-in-launchpad>
             <tal:upstream-not-in-launchpad
-                condition="not: item/official_malone">
+                condition="not: item/bug_tracking_usage/enumvalue:LAUNCHPAD">
               <td tal:attributes="class string:amount ${item/watched_bugs_class}"
                   tal:content="item/watched_bugs" />
               <td tal:attributes="class string:amount ${item/watched_bugs_class}"

=== modified file 'lib/lp/bugs/tests/bugtarget-questiontarget.txt'
--- lib/lp/bugs/tests/bugtarget-questiontarget.txt	2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/tests/bugtarget-questiontarget.txt	2010-08-25 20:33:46 +0000
@@ -43,8 +43,8 @@
 prerequisite for a bug to become a question is that the bugtarget's
 pillar must use Launchpad to track bugs.
 
-    >>> bug.affected_pillars[0].official_malone
-    True
+    >>> bug.affected_pillars[0].bug_tracking_usage
+    <DBItem ServiceUsage.LAUNCHPAD, (20) Launchpad>   
     >>> bug.canBeAQuestion()
     True
 
@@ -56,8 +56,8 @@
     >>> firefox = firefox_bug.bugtasks[0].target
     >>> IQuestionTarget.providedBy(firefox)
     True
-    >>> firefox.distribution.official_malone
-    False
+    >>> firefox.distribution.bug_tracking_usage
+    <DBItem ServiceUsage.UNKNOWN, (10) Unknown>
     >>> firefox_bug.canBeAQuestion()
     False
 

=== modified file 'lib/lp/bugs/tests/test_bugtask_1.py'
--- lib/lp/bugs/tests/test_bugtask_1.py	2010-08-20 20:31:18 +0000
+++ lib/lp/bugs/tests/test_bugtask_1.py	2010-08-25 20:33:46 +0000
@@ -17,6 +17,7 @@
     )
 from canonical.launchpad.webapp.interfaces import ILaunchBag
 from canonical.testing import DatabaseFunctionalLayer
+from lp.app.enums import ServiceUsage
 from lp.bugs.interfaces.bug import IBugSet
 from lp.bugs.interfaces.bugtask import (
     BugTaskStatus,
@@ -73,7 +74,7 @@
         # Mark an upstream task on bug #1 "Fix Released"
         bug_one = bugset.get(1)
         firefox_upstream = self._getBugTaskByTarget(bug_one, firefox)
-        self.assert_(firefox_upstream.product.official_malone)
+        self.assert_(firefox_upstream.product.bug_tracking_usage == ServiceUsage.LAUNCHPAD)
         self.old_firefox_status = firefox_upstream.status
         firefox_upstream.transitionToStatus(
             BugTaskStatus.FIXRELEASED, getUtility(ILaunchBag).user)

=== modified file 'lib/lp/registry/adapters.py'
--- lib/lp/registry/adapters.py	2010-08-20 20:31:18 +0000
+++ lib/lp/registry/adapters.py	2010-08-25 20:33:46 +0000
@@ -7,6 +7,7 @@
 
 __all__ = [
     'distroseries_to_launchpadusage',
+    'distroseries_to_serviceusage',
     'PollSubset',
     'productseries_to_product',
     ]
@@ -29,6 +30,9 @@
     """Adapts `IDistroSeries` object to `ILaunchpadUsage`."""
     return distroseries.distribution
 
+def distroseries_to_serviceusage(distroseries):
+    """Adapts `IDistroSeries` object to `IServiceUsage`."""
+    return distroseries.distribution
 
 def person_from_principal(principal):
     """Adapt `ILaunchpadPrincipal` to `IPerson`."""

=== modified file 'lib/lp/registry/browser/pillar.py'
--- lib/lp/registry/browser/pillar.py	2010-08-20 20:31:18 +0000
+++ lib/lp/registry/browser/pillar.py	2010-08-25 20:33:46 +0000
@@ -31,6 +31,7 @@
     nearest,
     )
 from canonical.launchpad.webapp.tales import MenuAPI
+from lp.app.enums import ServiceUsage
 from lp.registry.browser.structuralsubscription import (
     StructuralSubscriptionMenuMixin,
     )
@@ -135,7 +136,8 @@
     def has_involvement(self):
         """This `IPillar` uses Launchpad."""
         return (
-            self.official_malone or self.official_answers
+            self.official_malone
+            or self.official_answers
             or self.official_blueprints or self.official_rosetta
             or self.official_codehosting)
 

=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py	2010-08-23 04:48:17 +0000
+++ lib/lp/registry/browser/productseries.py	2010-08-25 20:33:46 +0000
@@ -83,6 +83,7 @@
 from canonical.launchpad.webapp.tales import MenuAPI
 from canonical.widgets.itemswidgets import LaunchpadRadioWidget
 from canonical.widgets.textwidgets import StrippedTextWidget
+from lp.app.enums import ServiceUsage
 from lp.app.errors import (
     NotFoundError,
     UnexpectedFormData,

=== modified file 'lib/lp/registry/browser/sourcepackage.py'
--- lib/lp/registry/browser/sourcepackage.py	2010-08-23 22:29:52 +0000
+++ lib/lp/registry/browser/sourcepackage.py	2010-08-25 20:33:46 +0000
@@ -73,6 +73,7 @@
 from canonical.launchpad.webapp.publisher import LaunchpadView
 from canonical.lazr.utils import smartquote
 from canonical.widgets import LaunchpadRadioWidget
+from lp.app.enums import ServiceUsage
 from lp.answers.browser.questiontarget import (
     QuestionTargetAnswersMenu,
     QuestionTargetFacetMixin,
@@ -575,7 +576,7 @@
         if self.context.productseries is None:
             return False
         product = self.context.productseries.product
-        if product.official_malone:
+        if product.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
             return True
         bugtracker = product.bugtracker
         if bugtracker is None:

=== modified file 'lib/lp/registry/browser/tests/distribution-views.txt'
--- lib/lp/registry/browser/tests/distribution-views.txt	2010-06-16 08:22:00 +0000
+++ lib/lp/registry/browser/tests/distribution-views.txt	2010-08-25 20:33:46 +0000
@@ -106,8 +106,8 @@
 
 The view accepts most of the distribution fields.
 
-    >>> distribution.official_malone
-    False
+    >>> distribution.bug_tracking_usage
+    <DBItem ServiceUsage.UNKNOWN, (10) Unknown>
 
     >>> view.field_names
     ['displayname', 'title', 'summary', 'description',
@@ -131,7 +131,7 @@
     guidelines
 
     >>> distribution.official_malone
-    True
+    <DBItem ServiceUsage.LAUNCHPAD, (20) Launchpad>
 
 Only admins and owners can access the view.
 

=== modified file 'lib/lp/registry/browser/tests/productseries-views.txt'
--- lib/lp/registry/browser/tests/productseries-views.txt	2010-08-23 04:48:17 +0000
+++ lib/lp/registry/browser/tests/productseries-views.txt	2010-08-25 20:33:46 +0000
@@ -37,10 +37,6 @@
     True
     >>> print view.official_malone
     True
-    >>> print view.official_rosetta
-    True
-    >>> print view.official_codehosting
-    False
     >>> for link in view.enabled_links:
     ...     print link.url
     http://bugs.launchpad.dev/app/simple/+filebug

=== modified file 'lib/lp/registry/browser/tests/sourcepackage-views.txt'
--- lib/lp/registry/browser/tests/sourcepackage-views.txt	2010-08-04 05:27:22 +0000
+++ lib/lp/registry/browser/tests/sourcepackage-views.txt	2010-08-25 20:33:46 +0000
@@ -293,8 +293,8 @@
     >>> view = create_initialized_view(
     ...     package, name='+upstream-connections')
 
-    >>> print product.official_malone
-    False
+    >>> print product.bug_tracking_usage.name
+    UNKNOWN
     >>> print product.bugtracker
     None
     >>> print view.has_bugtracker

=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2010-08-23 03:25:20 +0000
+++ lib/lp/registry/configure.zcml	2010-08-25 20:33:46 +0000
@@ -171,6 +171,11 @@
         factory="lp.registry.adapters.distroseries_to_launchpadusage"
         permission="zope.Public"/>
     <adapter
+        provides="lp.app.interfaces.launchpad.IServiceUsage"
+        for="lp.registry.interfaces.distroseries.IDistroSeries"
+        factory="lp.registry.adapters.distroseries_to_serviceusage"
+        permission="zope.Public"/>
+    <adapter
         provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
         for="lp.registry.interfaces.distroseries.IDistroSeries"
         factory="lp.registry.browser.distroseries.DistroSeriesBreadcrumb"
@@ -1379,6 +1384,11 @@
         factory="lp.registry.adapters.productseries_to_product"
         permission="zope.Public"/>
     <adapter
+        provides="lp.app.interfaces.launchpad.IServiceUsage"
+        for="lp.registry.interfaces.productseries.IProductSeries"
+        factory="lp.registry.adapters.productseries_to_product"
+        permission="zope.Public"/>
+    <adapter
         provides="lp.app.interfaces.launchpad.ILaunchpadUsage"
         for="lp.registry.interfaces.productseries.IProductSeries"
         factory="lp.registry.adapters.productseries_to_product"

=== modified file 'lib/lp/registry/doc/product.txt'
--- lib/lp/registry/doc/product.txt	2010-08-22 19:46:19 +0000
+++ lib/lp/registry/doc/product.txt	2010-08-25 20:33:46 +0000
@@ -258,8 +258,8 @@
 one.
 
     >>> firefox = getUtility(IProductSet).getByName('firefox')
-    >>> firefox.official_malone
-    True
+    >>> firefox.bug_tracking_usage
+    <DBItem ServiceUsage.LAUNCHPAD, (20) Launchpad>
     >>> print firefox.bug_tracking_usage.name
     LAUNCHPAD
     >>> firefox.getExternalBugTracker() is None

=== modified file 'lib/lp/registry/templates/distribution-index.pt'
--- lib/lp/registry/templates/distribution-index.pt	2010-08-06 16:01:38 +0000
+++ lib/lp/registry/templates/distribution-index.pt	2010-08-25 20:33:46 +0000
@@ -55,7 +55,7 @@
             tal:condition="context/official_answers" />
 
           <div tal:replace="structure context/@@+portlet-latestbugs"
-            tal:condition="context/official_malone" />
+            tal:condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD" />
 
           <div tal:replace="structure context/@@+portlet-top-contributors" />
         </div>

=== modified file 'lib/lp/registry/templates/distribution-search.pt'
--- lib/lp/registry/templates/distribution-search.pt	2009-08-05 19:34:07 +0000
+++ lib/lp/registry/templates/distribution-search.pt	2010-08-25 20:33:46 +0000
@@ -69,7 +69,7 @@
                     tal:define="distribution package/distribution">
                     <a
                       tal:define="link package/menu:bugs/filebug"
-                      tal:condition="distribution/official_malone"
+                      tal:condition="distribution/bug_tracking_usage/enumvalue:LAUNCHPAD"
                       tal:attributes="href link/url">
                       <img
                         tal:attributes="alt link/text"

=== modified file 'lib/lp/registry/templates/product-index.pt'
--- lib/lp/registry/templates/product-index.pt	2010-08-13 21:30:24 +0000
+++ lib/lp/registry/templates/product-index.pt	2010-08-25 20:33:46 +0000
@@ -218,7 +218,7 @@
             tal:condition="context/official_answers" />
 
           <div tal:content="structure context/@@+portlet-latestbugs"
-            tal:condition="context/official_malone" />
+            tal:condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD" />
 
           <div tal:content="structure context/@@+portlet-top-contributors" />
 

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2010-08-22 18:31:30 +0000
+++ lib/lp/testing/factory.py	2010-08-25 20:33:46 +0000
@@ -835,7 +835,7 @@
             project=project,
             registrant=registrant)
         if official_malone is not None:
-            product.official_malone = official_malone
+            removeSecurityProxy(product).official_malone = official_malone
         if official_rosetta is not None:
             removeSecurityProxy(product).official_rosetta = official_rosetta
         if bug_supervisor is not None:


Follow ups