← Back to team overview

launchpad-reviewers team mailing list archive

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

 

j.c.sackett has proposed merging lp:~jcsackett/launchpad/deprecate-official_rosetta 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_rosetta with the translations_usage property.

== Proposed fix ==

Where code uses official_rosetta, use translations_usage instead so that we can take advantage of richer data.

== Pre-implementation notes ==

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

== Implementation details ==

As in Proposed fix.

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

== Tests ==

No new tests written.

To fully test the refactor:

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

== Demo and Q/A ==

In Launchpad.dev, nothing should crash when reviewing translations or performing translation related actions.

= 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_rosetta/+merge/34229
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jcsackett/launchpad/deprecate-official_rosetta into lp:launchpad/devel.
=== modified file 'lib/lp/app/enums.py'
--- lib/lp/app/enums.py	2010-08-20 20:31:18 +0000
+++ lib/lp/app/enums.py	2010-08-31 18:18:46 +0000
@@ -1,11 +1,12 @@
 # Copyright 2010 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-"""Enumerations used in the lp/app modules."""
+"""Enumerations and related utilities used in the lp/app modules."""
 
 __metaclass__ = type
 __all__ = [
     'ServiceUsage',
+    'service_uses_launchpad',
     ]
 
 from lazr.enum import (
@@ -45,3 +46,7 @@
 
     The pillar does not use this type of service in Launchpad or externally.
     """)
+
+
+def service_uses_launchpad(usage_enum):
+    return usage_enum == ServiceUsage.LAUNCHPAD

=== 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-31 18:18:46 +0000
@@ -7,16 +7,25 @@
 
 __all__ = [
     'distroseries_to_launchpadusage',
+    'distroseries_to_serviceusage',
     'PollSubset',
     'productseries_to_product',
     ]
 
 
-from zope.component import getUtility
+from zope.component import (
+    adapter,
+    getUtility,
+    )
 from zope.component.interfaces import ComponentLookupError
-from zope.interface import implements
+from zope.interface import (
+    implementer,
+    implements,
+    )
 
 from canonical.launchpad.webapp.interfaces import ILaunchpadPrincipal
+from lp.app.interfaces.launchpad import IServiceUsage
+from lp.registry.interfaces.distroseries import IDistroSeries
 from lp.registry.interfaces.poll import (
     IPollSet,
     IPollSubset,
@@ -25,6 +34,13 @@
     )
 
 
+@implementer(IServiceUsage)
+@adapter(IDistroSeries)
+def distroseries_to_serviceusage(distroseries):
+    """Adapts `IDistroSeries` object to `IServiceUsage`."""
+    return distroseries.distribution
+
+
 def distroseries_to_launchpadusage(distroseries):
     """Adapts `IDistroSeries` object to `ILaunchpadUsage`."""
     return distroseries.distribution

=== modified file 'lib/lp/registry/browser/distribution.py'
--- lib/lp/registry/browser/distribution.py	2010-08-26 22:44:30 +0000
+++ lib/lp/registry/browser/distribution.py	2010-08-31 18:18:46 +0000
@@ -75,6 +75,7 @@
 from canonical.launchpad.webapp.breadcrumb import Breadcrumb
 from canonical.launchpad.webapp.interfaces import ILaunchBag
 from canonical.widgets.image import ImageChangeWidget
+from lp.app.enums import service_uses_launchpad
 from lp.answers.browser.faqtarget import FAQTargetNavigationMixin
 from lp.answers.browser.questiontarget import (
     QuestionTargetFacetMixin,
@@ -136,7 +137,7 @@
             if self.context.official_codehosting:
                 url = canonical_url(self.context, rootsite='code')
                 uses.append(href_template % (url, 'Branches'))
-        if self.context.official_rosetta:
+        if service_uses_launchpad(self.context.translations_usage):
             url = canonical_url(self.context, rootsite='translations')
             uses.append(href_template % (url, 'Translations'))
 

=== 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-31 18:18:46 +0000
@@ -31,6 +31,11 @@
     nearest,
     )
 from canonical.launchpad.webapp.tales import MenuAPI
+from lp.app.enums import (
+    ServiceUsage,
+    service_uses_launchpad,
+    )
+from lp.app.interfaces.launchpad import IServiceUsage
 from lp.registry.browser.structuralsubscription import (
     StructuralSubscriptionMenuMixin,
     )
@@ -70,7 +75,7 @@
     def help_translate(self):
         return Link(
             '', 'Help translate', site='translations', icon='translations',
-            enabled=self.pillar.official_rosetta)
+            enabled=service_uses_launchpad(self.pillar.translations_usage))
 
     def submit_code(self):
         return Link(
@@ -95,7 +100,7 @@
         self.official_malone = False
         self.official_answers = False
         self.official_blueprints = False
-        self.official_rosetta = False
+        self.translations_usage = ServiceUsage.UNKNOWN
         self.official_codehosting = False
         pillar = nearest(self.context, IPillar)
         if IProjectGroup.providedBy(pillar):
@@ -111,7 +116,7 @@
                 self.official_codehosting = False
             elif IDistributionSourcePackage.providedBy(self.context):
                 self.official_blueprints = False
-                self.official_rosetta = False
+                self.translations_usage = ServiceUsage.UNKNOWN
             else:
                 # The context is used by all apps.
                 pass
@@ -126,8 +131,7 @@
             self.official_answers = True
         if pillar.official_blueprints:
             self.official_blueprints = True
-        if pillar.official_rosetta:
-            self.official_rosetta = True
+        self.translations_usage = IServiceUsage(pillar).translations_usage
         if pillar.official_codehosting:
             self.official_codehosting = True
 
@@ -136,7 +140,8 @@
         """This `IPillar` uses Launchpad."""
         return (
             self.official_malone or self.official_answers
-            or self.official_blueprints or self.official_rosetta
+            or self.official_blueprints
+            or service_uses_launchpad(self.translations_usage)
             or self.official_codehosting)
 
     @property

=== modified file 'lib/lp/registry/browser/tests/pillar-views.txt'
--- lib/lp/registry/browser/tests/pillar-views.txt	2010-08-19 20:11:11 +0000
+++ lib/lp/registry/browser/tests/pillar-views.txt	2010-08-31 18:18:46 +0000
@@ -35,8 +35,8 @@
     True
     >>> view.official_answers
     True
-    >>> view.official_rosetta
-    False
+    >>> view.translations_usage.name
+    'UNKNOWN'
     >>> view.official_blueprints
     False
     >>> view.official_codehosting
@@ -230,9 +230,10 @@
 set the links.  Despite the fact that the distribution uses blueprints,
 and translations those links are not enabled for DistributionSourcePackages.
 
+    >>> from lp.app.enums import ServiceUsage
     >>> login_person(distribution.owner)
     >>> distribution.official_blueprints = True
-    >>> distribution.official_rosetta = True
+    >>> distribution.translations_usage = ServiceUsage.LAUNCHPAD
     >>> package = factory.makeDistributionSourcePackage(
     ...     sourcepackagename="box",
     ...     distribution=distribution)

=== 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-31 18:18:46 +0000
@@ -23,11 +23,12 @@
 The ProductSeries involvement view uses the ProductSeriesInvolvedMenu when
 rendering links:
 
+    >>> from lp.app.enums import ServiceUsage
     >>> login_person(product.owner)
     >>> product.official_answers = True
     >>> product.official_blueprints = True
     >>> product.official_malone = True
-    >>> product.official_rosetta = True
+    >>> product.translations_usage = ServiceUsage.LAUNCHPAD
     >>> view = create_view(series, '+get-involved')
 
     # official_answers is always false for product series.
@@ -37,8 +38,8 @@
     True
     >>> print view.official_malone
     True
-    >>> print view.official_rosetta
-    True
+    >>> print view.translations_usage.name
+    LAUNCHPAD
     >>> print view.official_codehosting
     False
     >>> for link in view.enabled_links:
@@ -476,7 +477,7 @@
 A series cannot be deleted if it is has translation templates.
 
     >>> translated_series = factory.makeProductSeries(product=product)
-    >>> product.official_rosetta = True
+    >>> product.translations_usage = ServiceUsage.LAUNCHPAD
     >>> po_template = factory.makePOTemplate(
     ...     name='gibberish', productseries=translated_series)
     >>> translated_view = create_initialized_view(

=== 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-31 18:18:46 +0000
@@ -171,6 +171,8 @@
         factory="lp.registry.adapters.distroseries_to_launchpadusage"
         permission="zope.Public"/>
     <adapter
+        factory="lp.registry.adapters.distroseries_to_serviceusage" />
+    <adapter
         provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
         for="lp.registry.interfaces.distroseries.IDistroSeries"
         factory="lp.registry.browser.distroseries.DistroSeriesBreadcrumb"
@@ -1379,6 +1381,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/distribution.txt'
--- lib/lp/registry/doc/distribution.txt	2010-08-23 00:51:30 +0000
+++ lib/lp/registry/doc/distribution.txt	2010-08-31 18:18:46 +0000
@@ -385,8 +385,8 @@
     >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
     >>> ubuntu.official_malone
     True
-    >>> ubuntu.official_rosetta
-    True
+    >>> ubuntu.translations_usage.name
+    'LAUNCHPAD' 
     >>> ubuntu.official_answers
     True
     >>> ubuntu.official_blueprints
@@ -412,7 +412,8 @@
     >>> print ubuntu.blueprints_usage.name
     LAUNCHPAD
 
-If the official_ attributes are False, the usage enums don't know anything.
+If the official_ attributes are False and the enum hasn't been set,
+the usage enums don't know anything.
 
     >>> login_person(ubuntu.owner.teamowner)
     >>> ubuntu.official_rosetta = False
@@ -422,37 +423,35 @@
 A distribution *cannot* specify that it uses codehosting. Currently there's
 no way for a distribution to use codehosting.
 
-    >>> ubuntu.official_codehosting
-    False
-    >>> ubuntu.official_codehosting = True
-    Traceback (most recent call last):
-    ForbiddenAttribute: ('official_codehosting', ...)
-
+    >>> from lp.app.enums import ServiceUsage
     >>> print ubuntu.codehosting_usage.name
     NOT_APPLICABLE
-
+    >>> ubuntu.codehosting_usage = ServiceUsage.LAUNCHPAD
+    Traceback (most recent call last):
+    AttributeError: can't set attribute...
+ 
 While Debian uses none:
 
     >>> debian = getUtility(ILaunchpadCelebrities).debian
-    >>> debian.official_malone
-    False
-    >>> debian.official_rosetta
-    False
-    >>> debian.official_answers
-    False
-    >>> debian.official_codehosting
-    False
-    >>> debian.official_blueprints
-    False
+    >>> print debian.bug_tracking_usage.name
+    UNKNOWN
+    >>> print debian.translations_usage.name
+    UNKNOWN
+    >>> print debian.answers_usage.name
+    UNKNOWN
+    >>> print debian.codehosting_usage.name
+    NOT_APPLICABLE
+    >>> print debian.blueprints_usage.name
+    UNKNOWN
 
 Gentoo only uses Malone
 
-    >>> print gentoo.official_malone
-    True
-    >>> print gentoo.official_rosetta
-    False
-    >>> print gentoo.official_answers
-    False
+    >>> print gentoo.bug_tracking_usage.name
+    LAUNCHPAD 
+    >>> print gentoo.translations_usage.name
+    UNKNOWN
+    >>> print gentoo.answers_usage.name
+    UNKNOWN
 
 Launchpad admins and the distro owner can set these fields.
 
@@ -464,9 +463,9 @@
     >>> debian.official_malone = True
     >>> debian.official_malone
     True
-    >>> debian.official_rosetta = True
-    >>> debian.official_rosetta
-    True
+    >>> debian.translations_usage = ServiceUsage.LAUNCHPAD
+    >>> debian.translations_usage.name
+    'LAUNCHPAD'
 
     >>> debian_owner = factory.makePerson()
     >>> debian.owner = debian_owner
@@ -484,9 +483,9 @@
     >>> debian.official_malone = True
     Traceback (most recent call last):
     Unauthorized: (..., 'official_malone', 'launchpad.Edit')
-    >>> debian.official_rosetta = True
+    >>> debian.translations_usage = ServiceUsage.LAUNCHPAD
     Traceback (most recent call last):
-    Unauthorized: (..., 'official_rosetta', 'launchpad.Edit')
+    Unauthorized: (..., 'translations_usage', 'launchpad.Edit')
 
 
 === Specification Listings ===

=== 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-31 18:18:46 +0000
@@ -583,6 +583,11 @@
     >>> from lp.translations.interfaces.potemplate import IPOTemplateSet
     >>> potemplate_set = getUtility(IPOTemplateSet)
 
+We're going to be setting the ServiceUsage values for products, so we 
+need those enums.
+
+    >>> from lp.app.enums import ServiceUsage
+
 Firefox has two series, but no translatable series either:
 
     >>> firefox = productset.getByName('firefox')
@@ -616,7 +621,7 @@
 And set that product as using translations officially. We need it so
 translations are available.
 
-    >>> firefox.official_rosetta = True
+    >>> firefox.translations_usage = ServiceUsage.LAUNCHPAD
 
 The primary_translatable now points at firefox 1.0:
 

=== modified file 'lib/lp/registry/doc/project.txt'
--- lib/lp/registry/doc/project.txt	2010-06-07 07:52:45 +0000
+++ lib/lp/registry/doc/project.txt	2010-08-31 18:18:46 +0000
@@ -349,8 +349,8 @@
 
 That is using Rosetta officially.
 
-    >>> evolution.official_rosetta
-    True
+    >>> print evolution.translations_usage.name
+    LAUNCHPAD
 
 GNOME project has also another product, netapplet.
 
@@ -361,8 +361,8 @@
 But it was not returned from 'translatables' method because it's not using
 Rosetta officially.
 
-    >>> netapplet.official_rosetta
-    False
+    >>> print netapplet.translations_usage.name
+    UNKNOWN
 
 And thus, it doesn't have any translatable series.
 

=== modified file 'lib/lp/registry/model/projectgroup.py'
--- lib/lp/registry/model/projectgroup.py	2010-08-20 20:31:18 +0000
+++ lib/lp/registry/model/projectgroup.py	2010-08-31 18:18:46 +0000
@@ -165,7 +165,6 @@
     max_bug_heat = Int()
 
     # convenient joins
-
     @property
     def products(self):
         return Product.selectBy(project=self, active=True, orderBy='name')
@@ -205,6 +204,9 @@
 
     def translatables(self):
         """See `IProjectGroup`."""
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this sql needs to be updated to check for the
+        # translations_usage, not official_rosetta.
         return Product.select('''
             Product.project = %s AND
             Product.official_rosetta = TRUE AND
@@ -274,7 +276,7 @@
 
         # filter based on completion. see the implementation of
         # Specification.is_complete() for more details
-        completeness =  Specification.completeness_clause
+        completeness = Specification.completeness_clause
 
         if SpecificationFilter.COMPLETE in filter:
             query += ' AND ( %s ) ' % completeness

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2010-08-30 06:38:53 +0000
+++ lib/lp/testing/factory.py	2010-08-31 18:18:46 +0000
@@ -93,6 +93,7 @@
     IStoreSelector,
     MAIN_STORE,
     )
+from lp.app.enums import ServiceUsage
 from lp.archiveuploader.dscfile import DSCFile
 from lp.archiveuploader.uploadpolicy import BuildDaemonUploadPolicy
 from lp.blueprints.interfaces.specification import (
@@ -804,11 +805,16 @@
                 description=description)
         return release_file
 
+    # XXX j.c.sackett 2010-08-30 While official_rosetta could be upgraded
+    # to translations_usage, official_malone had to be left alone as the
+    # usage enum bug_tracking_usage isn't assignable. It would be really
+    # nice if someone found a way to make this more consistent in the
+    # future.
     def makeProduct(
         self, name=None, project=None, displayname=None,
         licenses=None, owner=None, registrant=None,
         title=None, summary=None, official_malone=None,
-        official_rosetta=None, bug_supervisor=None):
+        translations_usage=None, bug_supervisor=None):
         """Create and return a new, arbitrary Product."""
         if owner is None:
             owner = self.makePerson()
@@ -837,8 +843,9 @@
             registrant=registrant)
         if official_malone is not None:
             product.official_malone = official_malone
-        if official_rosetta is not None:
-            removeSecurityProxy(product).official_rosetta = official_rosetta
+        if translations_usage is not None:
+            naked_product = removeSecurityProxy(product)
+            naked_product.translations_usage = translations_usage
         if bug_supervisor is not None:
             naked_product = removeSecurityProxy(product)
             naked_product.bug_supervisor = bug_supervisor
@@ -2090,7 +2097,8 @@
             productseries = self.makeProductSeries(owner=owner)
             # Make it use Translations, otherwise there's little point
             # to us creating a template for it.
-            removeSecurityProxy(productseries).product.official_rosetta = True
+            naked_series = removeSecurityProxy(productseries)
+            naked_series.product.translations_usage = ServiceUsage.LAUNCHPAD
         templateset = getUtility(IPOTemplateSet)
         subset = templateset.getSubset(
             distroseries, sourcepackagename, productseries)

=== modified file 'lib/lp/translations/browser/potemplate.py'
--- lib/lp/translations/browser/potemplate.py	2010-08-24 12:22:28 +0000
+++ lib/lp/translations/browser/potemplate.py	2010-08-31 18:18:46 +0000
@@ -61,6 +61,7 @@
 from canonical.launchpad.webapp.launchpadform import ReturnToReferrerMixin
 from canonical.launchpad.webapp.menu import structured
 from canonical.lazr.utils import smartquote
+from lp.app.enums import service_uses_launchpad
 from lp.app.errors import NotFoundError
 from lp.registry.browser.productseries import ProductSeriesFacets
 from lp.registry.browser.sourcepackage import SourcePackageFacets
@@ -794,9 +795,10 @@
             product_or_distro = potemplate.productseries.product
         else:
             product_or_distro = potemplate.distroseries.distribution
-        official_rosetta = product_or_distro.official_rosetta
+        translations_usage = product_or_distro.translations_usage
 
-        if official_rosetta and potemplate.iscurrent:
+        if (service_uses_launchpad(translations_usage) and
+           potemplate.iscurrent):
             # This template is available for translation.
             return potemplate
         elif check_permission('launchpad.Edit', potemplate):

=== modified file 'lib/lp/translations/browser/product.py'
--- lib/lp/translations/browser/product.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/browser/product.py	2010-08-31 18:18:46 +0000
@@ -20,6 +20,7 @@
     )
 from canonical.launchpad.webapp.authorization import check_permission
 from canonical.launchpad.webapp.menu import NavigationMenu
+from lp.app.enums import service_uses_launchpad
 from lp.registry.browser.product import ProductEditView
 from lp.registry.interfaces.product import IProduct
 from lp.registry.interfaces.productseries import IProductSeries
@@ -51,12 +52,14 @@
     def translationdownload(self):
         text = 'Download'
         preferred_series = self.context.primary_translatable
-        enabled = (self.context.official_rosetta and
-            preferred_series is not None)
+        enabled = (service_uses_launchpad(self.context.translations_usage)
+            and preferred_series is not None)
         link = ''
         if enabled:
             link = canonical_url(
-                preferred_series, rootsite='translations', view_name='+export')
+                preferred_series,
+                rootsite='translations',
+                view_name='+export')
             text = 'Download "%s"' % preferred_series.name
 
         return Link(link, text, icon='download', enabled=enabled)
@@ -90,19 +93,19 @@
     @cachedproperty
     def uses_translations(self):
         """Whether this product has translatable templates."""
-        return (self.context.official_rosetta and
-                self.primary_translatable is not None)
+        return (service_uses_launchpad(self.context.translations_usage)
+                and self.primary_translatable is not None)
 
     @cachedproperty
     def no_translations_available(self):
         """Has no translation templates but does support translations."""
-        return (self.context.official_rosetta and
-                self.primary_translatable is None)
+        return (service_uses_launchpad(self.context.translations_usage)
+                and self.primary_translatable is None)
 
     @cachedproperty
     def show_page_content(self):
         """Whether the main content of the page should be shown."""
-        return (self.context.official_rosetta or
+        return (service_uses_launchpad(self.context.translations_usage) or
                 check_permission("launchpad.TranslationsAdmin", self.context))
 
     @cachedproperty

=== modified file 'lib/lp/translations/browser/tests/language-views.txt'
--- lib/lp/translations/browser/tests/language-views.txt	2010-07-16 16:51:52 +0000
+++ lib/lp/translations/browser/tests/language-views.txt	2010-08-31 18:18:46 +0000
@@ -143,7 +143,10 @@
 
 Create a product, a template with one msgset and a pofile
 
-    >>> product = factory.makeProduct(official_rosetta=True)
+    >>> from lp.app.enums import ServiceUsage
+
+    >>> product = factory.makeProduct(
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> template = factory.makePOTemplate(
     ...     productseries=product.getSeries('trunk'))
     >>> potmsgset = factory.makePOTMsgSet(template)

=== modified file 'lib/lp/translations/doc/potmsgset.txt'
--- lib/lp/translations/doc/potmsgset.txt	2010-08-06 06:51:37 +0000
+++ lib/lp/translations/doc/potmsgset.txt	2010-08-31 18:18:46 +0000
@@ -690,10 +690,10 @@
 
 Both, product and distribution use Launchpad Translations.
 
-    >>> evolution.official_rosetta
-    True
-    >>> ubuntu.official_rosetta
-    True
+    >>> evolution.translations_usage.name
+    'LAUNCHPAD'
+    >>> ubuntu.translations_usage.name
+    'LAUNCHPAD'
 
 And both translation templates are current
 
@@ -752,7 +752,9 @@
 The same happens if the distribution is not officially using
 translations.
 
-    >>> ubuntu.official_rosetta = False
+    >>> from lp.app.enums import ServiceUsage
+
+    >>> ubuntu.translations_usage = ServiceUsage.NOT_APPLICABLE
 
     # We set the template as current again so we are sure that we don't show
     # suggestions just due to the change to the official_rosetta flag.
@@ -765,7 +767,7 @@
 
 And products not using translations officially have the same behaviour.
 
-    >>> evolution.official_rosetta = False
+    >>> evolution.translations_usage = ServiceUsage.NOT_APPLICABLE
     >>> transaction.commit()
     >>> suggestions = evo_distro_message.getExternallyUsedTranslationMessages(
     ...    spanish)
@@ -774,8 +776,8 @@
 
 Let's restore the flags for next section.
 
-    >>> ubuntu.official_rosetta = True
-    >>> evolution.official_rosetta = True
+    >>> ubuntu.translations_usage = ServiceUsage.LAUNCHPAD
+    >>> evolution.translations_usage = ServiceUsage.LAUNCHPAD
     >>> transaction.commit()
 
 
@@ -874,7 +876,7 @@
     # We set the template as current again so we are sure that we don't show
     # suggestions just due to the change to the official_rosetta flag.
     >>> potmsgset_translated.potemplate.iscurrent = True
-    >>> ubuntu.official_rosetta = False
+    >>> ubuntu.translations_usage = ServiceUsage.NOT_APPLICABLE
     >>> transaction.commit()
 
     >>> wiki_submissions = (

=== modified file 'lib/lp/translations/doc/translationimportqueue.txt'
--- lib/lp/translations/doc/translationimportqueue.txt	2010-07-13 21:49:34 +0000
+++ lib/lp/translations/doc/translationimportqueue.txt	2010-08-31 18:18:46 +0000
@@ -1523,9 +1523,11 @@
 
 A user sets up Jokosher for translation, and uploads a template.
 
+    >>> from lp.app.enums import ServiceUsage
+
     >>> jokosher = productset['jokosher']
     >>> jokosher_trunk = jokosher.getSeries('trunk')
-    >>> jokosher.official_rosetta = True
+    >>> jokosher.translations_usage = ServiceUsage.LAUNCHPAD
     >>> syncUpdate(jokosher)
     >>> jokosher_subset = potemplateset.getSubset(productseries=jokosher_trunk)
     >>> template = jokosher_subset.new(

=== modified file 'lib/lp/translations/doc/translationmessage-destroy.txt'
--- lib/lp/translations/doc/translationmessage-destroy.txt	2009-07-02 17:16:50 +0000
+++ lib/lp/translations/doc/translationmessage-destroy.txt	2010-08-31 18:18:46 +0000
@@ -35,16 +35,17 @@
     >>> # a global 'postgres' permission which allows everything.
     >>> LaunchpadZopelessLayer.switchDbUser('postgres')
     >>> from canonical.database.sqlbase import sqlvalues
+    >>> from lp.app.enums import ServiceUsage
     >>> from lp.translations.model.pofiletranslator import POFileTranslator
     >>> from lp.testing.factory import LaunchpadObjectFactory
     >>> factory = LaunchpadObjectFactory()
 
-    >>> foo = factory.makeProduct()
+    >>> foo = factory.makeProduct(
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> foo_devel = factory.makeProductSeries(
     ...     name='devel', product=foo)
     >>> foo_stable = factory.makeProductSeries(
     ...     name='stable', product=foo)
-    >>> foo.official_rosetta = True
     >>> devel_potemplate = factory.makePOTemplate(
     ...     productseries=foo_devel, name="messages")
     >>> stable_potemplate = factory.makePOTemplate(foo_stable,

=== modified file 'lib/lp/translations/doc/translations-export-to-branch.txt'
--- lib/lp/translations/doc/translations-export-to-branch.txt	2010-07-20 17:50:45 +0000
+++ lib/lp/translations/doc/translations-export-to-branch.txt	2010-08-31 18:18:46 +0000
@@ -76,10 +76,11 @@
 branch.
 
     >>> from zope.security.proxy import removeSecurityProxy
+    >>> from lp.app.enums import ServiceUsage
 
     >>> gazblachko = removeSecurityProxy(factory.makeProduct(
     ...     name='gazblachko', displayname='Gazblachko'))
-    >>> gazblachko.official_rosetta = True
+    >>> gazblachko.translations_usage = ServiceUsage.LAUNCHPAD
 
     >>> branch = removeSecurityProxy(factory.makeBranch(
     ...     name='gazpo', owner=gazblachko.owner, product=gazblachko))
@@ -162,13 +163,13 @@
 When Gazblachko stops using Launchpad for Translations, the exports stop
 also.
 
-    >>> gazblachko.official_rosetta = False
+    >>> gazblachko.translations_usage = ServiceUsage.NOT_APPLICABLE
     >>> transaction.commit()
     >>> script.main()
     INFO Exporting to translations branches.
     INFO Processed 0 item(s); 0 failure(s), 0 unpushed branch(es).
 
-    >>> gazblachko.official_rosetta = True
+    >>> gazblachko.translations_usage = ServiceUsage.LAUNCHPAD
     >>> transaction.commit()
 
 

=== modified file 'lib/lp/translations/doc/translationsoverview.txt'
--- lib/lp/translations/doc/translationsoverview.txt	2009-07-24 12:55:03 +0000
+++ lib/lp/translations/doc/translationsoverview.txt	2010-08-31 18:18:46 +0000
@@ -104,10 +104,13 @@
 
 Adding a little bit of karma to upstart will put it in the list as well.
 
+    >>> from lp.app.enums import ServiceUsage
+
     >>> start_karma_update()
     >>> upstart = product_set.getByName('upstart')
     >>> upstart_id = upstart.id
-    >>> removeSecurityProxy(upstart).official_rosetta = True
+    >>> naked_upstart = removeSecurityProxy(upstart)
+    >>> naked_upstart.translations_usage = ServiceUsage.LAUNCHPAD
     >>> cache_entry = karmacachemanager.new(
     ...     50, carlos.id, translations.id, product_id=upstart_id)
     >>> finish_karma_update()

=== modified file 'lib/lp/translations/model/potemplate.py'
--- lib/lp/translations/model/potemplate.py	2010-08-24 21:02:12 +0000
+++ lib/lp/translations/model/potemplate.py	2010-08-31 18:18:46 +0000
@@ -65,6 +65,7 @@
     IMasterStore,
     IStore,
     )
+from lp.app.enums import service_uses_launchpad
 from lp.app.errors import NotFoundError
 from lp.registry.interfaces.person import validate_public_person
 from lp.registry.model.sourcepackagename import SourcePackageName
@@ -1322,8 +1323,7 @@
             preferred_matches = [
                 match
                 for match in matches
-                if match.from_sourcepackagename == sourcepackagename
-            ]
+                if match.from_sourcepackagename == sourcepackagename]
 
             if len(preferred_matches) == 1:
                 return preferred_matches[0]
@@ -1378,6 +1378,9 @@
 
     def populateSuggestivePOTemplatesCache(self):
         """See `IPOTemplateSet`."""
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this sql needs to be updated to check for the
+        # translations_usage, not official_rosetta.
         return IMasterStore(POTemplate).execute("""
             INSERT INTO SuggestivePOTemplate (
                 SELECT POTemplate.id
@@ -1437,15 +1440,13 @@
         if self.product:
             subsets = [
                 self.potemplateset.getSubset(productseries=series)
-                for series in self.product.series
-                ]
+                for series in self.product.series]
         else:
             subsets = [
                 self.potemplateset.getSubset(
                     distroseries=series,
                     sourcepackagename=self.sourcepackagename)
-                for series in self.distribution.series
-                ]
+                for series in self.distribution.series]
         for subset in subsets:
             for template in subset:
                 if name_pattern is None or re.match(name_pattern,
@@ -1548,8 +1549,7 @@
                 msgset.flags = set([
                     flag.strip()
                     for flag in row.flags_comment.split(',')
-                    if flag
-                    ])
+                    if flag])
 
             # Store the message.
             messages.append(msgset)
@@ -1578,8 +1578,9 @@
         collection = self.getTemplatesCollection()
 
         # XXX JeroenVermeulen 2010-07-15 bug=605924: Move the
-        # official_rosetta distinction into browser code.
-        if collection.target_pillar.official_rosetta:
+        # translations_usage distinction into browser code.
+        pillar = collection.target_pillar
+        if service_uses_launchpad(pillar.translations_usage):
             return collection.restrictCurrent(current_value)
         else:
             # Product/Distribution does not have translation enabled.

=== modified file 'lib/lp/translations/model/potmsgset.py'
--- lib/lp/translations/model/potmsgset.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/model/potmsgset.py	2010-08-31 18:18:46 +0000
@@ -361,6 +361,9 @@
             query = ["(NOT %s)" % in_use_clause]
         query.append('TranslationMessage.language = %s' % sqlvalues(language))
 
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this sql needs to be updated to check for the
+        # translations_usage, not official_rosetta.
         query.append('''
             potmsgset IN (
                 SELECT POTMsgSet.id
@@ -381,7 +384,8 @@
                     POTMsgSet.id <> %s AND
                     msgid_singular = %s AND
                     POTemplate.iscurrent AND
-                    (Product.official_rosetta OR Distribution.official_rosetta)
+                    (Product.official_rosetta OR
+                        Distribution.official_rosetta)
             )''' % sqlvalues(self, self.msgid_singular))
 
         # Subquery to find the ids of TranslationMessages that are
@@ -396,8 +400,8 @@
             for form in xrange(TranslationConstants.MAX_PLURAL_FORMS)])
         ids_query_params = {
             'msgstrs': msgstrs,
-            'where': ' AND '.join(query)
-        }
+            'where': ' AND '.join(query),
+            }
         ids_query = '''
             SELECT DISTINCT ON (%(msgstrs)s)
                 TranslationMessage.id
@@ -565,8 +569,7 @@
         # plural forms.
         order.extend([
             'msgstr%s NULLS FIRST' % quote(form)
-            for form in remaining_plural_forms
-            ])
+            for form in remaining_plural_forms])
         matches = list(
             TranslationMessage.select(' AND '.join(clauses), orderBy=order))
 
@@ -722,7 +725,6 @@
         if is_imported or new_message == imported_message:
             new_message.is_imported = True
 
-
     def _isTranslationMessageASuggestion(self, force_suggestion,
                                          pofile, submitter,
                                          force_edition_rights, is_imported,
@@ -1177,4 +1179,3 @@
         """See `IPOTMsgSet`."""
         return TranslationTemplateItem.selectBy(
             potmsgset=self, orderBy=['id'])
-

=== modified file 'lib/lp/translations/model/translationsoverview.py'
--- lib/lp/translations/model/translationsoverview.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/model/translationsoverview.py	2010-08-31 18:18:46 +0000
@@ -39,13 +39,15 @@
             new_size = int(round(
                 real_minimum +
                 (size - offset - real_minimum) * multiplier))
-            normalized_sizes.append({'pillar' : pillar,
-                                     'weight' : new_size })
+            normalized_sizes.append({'pillar': pillar, 'weight': new_size})
         return normalized_sizes
 
     def getMostTranslatedPillars(self, limit=50):
         """See `ITranslationsOverview`."""
 
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this sql needs to be updated to check for the
+        # translations_usage, not official_rosetta.
         query = """
         SELECT LOWER(COALESCE(product_name, distro_name)) AS name,
                product_id,
@@ -65,7 +67,8 @@
                      distribution=distribution.id
               WHERE category=3 AND
                     (product IS NOT NULL OR distribution IS NOT NULL) AND
-                    (product.official_rosetta OR distribution.official_rosetta)
+                    (product.official_rosetta OR
+                        distribution.official_rosetta)
               GROUP BY product.displayname, product.id,
                        distribution.displayname, distribution.id
               HAVING SUM(karmavalue) > 0

=== modified file 'lib/lp/translations/model/translationsperson.py'
--- lib/lp/translations/model/translationsperson.py	2010-08-27 10:53:40 +0000
+++ lib/lp/translations/model/translationsperson.py	2010-08-31 18:18:46 +0000
@@ -262,6 +262,10 @@
         The added joins may make the overall query non-distinct, so be
         sure to enforce distinctness.
         """
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this query needs to be updated to check for the
+        # translations_usage, not official_rosetta.
+
         POTemplateJoin = Join(POTemplate, And(
             POTemplate.id == POFile.potemplateID,
             POTemplate.iscurrent == True))

=== modified file 'lib/lp/translations/scripts/translations_to_branch.py'
--- lib/lp/translations/scripts/translations_to_branch.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/scripts/translations_to_branch.py	2010-08-31 18:18:46 +0000
@@ -306,6 +306,9 @@
 
         self.store = getUtility(IStoreSelector).get(MAIN_STORE, SLAVE_FLAVOR)
 
+        # XXX j.c.sackett 2010-08-30 Once data migration has happened for the
+        # usage enums, this sql needs to be updated to check for the
+        # translations_usage, not official_rosetta.
         product_join = Join(
             ProductSeries, Product, ProductSeries.product == Product.id)
         productseries = self.store.using(product_join).find(

=== modified file 'lib/lp/translations/stories/buildfarm/xx-build-summary.txt'
--- lib/lp/translations/stories/buildfarm/xx-build-summary.txt	2010-07-20 17:50:45 +0000
+++ lib/lp/translations/stories/buildfarm/xx-build-summary.txt	2010-08-31 18:18:46 +0000
@@ -13,6 +13,7 @@
     >>> from canonical.launchpad.interfaces.librarian import (
     ...     ILibraryFileAliasSet)
     >>> from canonical.launchpad.scripts.logger import QuietFakeLogger
+    >>> from lp.app.enums import ServiceUsage
     >>> from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
     >>> from lp.testing.factory import (
     ...     remove_security_proxy_and_shout_at_engineer)
@@ -32,7 +33,7 @@
     >>> productseries = factory.makeProductSeries(owner=owner)
     >>> product = productseries.product
     >>> naked_product = remove_security_proxy_and_shout_at_engineer(product)
-    >>> naked_product.official_rosetta = True
+    >>> naked_product.translations_usage = ServiceUsage.LAUNCHPAD
     >>> branch = factory.makeProductBranch(product=product, owner=owner)
     >>> branch_url = branch.unique_name
 

=== modified file 'lib/lp/translations/stories/importqueue/xx-entry-details.txt'
--- lib/lp/translations/stories/importqueue/xx-entry-details.txt	2010-03-11 20:54:36 +0000
+++ lib/lp/translations/stories/importqueue/xx-entry-details.txt	2010-08-31 18:18:46 +0000
@@ -4,6 +4,7 @@
 entry and its target that may be helpful in queue review.
 
     >>> from zope.security.proxy import removeSecurityProxy
+    >>> from lp.app.enums import ServiceUsage
     >>> from lp.translations.model.translationimportqueue import (
     ...     TranslationImportQueue)
 
@@ -11,8 +12,8 @@
 
     >>> login(ANONYMOUS)
     >>> queue = TranslationImportQueue()
-    >>> product = factory.makeProduct()
-    >>> removeSecurityProxy(product).official_rosetta = True
+    >>> product = factory.makeProduct(
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> trunk = product.getSeries('trunk')
     >>> uploader = factory.makePerson()
     >>> entry = queue.addOrUpdateEntry(

=== modified file 'lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt'
--- lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt	2009-09-02 16:35:54 +0000
+++ lib/lp/translations/stories/productseries/xx-productseries-export-to-branch.txt	2010-08-31 18:18:46 +0000
@@ -5,11 +5,12 @@
 branch.
 
     >>> from zope.security.proxy import removeSecurityProxy
+    >>> from lp.app.enums import ServiceUsage
 
     >>> login(ANONYMOUS)
     >>> owner = factory.makePerson(email='x@xxxxxxxxxxx', password='****')
-    >>> product = factory.makeProduct(owner=owner)
-    >>> removeSecurityProxy(product).official_rosetta = True
+    >>> product = factory.makeProduct(owner=owner,
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> productseries = product.getSeries('trunk')
     >>> branch = factory.makeBranch(product=product, owner=owner)
     >>> branch_name = branch.name

=== modified file 'lib/lp/translations/stories/productseries/xx-productseries-translations.txt'
--- lib/lp/translations/stories/productseries/xx-productseries-translations.txt	2010-03-31 20:25:33 +0000
+++ lib/lp/translations/stories/productseries/xx-productseries-translations.txt	2010-08-31 18:18:46 +0000
@@ -5,9 +5,10 @@
 a single product series, or instructions on how to set up a series for
 translation.
 
+    >>> from lp.app.enums import ServiceUsage
     >>> login('foo.bar@xxxxxxxxxxxxx')
-    >>> frobnicator = factory.makeProduct(name='frobnicator')
-    >>> frobnicator.official_rosetta = True
+    >>> frobnicator = factory.makeProduct(name='frobnicator',
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> frobnicator_trunk = frobnicator.getSeries('trunk')
     >>> frobnicator_trunk_url = canonical_url(
     ...     frobnicator_trunk, rootsite='translations')
@@ -148,7 +149,8 @@
 
     # Use the raw DB object to bypass the security proxy.
     >>> from lp.registry.model.product import Product
-    >>> Product.byName('bazaar').official_rosetta = False
+    >>> product = Product.byName('bazaar')
+    >>> product.translations_usage = ServiceUsage.NOT_APPLICABLE
 
 When the owner now visits the upload page for trunk, there's a notice.
 

=== modified file 'lib/lp/translations/stories/standalone/custom-language-codes.txt'
--- lib/lp/translations/stories/standalone/custom-language-codes.txt	2010-03-11 20:54:36 +0000
+++ lib/lp/translations/stories/standalone/custom-language-codes.txt	2010-08-31 18:18:46 +0000
@@ -16,6 +16,7 @@
     >>> from zope.security.proxy import removeSecurityProxy
     >>> from canonical.launchpad.interfaces.launchpad import (
     ...     ILaunchpadCelebrities)
+    >>> from lp.app.enums import ServiceUsage
 
     >>> def find_custom_language_codes_link(browser):
     ...     """Find reference to custom language codes on a page."""
@@ -29,7 +30,8 @@
     ...     getUtility(ILaunchpadCelebrities).rosetta_experts)
     >>> product = factory.makeProduct(displayname="Foo", owner=owner)
     >>> trunk = product.getSeries('trunk')
-    >>> removeSecurityProxy(product).official_rosetta = True
+    >>> naked_product = removeSecurityProxy(product) 
+    >>> naked_product.translations_usage = ServiceUsage.LAUNCHPAD
     >>> template = factory.makePOTemplate(productseries=trunk)
     >>> product_page = canonical_url(product, rootsite='translations')
     >>> logout()
@@ -198,7 +200,8 @@
     >>> sourcepackagename = SourcePackageName(name='bar')
     >>> package = factory.makeSourcePackage(
     ...     sourcepackagename=sourcepackagename, distroseries=distroseries)
-    >>> removeSecurityProxy(distro).official_rosetta = True
+    >>> naked_distro = removeSecurityProxy(distro)
+    >>> naked_distro.translations_usage = ServiceUsage.LAUNCHPAD
     >>> other_series = factory.makeDistroRelease(distribution=distro)
     >>> template = factory.makePOTemplate(
     ...     distroseries=package.distroseries,

=== modified file 'lib/lp/translations/stories/standalone/xx-potemplate-index.txt'
--- lib/lp/translations/stories/standalone/xx-potemplate-index.txt	2010-02-16 21:21:14 +0000
+++ lib/lp/translations/stories/standalone/xx-potemplate-index.txt	2010-08-31 18:18:46 +0000
@@ -212,8 +212,10 @@
     >>> from zope.component import getUtility
     >>> from canonical.launchpad.interfaces.launchpad import (
     ...     ILaunchpadCelebrities)
+    >>> from lp.app.enums import ServiceUsage
     >>> login('admin@xxxxxxxxxxxxx')
-    >>> product = factory.makeProduct(name="fusa", official_rosetta=True)
+    >>> product = factory.makeProduct(name="fusa", 
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> product_trunk = product.getSeries('trunk')
     >>> template = factory.makePOTemplate(
     ...     productseries=product_trunk, name='first')

=== modified file 'lib/lp/translations/stories/standalone/xx-product-export.txt'
--- lib/lp/translations/stories/standalone/xx-product-export.txt	2009-09-18 15:42:19 +0000
+++ lib/lp/translations/stories/standalone/xx-product-export.txt	2010-08-31 18:18:46 +0000
@@ -40,9 +40,10 @@
 
     # Use the DB classes directly to avoid having to setup a zope interaction
     # (i.e. login()) and bypass the security proxy.
+    >>> from lp.app.enums import ServiceUsage
     >>> from lp.registry.model.product import Product
     >>> product = Product.byName('evolution')
-    >>> product.official_rosetta = False
+    >>> product.translations_usage = ServiceUsage.NOT_APPLICABLE
     >>> product.sync()
     >>> user_browser.open('http://translations.launchpad.dev/evolution')
     >>> user_browser.getLink('download')
@@ -51,7 +52,7 @@
     LinkNotFoundError
 
     >>> # Restore previous state for subsequent tests, and verify
-    >>> product.official_rosetta = True
+    >>> product.translations_usage = ServiceUsage.LAUNCHPAD
     >>> product.sync()
     >>> user_browser.open('http://translations.launchpad.dev/evolution')
     >>> user_browser.getLink('download') is not None

=== modified file 'lib/lp/translations/stories/standalone/xx-template-description-escaping.txt'
--- lib/lp/translations/stories/standalone/xx-template-description-escaping.txt	2009-09-14 15:41:21 +0000
+++ lib/lp/translations/stories/standalone/xx-template-description-escaping.txt	2010-08-31 18:18:46 +0000
@@ -1,12 +1,14 @@
     >>> import re
     >>> from zope.security.proxy import removeSecurityProxy
+    >>> from lp.app.enums import ServiceUsage
 
     >>> login('foo.bar@xxxxxxxxxxxxx')
     >>> package = factory.makeSourcePackage()
     >>> template = removeSecurityProxy(factory.makePOTemplate(
     ...     distroseries=package.distroseries,
     ...     sourcepackagename=package.sourcepackagename))
-    >>> template.distroseries.distribution.official_rosetta = True
+    >>> distribution = template.distroseries.distribution
+    >>> distribution.translations_usage = ServiceUsage.LAUNCHPAD
     >>> template.distroseries.hide_all_translations = False
     >>> template.description = "See http://example.com/ for an example!"
     >>> package_url = canonical_url(package, rootsite='translations')

=== modified file 'lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt'
--- lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt	2010-01-20 20:21:42 +0000
+++ lib/lp/translations/stories/translationfocus/xx-product-translationfocus.txt	2010-08-31 18:18:46 +0000
@@ -1,9 +1,10 @@
 The translation focus of a product can be explicitly set to a specific series.
 When not set, launchpad recommends the development focus to translate.
 
+    >>> from lp.app.enums import ServiceUsage
     >>> login('admin@xxxxxxxxxxxxx')
     >>> fooproject = factory.makeProduct(name="fooproject")
-    >>> fooproject.official_rosetta = True
+    >>> fooproject.translations_usage = ServiceUsage.LAUNCHPAD
     >>> fooproject_trunk = fooproject.getSeries("trunk")
     >>> fooproject_url = canonical_url(
     ...     fooproject, rootsite="translations")

=== modified file 'lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt'
--- lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt	2010-02-16 21:21:14 +0000
+++ lib/lp/translations/stories/translationgroups/xx-change-translation-policy.txt	2010-08-31 18:18:46 +0000
@@ -4,11 +4,15 @@
 A product owner, Rosetta expert, and Ubuntu translations coordinator
 browser is created.
 
+    >>> from lp.app.enums import ServiceUsage
+
     >>> login('admin@xxxxxxxxxxxxx')
     >>> product_owner = factory.makePerson(
     ...     email="po@xxxxxx", password="test")
     >>> chestii = factory.makeProduct(
-    ...     name='chestii', owner=product_owner, official_rosetta=True)
+    ...     name='chestii',
+    ...     owner=product_owner,
+    ...     translations_usage=ServiceUsage.LAUNCHPAD)
     >>> logout()
     >>> dtc_browser = setupDTCBrowser()
     >>> re_browser = setupRosettaExpertBrowser()

=== modified file 'lib/lp/translations/templates/product-portlet-not-using-launchpad.pt'
--- lib/lp/translations/templates/product-portlet-not-using-launchpad.pt	2010-03-15 20:17:21 +0000
+++ lib/lp/translations/templates/product-portlet-not-using-launchpad.pt	2010-08-31 18:18:46 +0000
@@ -5,7 +5,7 @@
   omit-tag="">
 
     <div id="not-translated-in-launchpad"
-         tal:condition="not: context/official_rosetta">
+         tal:condition="not: context/translations_usage/enumvalue:LAUNCHPAD">
       <strong>
         This project is not using Launchpad for translations.
       </strong>

=== modified file 'lib/lp/translations/templates/productseries-translations.pt'
--- lib/lp/translations/templates/productseries-translations.pt	2009-12-16 15:21:36 +0000
+++ lib/lp/translations/templates/productseries-translations.pt	2010-08-31 18:18:46 +0000
@@ -30,7 +30,7 @@
           <a href="https://help.launchpad.net/Translations/YourProject";>start
             translating your project</a>,
           <tal:uses-translations condition="not:
-                                            context/product/official_rosetta">
+                    context/product/translations_usage/enumvalue:LAUNCHPAD">
             you should enable translations in your project settings, and
           </tal:uses-translations>
           you can either

=== modified file 'lib/lp/translations/tests/test_autoapproval.py'
--- lib/lp/translations/tests/test_autoapproval.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_autoapproval.py	2010-08-31 18:18:46 +0000
@@ -23,6 +23,7 @@
 from canonical.launchpad.interfaces.lpstorm import IMasterStore
 from canonical.launchpad.webapp.testing import verifyObject
 from canonical.testing import LaunchpadZopelessLayer
+from lp.app.enums import ServiceUsage
 from lp.registry.interfaces.series import SeriesStatus
 from lp.registry.model.distribution import Distribution
 from lp.registry.model.sourcepackagename import (
@@ -714,8 +715,8 @@
         # _get_pofile_from_language will find an enabled template, and
         # return either an existing POFile for the given language, or a
         # newly created one.
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         trunk = product.getSeries('trunk')
         template = self.factory.makePOTemplate(
             productseries=trunk, translation_domain='domain')
@@ -732,8 +733,8 @@
         # _get_pofile_from_language will not consider a disabled
         # template as an auto-approval target, and so will not return a
         # POFile for it.
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         trunk = product.getSeries('trunk')
         template = self.factory.makePOTemplate(
             productseries=trunk, translation_domain='domain')
@@ -750,8 +751,8 @@
         # When the template has translation credits, a new dummy translation
         # is created in the new POFile. Since this is running with gardener
         # privileges, we need to check that this works, too.
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         trunk = product.getSeries('trunk')
         template = self.factory.makePOTemplate(
             productseries=trunk, translation_domain='domain')
@@ -778,8 +779,8 @@
 
     def _makeProductEntry(self, path='foo.pot', status=None):
         """Simulate upload for a product."""
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         trunk = product.getSeries('trunk')
         entry = self.queue.addOrUpdateEntry(
             path, '# contents', False, product.owner, productseries=trunk)

=== modified file 'lib/lp/translations/tests/test_empty_messages.py'
--- lib/lp/translations/tests/test_empty_messages.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_empty_messages.py	2010-08-31 18:18:46 +0000
@@ -4,17 +4,17 @@
 __metaclass__ = type
 
 from datetime import datetime
-import unittest
 
 from pytz import timezone
 from zope.component import getUtility
 
 from canonical.testing import LaunchpadZopelessLayer
+from lp.app.enums import ServiceUsage
 from lp.services.worlddata.interfaces.language import ILanguageSet
-from lp.testing.factory import LaunchpadObjectFactory
-
-
-class TestTranslationEmptyMessages(unittest.TestCase):
+from lp.testing import TestCaseWithFactory
+
+
+class TestTranslationEmptyMessages(TestCaseWithFactory):
     """Test behaviour of empty translation messages."""
 
     layer = LaunchpadZopelessLayer
@@ -23,13 +23,15 @@
         """Set up context to test in."""
         # Pretend we have a product being translated to Serbian.
         # This is where we are going to be importing translations to.
-        factory = LaunchpadObjectFactory()
-        self.factory = factory
-        self.productseries = factory.makeProductSeries()
-        self.productseries.product.official_rosetta = True
-        self.potemplate = factory.makePOTemplate(self.productseries)
+        super(TestTranslationEmptyMessages, self).setUp()
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
+        self.productseries = self.factory.makeProductSeries(product=product)
+        self.potemplate = self.factory.makePOTemplate(self.productseries)
         self.serbian = getUtility(ILanguageSet).getLanguageByCode('sr')
-        self.pofile_sr = factory.makePOFile('sr', potemplate=self.potemplate)
+        self.pofile_sr = self.factory.makePOFile(
+            'sr',
+            potemplate=self.potemplate)
         self.now = datetime.now(timezone('UTC'))
 
     def test_NoEmptyImporedTranslation(self):

=== modified file 'lib/lp/translations/tests/test_hastranslationtemplates.py'
--- lib/lp/translations/tests/test_hastranslationtemplates.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_hastranslationtemplates.py	2010-08-31 18:18:46 +0000
@@ -6,6 +6,7 @@
 from zope.interface.verify import verifyObject
 
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.testing import TestCaseWithFactory
 from lp.translations.interfaces.potemplate import IHasTranslationTemplates
 from lp.translations.interfaces.translationfileformat import (
@@ -152,7 +153,7 @@
 
         # A product or distribution that doesn't use Launchpad for
         # translations has no current templates.
-        self.product_or_distro.official_rosetta = False
+        self.product_or_distro.translations_usage = ServiceUsage.EXTERNAL
         self.assertFalse(self.container.has_current_translation_templates)
 
     def test_getTranslationTemplateFormats(self):
@@ -205,7 +206,7 @@
         super(TestProductSeriesHasTranslationTemplates, self).setUp()
         self.container = self.factory.makeProductSeries()
         self.product_or_distro = self.container.product
-        self.product_or_distro.official_rosetta = True
+        self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD
 
 
 class TestSourcePackageHasTranslationTemplates(
@@ -223,7 +224,7 @@
         super(TestSourcePackageHasTranslationTemplates, self).setUp()
         self.container = self.factory.makeSourcePackage()
         self.product_or_distro = self.container.distroseries.distribution
-        self.product_or_distro.official_rosetta = True
+        self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD
 
 
 class TestDistroSeriesHasTranslationTemplates(
@@ -243,4 +244,4 @@
         super(TestDistroSeriesHasTranslationTemplates, self).setUp()
         self.container = self.factory.makeDistroRelease()
         self.product_or_distro = self.container.distribution
-        self.product_or_distro.official_rosetta = True
+        self.product_or_distro.translations_usage = ServiceUsage.LAUNCHPAD

=== modified file 'lib/lp/translations/tests/test_pofile.py'
--- lib/lp/translations/tests/test_pofile.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_pofile.py	2010-08-31 18:18:46 +0000
@@ -24,6 +24,7 @@
     LaunchpadZopelessLayer,
     ZopelessDatabaseLayer,
     )
+from lp.app.enums import ServiceUsage
 from lp.testing import TestCaseWithFactory
 from lp.translations.interfaces.pofile import IPOFileSet
 from lp.translations.interfaces.translatablemessage import (
@@ -46,12 +47,13 @@
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
         super(TestTranslationSharedPOFile, self).setUp()
-        self.foo = self.factory.makeProduct(name='foo')
+        self.foo = self.factory.makeProduct(
+            name='foo',
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
             name='devel', product=self.foo)
         self.foo_stable = self.factory.makeProductSeries(
             name='stable', product=self.foo)
-        self.foo.official_rosetta = True
 
         # POTemplate is 'shared' if it has the same name ('messages').
         self.devel_potemplate = self.factory.makePOTemplate(
@@ -76,7 +78,8 @@
             'http://translations.launchpad.dev/foo/devel/+pots/messages/sr',
             canonical_url(self.devel_sr_pofile))
         self.assertEqual(
-            'http://translations.launchpad.dev/foo/devel/+pots/messages/sr/+details',
+            ('http://translations.launchpad.dev/'
+            'foo/devel/+pots/messages/sr/+details'),
             canonical_url(self.devel_sr_pofile, view_name="+details"))
 
     def test_findPOTMsgSetsContaining(self):
@@ -879,12 +882,12 @@
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
         super(TestSharedPOFileCreation, self).setUp()
-        self.foo = self.factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
             name='devel', product=self.foo)
         self.foo_stable = self.factory.makeProductSeries(
             name='stable', product=self.foo)
-        self.foo.official_rosetta = True
 
     def test_pofile_creation_shared(self):
         # When a pofile is created in a POTemplate it is also created in
@@ -1009,12 +1012,12 @@
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
         super(TestTranslationPOFilePOTMsgSetOrdering, self).setUp()
-        self.foo = self.factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
             name='devel', product=self.foo)
         self.foo_stable = self.factory.makeProductSeries(
             name='stable', product=self.foo)
-        self.foo.official_rosetta = True
 
         # POTemplate is 'shared' if it has the same name ('messages').
         self.devel_potemplate = self.factory.makePOTemplate(
@@ -1288,8 +1291,8 @@
         # We create a product with two series, and attach
         # a POTemplate and Serbian POFile to each, making
         # sure they share translations (potemplates have the same name).
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         series1 = self.factory.makeProductSeries(product=product,
                                                  name='one')
         series2 = self.factory.makeProductSeries(product=product,
@@ -1324,8 +1327,8 @@
         # This is a test for bug #414832 which caused sharing POFiles
         # of the touched POFile not to be returned if they had
         # IDs smaller than the touched POFile.
-        product = self.factory.makeProduct()
-        product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         series1 = self.factory.makeProductSeries(product=product,
                                                  name='one')
         series2 = self.factory.makeProductSeries(product=product,
@@ -1357,7 +1360,7 @@
         # POFile to each, making sure they share translations
         # (potemplates have the same name).
         distro = self.factory.makeDistribution()
-        distro.official_rosetta = True
+        distro.translations_usage = ServiceUsage.LAUNCHPAD
         series1 = self.factory.makeDistroRelease(distribution=distro,
                                                  name='one')
         sourcepackagename = self.factory.makeSourcePackageName()
@@ -1395,9 +1398,9 @@
         # Make sure POFiles which are in different products
         # are not returned even though they have the same potemplate name.
         series1 = self.factory.makeProductSeries(name='one')
-        series1.product.official_rosetta = True
+        series1.product.translations_usage = ServiceUsage.LAUNCHPAD
         series2 = self.factory.makeProductSeries(name='two')
-        series2.product.official_rosetta = True
+        series1.product.translations_usage = ServiceUsage.LAUNCHPAD
         self.assertNotEqual(series1.product, series2.product)
 
         potemplate1 = self.factory.makePOTemplate(name='shared',

=== modified file 'lib/lp/translations/tests/test_potemplate.py'
--- lib/lp/translations/tests/test_potemplate.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_potemplate.py	2010-08-31 18:18:46 +0000
@@ -7,6 +7,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.testing import DatabaseFunctionalLayer
+from lp.app.enums import ServiceUsage
 from lp.registry.interfaces.distribution import IDistributionSet
 from lp.services.worlddata.interfaces.language import ILanguageSet
 from lp.testing import TestCaseWithFactory
@@ -327,8 +328,8 @@
 
     def setUp(self):
         super(TestTemplatePrecedence, self).setUp(user='mark@xxxxxxxxxxx')
-        self.product = self.factory.makeProduct()
-        self.product.official_rosetta = True
+        self.product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.trunk = self.product.getSeries('trunk')
         self.one_dot_oh = self.factory.makeProductSeries(
             product=self.product, name='one')

=== modified file 'lib/lp/translations/tests/test_potmsgset.py'
--- lib/lp/translations/tests/test_potmsgset.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_potmsgset.py	2010-08-31 18:18:46 +0000
@@ -20,6 +20,7 @@
 
 from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.registry.interfaces.person import IPersonSet
 from lp.registry.interfaces.product import IProductSet
 from lp.services.worlddata.interfaces.language import ILanguageSet
@@ -45,12 +46,12 @@
         # Create a product with two series and a shared POTemplate
         # in different series ('devel' and 'stable').
         super(TestTranslationSharedPOTMsgSets, self).setUp()
-        self.foo = self.factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = self.factory.makeProductSeries(
             name='devel', product=self.foo)
         self.foo_stable = self.factory.makeProductSeries(
             name='stable', product=self.foo)
-        self.foo.official_rosetta = True
 
         # POTemplate is 'shared' if it has the same name ('messages').
         self.devel_potemplate = self.factory.makePOTemplate(
@@ -324,7 +325,8 @@
         # Create an external POTemplate with a POTMsgSet using
         # the same English string as the one in self.potmsgset.
         external_template = self.factory.makePOTemplate()
-        external_template.productseries.product.official_rosetta = True
+        product = external_template.productseries.product
+        product.translations_usage = ServiceUsage.LAUNCHPAD
         external_potmsgset = self.factory.makePOTMsgSet(
             external_template,
             singular=self.potmsgset.singular_text)
@@ -383,7 +385,8 @@
         # Create an external POTemplate with a POTMsgSet using
         # the same English string as the one in self.potmsgset.
         external_template = self.factory.makePOTemplate()
-        external_template.productseries.product.official_rosetta = True
+        product = external_template.productseries.product
+        product.translations_usage = ServiceUsage.LAUNCHPAD
         external_potmsgset = self.factory.makePOTMsgSet(
             external_template,
             singular=self.potmsgset.singular_text)
@@ -738,10 +741,10 @@
         # create TranslationMessage objects.
         super(TestPOTMsgSetSuggestions, self).setUp()
         self.now = self.gen_now().next
-        self.foo = self.factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_main = self.factory.makeProductSeries(
             name='main', product=self.foo)
-        self.foo.official_rosetta = True
 
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.foo_main, name="messages")
@@ -926,10 +929,10 @@
         # create TranslationMessage objects.
         super(TestPOTMsgSetResetTranslation, self).setUp()
         self.now = self.gen_now().next
-        self.foo = self.factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_main = self.factory.makeProductSeries(
             name='main', product=self.foo)
-        self.foo.official_rosetta = True
 
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.foo_main, name="messages")

=== modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
--- lib/lp/translations/tests/test_productserieslanguage.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_productserieslanguage.py	2010-08-31 18:18:46 +0000
@@ -10,6 +10,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.services.worlddata.interfaces.language import ILanguageSet
 from lp.testing import TestCaseWithFactory
 from lp.translations.interfaces.productserieslanguage import (
@@ -26,8 +27,10 @@
     def setUp(self):
         # Create a productseries that uses translations.
         TestCaseWithFactory.setUp(self)
-        self.productseries = self.factory.makeProductSeries()
-        self.productseries.product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
+        self.productseries = self.factory.makeProductSeries(
+            product=product)
 
     def test_no_templates_no_translation(self):
         # There are no templates and no translations.
@@ -125,8 +128,10 @@
     def setUp(self):
         # Create a productseries that uses translations.
         TestCaseWithFactory.setUp(self)
-        self.productseries = self.factory.makeProductSeries()
-        self.productseries.product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
+        self.productseries = self.factory.makeProductSeries(
+            product=product)
         self.psl_set = getUtility(IProductSeriesLanguageSet)
         self.language = getUtility(ILanguageSet).getLanguageByCode('sr')
 

=== modified file 'lib/lp/translations/tests/test_shared_potemplate.py'
--- lib/lp/translations/tests/test_shared_potemplate.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_shared_potemplate.py	2010-08-31 18:18:46 +0000
@@ -10,6 +10,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.testing.factory import LaunchpadObjectFactory
 
 
@@ -24,12 +25,12 @@
         # in different series ('devel' and 'stable').
         factory = LaunchpadObjectFactory()
         self.factory = factory
-        self.foo = factory.makeProduct()
+        self.foo = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.foo_devel = factory.makeProductSeries(
             name='devel', product=self.foo)
         self.foo_stable = factory.makeProductSeries(
             name='stable', product=self.foo)
-        self.foo.official_rosetta = True
 
         # POTemplate is a 'sharing' one if it has the same name ('messages').
         self.devel_potemplate = factory.makePOTemplate(

=== modified file 'lib/lp/translations/tests/test_suggestions.py'
--- lib/lp/translations/tests/test_suggestions.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_suggestions.py	2010-08-31 18:18:46 +0000
@@ -17,6 +17,7 @@
 
 from canonical.config import config
 from canonical.testing import LaunchpadZopelessLayer
+from lp.app.enums import ServiceUsage
 from lp.services.worlddata.interfaces.language import ILanguageSet
 from lp.testing.factory import LaunchpadObjectFactory
 from lp.translations.interfaces.translationmessage import (
@@ -36,10 +37,14 @@
         # suggestions for the other.
         factory = LaunchpadObjectFactory()
         self.factory = factory
-        self.foo_trunk = factory.makeProductSeries()
-        self.bar_trunk = factory.makeProductSeries()
-        self.foo_trunk.product.official_rosetta = True
-        self.bar_trunk.product.official_rosetta = True
+        foo_product = factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
+        bar_product = factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
+        self.foo_trunk = factory.makeProductSeries(
+            product=foo_product)
+        self.bar_trunk = factory.makeProductSeries(
+            product=bar_product)
         self.foo_template = factory.makePOTemplate(self.foo_trunk)
         self.bar_template = factory.makePOTemplate(self.bar_trunk)
         self.nl = getUtility(ILanguageSet).getLanguageByCode('nl')
@@ -222,5 +227,6 @@
                           "TranslationMessage with errors is not correctly"
                           "marked as such in the database.")
 
+
 def test_suite():
     return unittest.TestLoader().loadTestsFromName(__name__)

=== modified file 'lib/lp/translations/tests/test_translatablemessage.py'
--- lib/lp/translations/tests/test_translatablemessage.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_translatablemessage.py	2010-08-31 18:18:46 +0000
@@ -15,6 +15,7 @@
 import transaction
 
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.testing import TestCaseWithFactory
 from lp.translations.model.translatablemessage import TranslatableMessage
 
@@ -31,8 +32,8 @@
         `POTMsgSet`, as well as a Esperanto translation.
         """
         super(TestTranslatableMessageBase, self).setUp()
-        self.product = self.factory.makeProduct()
-        self.product.official_rosetta = True
+        self.product = self.factory.makeProduct(
+            translations_usage=ServiceUsage.LAUNCHPAD)
         self.trunk = self.product.getSeries('trunk')
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.trunk)
@@ -137,7 +138,8 @@
         super(TestTranslatableMessageExternal, self).setUp()
         common_msgid = self.potmsgset.singular_text
         self.external_potemplate = self.factory.makePOTemplate()
-        self.external_potemplate.productseries.product.official_rosetta = True
+        product = self.external_potemplate.productseries.product
+        product.translations_usage = ServiceUsage.LAUNCHPAD
         self.external_potmsgset = self.factory.makePOTMsgSet(
             potemplate=self.external_potemplate,
             singular=common_msgid, sequence=1)
@@ -175,24 +177,24 @@
         super(TestTranslatableMessageSuggestions, self).setUp()
         self.now = self.gen_now().next
         self.suggestion1 = self._createTranslation(date_updated=self.now())
-        self.current =  self._createTranslation(is_current=True,
+        self.current = self._createTranslation(is_current=True,
                                                 date_updated=self.now())
         self.suggestion2 = self._createTranslation(date_updated=self.now())
         self.message = TranslatableMessage(self.potmsgset, self.pofile)
 
     def test_getAllSuggestions(self):
-        # There are three different methods to return 
+        # There are three different methods to return
         suggestions = self.message.getAllSuggestions()
         self.assertContentEqual([self.suggestion1, self.suggestion2],
                                 suggestions)
 
     def test_getDismissedSuggestions(self):
-        # There are three different methods to return 
+        # There are three different methods to return
         suggestions = self.message.getDismissedSuggestions()
         self.assertContentEqual([self.suggestion1], suggestions)
 
     def test_getUnreviewedSuggestions(self):
-        # There are three different methods to return 
+        # There are three different methods to return
         suggestions = self.message.getUnreviewedSuggestions()
         self.assertContentEqual([self.suggestion2], suggestions)
 

=== modified file 'lib/lp/translations/tests/test_translatedlanguage.py'
--- lib/lp/translations/tests/test_translatedlanguage.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_translatedlanguage.py	2010-08-31 18:18:46 +0000
@@ -8,6 +8,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.testing import ZopelessDatabaseLayer
+from lp.app.enums import ServiceUsage
 from lp.testing import TestCaseWithFactory
 from lp.translations.interfaces.productserieslanguage import (
     IProductSeriesLanguageSet,
@@ -24,8 +25,10 @@
     def setUp(self):
         # Create a productseries that uses translations.
         TestCaseWithFactory.setUp(self)
-        self.productseries = self.factory.makeProductSeries()
-        self.productseries.product.official_rosetta = True
+        product = self.factory.makeProduct(
+            translations_usage = ServiceUsage.LAUNCHPAD)
+        self.productseries = self.factory.makeProductSeries(
+            product=product)
         self.parent = self.productseries
         self.psl_set = getUtility(IProductSeriesLanguageSet)
         self.language = self.factory.makeLanguage('sr@test')

=== modified file 'lib/lp/translations/tests/test_translations_to_review.py'
--- lib/lp/translations/tests/test_translations_to_review.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/tests/test_translations_to_review.py	2010-08-31 18:18:46 +0000
@@ -16,6 +16,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.testing import DatabaseFunctionalLayer
+from lp.app.enums import ServiceUsage
 from lp.services.worlddata.model.language import LanguageSet
 from lp.testing import TestCaseWithFactory
 from lp.translations.interfaces.translationsperson import ITranslationsPerson
@@ -28,6 +29,7 @@
 
 class ReviewTestMixin:
     """Base for testing which translations a reviewer can review."""
+
     def setUpMixin(self, for_product=True):
         """Set up test environment.
 
@@ -68,7 +70,7 @@
         transaction.commit()
 
         self.supercontext.translationgroup = self.translationgroup
-        self.supercontext.official_rosetta = True
+        self.supercontext.translations_usage = ServiceUsage.LAUNCHPAD
 
         self.potemplate = self.factory.makePOTemplate(
             productseries=self.productseries, distroseries=self.distroseries,
@@ -111,6 +113,7 @@
 
     Can be applied to product or distribution setups.
     """
+
     def test_OneFileToReview(self):
         # In the base case, the method finds one POFile for self.person
         # to review.
@@ -131,7 +134,7 @@
     def test_getReviewableTranslationFiles_not_translating_in_launchpad(self):
         # We don't see products/distros that don't use Launchpad for
         # translations.
-        self.supercontext.official_rosetta = False
+        self.supercontext.translations_usage = ServiceUsage.NOT_APPLICABLE
         self.assertEqual(self._getReviewables(), [])
 
     def test_getReviewableTranslationFiles_non_reviewer(self):
@@ -200,7 +203,7 @@
         other_pofile = removeSecurityProxy(other_pofile)
 
         product = other_pofile.potemplate.productseries.product
-        product.official_rosetta = True
+        product.translations_usage = ServiceUsage.LAUNCHPAD
 
         if with_unreviewed:
             other_pofile.unreviewed_count = 1

=== modified file 'lib/lp/translations/windmill/tests/test_documentation_links.py'
--- lib/lp/translations/windmill/tests/test_documentation_links.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/windmill/tests/test_documentation_links.py	2010-08-31 18:18:46 +0000
@@ -9,6 +9,7 @@
 from zope.security.proxy import removeSecurityProxy
 
 from canonical.launchpad.windmill.testing import lpuser
+from lp.app.enums import ServiceUsage
 from lp.testing import WindmillTestCase
 from lp.translations.windmill.testing import TranslationsWindmillLayer
 
@@ -52,7 +53,7 @@
         project = self.factory.makeProduct(
             name='test-product',
             displayname='Test Product',
-            official_rosetta=True)
+            translations_usage=ServiceUsage.LAUNCHPAD)
         removeSecurityProxy(project).translationgroup = group
 
         potemplate = self.createPOTemplateWithPOTMsgSets(

=== modified file 'lib/lp/translations/windmill/tests/test_import_queue.py'
--- lib/lp/translations/windmill/tests/test_import_queue.py	2010-08-20 20:31:18 +0000
+++ lib/lp/translations/windmill/tests/test_import_queue.py	2010-08-31 18:18:46 +0000
@@ -8,7 +8,6 @@
 
 import transaction
 from zope.component import getUtility
-from zope.security.proxy import removeSecurityProxy
 
 from canonical.launchpad.webapp import canonical_url
 from canonical.launchpad.windmill.testing import lpuser
@@ -18,6 +17,7 @@
     SLEEP,
     )
 from canonical.launchpad.windmill.testing.lpuser import login_person
+from lp.app.enums import ServiceUsage
 from lp.testing import WindmillTestCase
 from lp.translations.interfaces.translationimportqueue import (
     ITranslationImportQueue,
@@ -41,8 +41,8 @@
             'field.potemplate',
             'field.potemplate_name',
             'field.language',
-            ]
-    }
+            ],
+        }
     SELECT_FIELDS = [
         'field.potemplate',
         'field.language',
@@ -55,8 +55,7 @@
             input_tag = 'input'
         return (
             u"//tr[contains(@class,'unseen')]"
-            u"//%s[@id='%s']" % (input_tag, field_id)
-                )
+            u"//%s[@id='%s']" % (input_tag, field_id))
 
     def _assertAllFieldsVisible(self, client, fields):
         """Assert that all given fields are visible.
@@ -279,8 +278,9 @@
             name="hubert", displayname="Hubert Hunt", password="test",
             email="hubert@xxxxxxxxxxx")
         # Create a project and an import entry with it.
-        product = self.factory.makeProduct(owner=hubert)
-        removeSecurityProxy(product).official_rosetta = True
+        product = self.factory.makeProduct(
+            owner=hubert,
+            translations_usage=ServiceUsage.LAUNCHPAD)
         productseries = product.getSeries('trunk')
         queue = getUtility(ITranslationImportQueue)
         potemplate = self.factory.makePOTemplate(productseries=productseries)