← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~henninge/launchpad/recife-current-tm-view-1 into lp:~launchpad/launchpad/recife

 

You have been requested to review the proposed merge of lp:~henninge/launchpad/recife-current-tm-view-1 into lp:~launchpad/launchpad/recife.

= Converting CurrentTranslationMessageView Part 1 =

This branch updates the CurrentTranslationMessageView to work with the new sharing model which loses the concept of "imported" or "packaged" (same thing, different name) translations and replaces them with the concept "translations on the other side". The "other side" is either Ubuntu or upstream, depending from where you look.

There are three changes in this branch:

1. A general renaming of "imported" to "other" to fit the new model.
2. Removal of "can_dismiss_packaged" because "other" translations cannot be dismissed. This also includes removal of related tests and a css class.
3. The view had member variables for "imported_translationmessage" and "shared_sharedtranslationmessage" while the latter was left None if it was identical to the context (the "Current Translation Message"), the former was assigned the context. This antisymmetry has been fixed with the renaming to "other_translationmessage" which is now set to None, too, if the context is used on both sides (ubuntu and upstream). This entailed having to fix some places that depended on the old definition.

== Tests ==

I have run all lp.translations tests on this branch and they pass fine.

bin/test -vvcm lp.translations \
  -t test_translationmessage_view \
  -t translationmessage-views.txt \
  -t xx-translationmessage-translate.txt

== Demo/QA ==

This will be QA'ed with the full feature branch. The big thing to notice now when running this branch is that "Packaged" has been replaced with "Other" on the translate page.

== Lint ==

There are lint issues which I will fix in the next branch.



-- 
https://code.launchpad.net/~henninge/launchpad/recife-current-tm-view-1/+merge/41690
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~henninge/launchpad/recife-current-tm-view-1 into lp:~launchpad/launchpad/recife.
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2010-11-21 20:46:19 +0000
+++ lib/lp/testing/factory.py	2010-11-24 08:04:10 +0000
@@ -282,6 +282,9 @@
 from lp.translations.model.translationimportqueue import (
     TranslationImportQueueEntry,
     )
+from lp.translations.utilities.sanitize import (
+    sanitize_translations_from_webui
+    )
 
 
 SPACE = ' '
@@ -2536,7 +2539,7 @@
         assert not (diverged and current_other), (
             "A diverged message can't be current on the other side.")
         if pofile is None:
-            pofile = self.makePOFile('nl')
+            pofile = self.makePOFile()
         if potmsgset is None:
             potmsgset = self.makePOTMsgSet(pofile.potemplate, sequence=1)
         if translator is None:
@@ -2544,10 +2547,11 @@
         if reviewer is None:
             reviewer = self.makePerson()
         if translations is None:
-            translations = [self.getUniqueString()]
-        if isinstance(translations, list):
-            # Support the list-of-strings format for convenience.
-            translations = dict(enumerate(translations))
+            translations = {0: self.getUniqueString()}
+        else:
+            translations = sanitize_translations_from_webui(
+                potmsgset.singular_text, translations,
+                pofile.language.pluralforms)
 
         message = potmsgset.setCurrentTranslation(
             pofile, translator, translations,

=== modified file 'lib/lp/translations/browser/tests/test_translationmessage_view.py'
--- lib/lp/translations/browser/tests/test_translationmessage_view.py	2010-11-23 10:06:35 +0000
+++ lib/lp/translations/browser/tests/test_translationmessage_view.py	2010-11-24 08:04:10 +0000
@@ -66,8 +66,7 @@
             False, False, None, None, True, pofile=self.pofile, can_edit=True)
         self.view.initialize()
 
-    def _makeTranslation(self, translation=None,
-                         suggestion=False, is_packaged=False):
+    def _makeTranslation(self, translation=None, suggestion=False):
         if translation is None:
             translations = None
         elif isinstance(translation, list):
@@ -81,44 +80,38 @@
                 translator=self.owner,
                 date_created=self.now())
         else:
-            message = self.factory.makeTranslationMessage(
+            message = self.factory.makeCurrentTranslationMessage(
                 self.pofile, self.potmsgset,
                 translations=translations,
-                suggestion=suggestion,
-                is_current_upstream=is_packaged,
-                translator=self.owner,
-                date_updated=self.now())
+                translator=self.owner, reviewer=self.owner)
         message.browser_pofile = self.pofile
         return message
 
-    def _assertConfirmEmptyPluralPackaged(self,
-                                          can_confirm_and_dismiss,
-                                          can_dismiss_on_empty,
-                                          can_dismiss_on_plural,
-                                          can_dismiss_packaged):
+    def _assertConfirmEmptyPlural(self,
+                                  can_confirm_and_dismiss,
+                                  can_dismiss_on_empty,
+                                  can_dismiss_on_plural):
         assert self.view is not None
         self.assertEqual(
             [can_confirm_and_dismiss,
                can_dismiss_on_empty,
-               can_dismiss_on_plural,
-               can_dismiss_packaged],
+               can_dismiss_on_plural],
             [self.view.can_confirm_and_dismiss,
                self.view.can_dismiss_on_empty,
-               self.view.can_dismiss_on_plural,
-               self.view.can_dismiss_packaged])
+               self.view.can_dismiss_on_plural])
 
     def test_no_suggestion(self):
         # If there is no suggestion, nothing can be dismissed.
         message = self._makeTranslation()
         self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, False, False, False)
+        self._assertConfirmEmptyPlural(False, False, False)
 
     def test_local_suggestion(self):
         # If there is a local suggestion, it can be dismissed.
         message = self._makeTranslation()
         suggestion = self._makeTranslation(suggestion=True)
         self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(True, False, False, False)
+        self._assertConfirmEmptyPlural(True, False, False)
 
     def test_local_suggestion_on_empty(self):
         # If there is a local suggestion on an empty message, it is dismissed
@@ -126,7 +119,7 @@
         message = self._makeTranslation("")
         suggestion = self._makeTranslation(suggestion=True)
         self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, True, False, False)
+        self._assertConfirmEmptyPlural(False, True, False)
 
     def test_local_suggestion_on_plural(self):
         # If there is a suggestion on a plural message, it is dismissed
@@ -137,59 +130,7 @@
         suggestion = self._makeTranslation(["singular_sugg", "plural_sugg"],
                                          suggestion=True)
         self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, False, True, False)
-
-        # XXX JeroenVermeulen 2010-11-22: Disabling this test
-        # temporarily.  We must re-enable it before completing the
-        # migration of CurrentTranslationMessageTranslateView to the
-        # Recife model.  Currently this is the only test that still
-        # breaks after a partial migration of model code and that view
-        # (as needed to complete the update of _storeTranslations).
-    def XXX_disabled_test_packaged_suggestion(self):
-        # If there is a packaged suggestion, it can be dismissed.
-        packaged = self._makeTranslation(is_packaged=True)
-        message = self._makeTranslation()
-        new_packaged = self._makeTranslation(is_packaged=True)
-        self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(True, False, False, True)
-
-    def test_packaged_suggestion_on_empty(self):
-        # If there is an empty suggestion on an empty message,
-        # it is dismissed in a different place.
-        packaged = self._makeTranslation(is_packaged=True)
-        message = self._makeTranslation("")
-        new_packaged = self._makeTranslation(is_packaged=True)
-        self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, True, False, True)
-
-    def test_packaged_suggestion_on_plural(self):
-        # If there is a suggestion on a plural message, it is dismissed
-        # in yet a different place.
-        self.potmsgset = self.factory.makePOTMsgSet(self.potemplate,
-                singular="msgid_singular", plural="msgid_plural")
-        packaged = self._makeTranslation(["singular_trans", "plural_trans"],
-                                         is_packaged=True)
-        message = self._makeTranslation(["singular_trans", "plural_trans"])
-        new_packaged = self._makeTranslation(["singular_new", "plural_new"],
-                                             is_packaged=True)
-        self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, False, True, True)
-
-    def test_packaged_suggestion_old(self):
-        # If there is an older packaged suggestion, it cannot be dismissed.
-        packaged = self._makeTranslation(is_packaged=True)
-        message = self._makeTranslation()
-        self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(False, False, False, False)
-
-    def test_packaged_old_local_new(self):
-        # If there is an older packaged suggestion, but a newer local
-        # suggestion, only the local suggestion can be dismissed.
-        packaged = self._makeTranslation(is_packaged=True)
-        message = self._makeTranslation()
-        suggestion = self._makeTranslation(suggestion=True)
-        self._createView(message)
-        self._assertConfirmEmptyPluralPackaged(True, False, False, False)
+        self._assertConfirmEmptyPlural(False, False, True)
 
 
 class TestResetTranslations(TestCaseWithFactory):

=== modified file 'lib/lp/translations/browser/tests/translationmessage-views.txt'
--- lib/lp/translations/browser/tests/translationmessage-views.txt	2010-11-22 14:27:36 +0000
+++ lib/lp/translations/browser/tests/translationmessage-views.txt	2010-11-24 08:04:10 +0000
@@ -135,14 +135,14 @@
     ...
     AssertionError: There is no plural form #1 for Spanish (es) language
 
-Upstream translation is defined and same as the active one.
+The translation on the other side is defined and same as the active one.
 
-    >>> subview.getImportedTranslation(0)
+    >>> subview.getOtherTranslation(0)
     u'libreta de direcciones de Evolution'
 
 However, if we ask for incorrect plural form, we get an AssertionError.
 
-    >>> subview.getImportedTranslation(1)
+    >>> subview.getOtherTranslation(1)
     Traceback (most recent call last):
     ...
     AssertionError: There is no plural form #1 for Spanish (es) language

=== modified file 'lib/lp/translations/browser/translationmessage.py'
--- lib/lp/translations/browser/translationmessage.py	2010-11-22 14:27:36 +0000
+++ lib/lp/translations/browser/translationmessage.py	2010-11-24 08:04:10 +0000
@@ -1017,29 +1017,30 @@
         if side_traits.other_side_traits.getFlag(self.context):
             # The shared translation for the other side matches the current
             # one.
-            self.imported_translationmessage = self.context
+            self.other_translationmessage = None
         else:
-            self.imported_translationmessage = (
+            self.other_translationmessage = (
                 self.context.potmsgset.getCurrentTranslation(
                     self.pofile.potemplate, self.pofile.language,
                     side_traits.other_side_traits.side))
 
         if self.context.potemplate is None:
-            # Shared translation is current.
+            # Current translation is shared.
             self.shared_translationmessage = None
         else:
-            self.shared_translationmessage = (
+            # Current translation is diverged, find the shared one.
+            shared_translationmessage = (
                 self.context.potmsgset.getCurrentTranslation(
                     None, self.pofile.language, side_traits.side))
-            if (self.shared_translationmessage ==
-                self.imported_translationmessage):
-                # If it matches the imported message, we don't care.
+            if (shared_translationmessage == self.other_translationmessage):
+                # If it matches the other message, we don't care.
                 self.shared_translationmessage = None
+            else:
+                self.shared_translationmessage = shared_translationmessage
 
         self.can_confirm_and_dismiss = False
         self.can_dismiss_on_empty = False
         self.can_dismiss_on_plural = False
-        self.can_dismiss_packaged = False
 
         # Initialize to True, allowing POFileTranslateView to override.
         self.zoomed_in_view = True
@@ -1093,15 +1094,12 @@
                     self.current_series.distribution.displayname,
                     self.current_series.name)
 
-        side_traits = getUtility(ITranslationSideTraitsSet).getForTemplate(
-            self.pofile.potemplate)
-
         # Initialise the translation dictionaries used from the
         # translation form.
         self.translation_dictionaries = []
         for index in self.pluralform_indices:
             current_translation = self.getCurrentTranslation(index)
-            imported_translation = self.getImportedTranslation(index)
+            other_translation = self.getOtherTranslation(index)
             shared_translation = self.getSharedTranslation(index)
             submitted_translation = self.getSubmittedTranslation(index)
             if (submitted_translation is None and
@@ -1118,18 +1116,17 @@
                 self.context.submitter == self.context.reviewer)
             is_same_date = (
                 self.context.date_created == self.context.date_reviewed)
-            if side_traits.other_side_traits.getFlag(self.context):
-                # Imported one matches the current one.
-                imported_submission = None
-            elif self.imported_translationmessage is not None:
+            if self.other_translationmessage is None:
+                other_submission = None
+            else:
                 pofile = (
-                    self.imported_translationmessage.ensureBrowserPOFile())
+                    self.other_translationmessage.ensureBrowserPOFile())
                 if pofile is None:
-                    imported_submission = None
+                    other_submission = None
                 else:
-                    imported_submission = (
+                    other_submission = (
                         convert_translationmessage_to_submission(
-                            message=self.imported_translationmessage,
+                            message=self.other_translationmessage,
                             current_message=self.context,
                             plural_form=index,
                             pofile=pofile,
@@ -1137,8 +1134,6 @@
                             is_empty=False,
                             packaged=True,
                             local_to_pofile=True))
-            else:
-                imported_submission = None
 
             diverged_and_have_shared = (
                 self.context.potemplate is not None and
@@ -1165,9 +1160,9 @@
                 'current_translation': text_to_html(
                     current_translation, self.context.potmsgset.flags),
                 'submitted_translation': submitted_translation,
-                'imported_translation': text_to_html(
-                    imported_translation, self.context.potmsgset.flags),
-                'imported_translation_message': imported_submission,
+                'other_translation': text_to_html(
+                    other_translation, self.context.potmsgset.flags),
+                'other_translation_message': other_submission,
                 'shared_translation': text_to_html(
                     shared_translation, self.context.potmsgset.flags),
                 'shared_translation_message': shared_submission,
@@ -1181,10 +1176,9 @@
                     self.context.makeHTMLID('translation_%d' % index),
                 }
 
-            if (not side_traits.other_side_traits.getFlag(self.context) and
-                self.imported_translationmessage is not None):
+            if self.other_translationmessage is not None:
                 translation_entry['html_id_imported_suggestion'] = (
-                    self.imported_translationmessage.makeHTMLID(
+                    self.other_translationmessage.makeHTMLID(
                         'suggestion'))
 
             if self.message_must_be_hidden:
@@ -1202,42 +1196,27 @@
         # HTML id for singular form of this message
         self.html_id_singular = self.context.makeHTMLID('translation_0')
 
-    def _set_dismiss_flags(self, local_suggestions, imported):
+    def _set_dismiss_flags(self, local_suggestions):
         """Set dismissal flags.
 
         The flags are all initialized as False.
 
         :param local_suggestions: The list of local suggestions.
-        :param imported: The imported (packaged) translation for this
-            message or None if there is no such translation.
         """
         # Only official translators can dismiss anything.
         if not self.user_is_official_translator:
             return
 
-        if imported is not None:
-            date_reviewed = self.context.date_reviewed
-            if date_reviewed is None:
-                has_new_imported = True
-            else:
-                has_new_imported = imported.date_created > date_reviewed
-        else:
-            has_new_imported = False
-
-        # If there are no local suggestion or a newly imported string,
-        # nothing can be dismissed.
-        if not (len(local_suggestions) > 0 or has_new_imported):
+        # If there are no local suggestions, nothing can be dismissed.
+        if len(local_suggestions) == 0:
             return
 
-        # OK, let's set some flags.
-        self.can_dismiss_packaged = has_new_imported
         if self.is_plural:
             self.can_dismiss_on_plural = True
+        elif self.getCurrentTranslation(0) is None:
+            self.can_dismiss_on_empty = True
         else:
-            if self.getCurrentTranslation(0) is None:
-                self.can_dismiss_on_empty = True
-            else:
-                self.can_confirm_and_dismiss = True
+            self.can_confirm_and_dismiss = True
 
     def _setOnePOFile(self, messages):
         """Return a list of messages that all have a browser_pofile set.
@@ -1286,13 +1265,7 @@
 
         language = self.pofile.language
         potmsgset = self.context.potmsgset
-        side_traits = getUtility(ITranslationSideTraitsSet).getForTemplate(
-            self.pofile.potemplate)
-
-        if not side_traits.other_side_traits.getFlag(self.context):
-            imported = self.imported_translationmessage
-        else:
-            imported = None
+        other = self.other_translationmessage
 
         # Show suggestions only when you can actually do something with them
         # (i.e. you are logged in and have access to at least submit
@@ -1308,7 +1281,7 @@
                 key=operator.attrgetter("date_created"),
                 reverse=True)
 
-            self._set_dismiss_flags(local, imported)
+            self._set_dismiss_flags(local)
 
             for suggestion in local:
                 suggestion.setPOFile(self.pofile)
@@ -1360,8 +1333,8 @@
         # suggestion per plural form.
         for index in self.pluralform_indices:
             self.seen_translations = set([self.context.translations[index]])
-            if imported:
-                self.seen_translations.add(imported.translations[index])
+            if other is not None:
+                self.seen_translations.add(other.translations[index])
             local_suggestions = (
                 self._buildTranslationMessageSuggestions(
                     'Suggestions', local, index, local_to_pofile=True))
@@ -1403,23 +1376,18 @@
         self.seen_translations = iterable_submissions.seen_translations
         return iterable_submissions
 
-    def getOfficialTranslation(self, index, is_current_upstream=False,
-                               is_shared=False):
-        """Return current or imported translation for plural form 'index'."""
+    def getOfficialTranslation(self, index, is_other=False, is_shared=False):
+        """Return current translation on either side for plural form 'index'."""
         assert index in self.pluralform_indices, (
             'There is no plural form #%d for %s language' % (
                 index, self.pofile.language.displayname))
 
-        if is_current_upstream:
-            if self.imported_translationmessage is None:
-                return None
-
-            translation = self.imported_translationmessage.translations[index]
-        elif is_shared:
+        if is_shared:
             if self.shared_translationmessage is None:
                 return None
-
             translation = self.shared_translationmessage.translations[index]
+        elif is_other and self.other_translationmessage is not None:
+            translation = self.other_translationmessage.translations[index]
         else:
             translation = self.context.translations[index]
         # We store newlines as '\n', '\r' or '\r\n', depending on the
@@ -1434,9 +1402,9 @@
         """Return the current translation for the pluralform 'index'."""
         return self.getOfficialTranslation(index)
 
-    def getImportedTranslation(self, index):
-        """Return the imported translation for the pluralform 'index'."""
-        return self.getOfficialTranslation(index, is_current_upstream=True)
+    def getOtherTranslation(self, index):
+        """Return the other-side translation for the pluralform 'index'."""
+        return self.getOfficialTranslation(index, is_other=True)
 
     def getSharedTranslation(self, index):
         """Return the shared translation for the pluralform 'index'."""
@@ -1581,18 +1549,15 @@
         return 3
 
     @property
+    def dismissable_button_class(self):
+        """The class string that deactivates only buttons on dismissal."""
+        return "%s_dismissable_button" % self.html_id
+
+    @property
     def dismissable_class(self):
         """The class string for dismissable parts."""
-        return "%s_dismissable %s_dismissable_button" % (
-                    self.html_id, self.html_id)
-
-    @property
-    def dismissable_class_packaged(self):
-        """The class string for dismissable packaged translations."""
-        if self.can_dismiss_packaged:
-            return self.dismissable_class
-        # Buttons are always dismissable.
-        return "%s_dismissable_button" % self.html_id
+        return "%s_dismissable %s" % (
+                    self.html_id, self.dismissable_button_class)
 
 
 class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):

=== modified file 'lib/lp/translations/doc/poexport-language-pack.txt'
--- lib/lp/translations/doc/poexport-language-pack.txt	2010-11-09 09:46:20 +0000
+++ lib/lp/translations/doc/poexport-language-pack.txt	2010-11-24 08:04:10 +0000
@@ -313,9 +313,8 @@
 
     >>> pofile_es = template.newPOFile('es')
     >>> translations = { 0: u'blah (es)' }
-    >>> new_translation_message = potmsgset.updateTranslation(
-    ...     pofile_es, mark, translations, is_current_upstream=False,
-    ...     lock_timestamp=datetime.datetime.now(UTC))
+    >>> new_translation_message = factory.makeCurrentTranslationMessage(
+    ...     pofile_es, potmsgset, mark, translations=translations)
     >>> pofile_es.date_changed = d2000_01_01
 
 Create a Welsh PO file, with an active translation submission created on
@@ -323,9 +322,8 @@
 
     >>> pofile_cy = template.newPOFile('cy')
     >>> translations = { 0: u'blah (cy)' }
-    >>> new_translation_message = potmsgset.updateTranslation(
-    ...     pofile_cy, mark, translations, is_current_upstream=False,
-    ...     lock_timestamp=datetime.datetime.now(UTC))
+    >>> new_translation_message = factory.makeCurrentTranslationMessage(
+    ...     pofile_cy, potmsgset, mark, translations=translations)
     >>> pofile_cy.date_changed = d2000_01_03
     >>> transaction.commit()
 

=== modified file 'lib/lp/translations/doc/potmsgset.txt'
--- lib/lp/translations/doc/potmsgset.txt	2010-11-18 05:28:57 +0000
+++ lib/lp/translations/doc/potmsgset.txt	2010-11-24 08:04:10 +0000
@@ -542,14 +542,14 @@
     ...     u'%d contact', u'%d contacts')
     >>> pofile_es.plural_forms
     2
-    >>> message = plural_potmsgset.updateTranslation(pofile_es, foobar,
-    ...     {0: u'foo %d', 1: None}, is_current_upstream=False,
-    ...     lock_timestamp=datetime.now(pytz.UTC))
+    >>> message = factory.makeCurrentTranslationMessage(
+    ...     pofile_es, plural_potmsgset, foobar,
+    ...     translations={0: u'foo %d', 1: None})
     >>> message.is_complete
     False
-    >>> message = plural_potmsgset.updateTranslation(pofile_es, foobar,
-    ...     {0: None}, is_current_upstream=False,
-    ...     lock_timestamp=datetime.now(pytz.UTC))
+    >>> message = factory.makeCurrentTranslationMessage(
+    ...     pofile_es, plural_potmsgset, foobar,
+    ...     translations={0: None})
     >>> message.is_complete
     False
 
@@ -580,18 +580,17 @@
 
 The message we're looking at is translated to two plural forms.
 
-    >>> message_with_two_forms = pm_potmsgset.updateTranslation(
-    ...     pm_translation, pm_template.owner, ['%d fu', '%d fuitl'],
-    ...     is_current_upstream=False, lock_timestamp=datetime.now(pytz.UTC))
+    >>> message_with_two_forms = factory.makeCurrentTranslationMessage(
+    ...     pm_translation, pm_potmsgset, pm_template.owner,
+    ...     translations=['%d fu', '%d fuitl'])
 
 When an otherwise identical translation with three comes along, the
 third form is ignored because it falls outside the current 2 forms.
 The "new" translation message is the same one we already had.
 
-    >>> message_with_three_forms = pm_potmsgset.updateTranslation(
-    ...     pm_translation, pm_template.owner,
-    ...     ['%d fu', '%d fuitl', '%d fuitlx'], is_current_upstream=False,
-    ...     lock_timestamp=datetime.now(pytz.UTC))
+    >>> message_with_three_forms = factory.makeCurrentTranslationMessage(
+    ...     pm_translation, pm_potmsgset, pm_template.owner,
+    ...     translations=['%d fu', '%d fuitl', '%d fuitlx'])
     >>> message_with_three_forms == message_with_two_forms
     True
 
@@ -602,10 +601,9 @@
     >>> zap.pluralforms = 3
     >>> zap.pluralexpression = 'n % 3'
 
-    >>> message_with_three_forms = pm_potmsgset.updateTranslation(
-    ...     pm_translation, pm_template.owner,
-    ...     ['%d fu', '%d fuitl', '%d fuitlx'], is_current_upstream=False,
-    ...     lock_timestamp=datetime.now(pytz.UTC))
+    >>> message_with_three_forms = factory.makeCurrentTranslationMessage(
+    ...     pm_translation, pm_potmsgset, pm_template.owner,
+    ...     translations=['%d fu', '%d fuitl', '%d fuitlx'])
     >>> message_with_three_forms == message_with_two_forms
     False
 
@@ -618,9 +616,9 @@
 no new message is created.  Instead, the closest existing match (the
 one with two forms) is updated.
 
-    >>> message_with_one_form = pm_potmsgset.updateTranslation(
-    ...     pm_translation, pm_template.owner, ['%d fu'],
-    ...     is_current_upstream=False, lock_timestamp=datetime.now(pytz.UTC))
+    >>> message_with_one_form = factory.makeCurrentTranslationMessage(
+    ...     pm_translation, pm_potmsgset, pm_template.owner,
+    ...     translations=['%d fu'])
 
     >>> message_with_one_form == message_with_two_forms
     True
@@ -939,12 +937,12 @@
     >>> spanish_pofile = alsa_potemplate.getPOFileByLang('es')
     >>> spanish = spanish_pofile.language
 
-    >>> new_translation = translator_credits.updateTranslation(spanish_pofile,
-    ...     carlos, {0: u'Some Translator'}, is_current_upstream=True,
-    ...     lock_timestamp=datetime.now(pytz.UTC))
+    >>> new_translation = factory.makeCurrentTranslationMessage(
+    ...     spanish_pofile, translator_credits, carlos,
+    ...     translations={0: u'Some Translator'})
 
-    >>> current = translator_credits.getCurrentTranslationMessage(
-    ...     alsa_potemplate, spanish)
+    >>> current = translator_credits.getCurrentTranslation(
+    ...     alsa_potemplate, spanish, alsa_potemplate.translation_side)
     >>> current.translations
     [u'Some Translator']
 

=== modified file 'lib/lp/translations/doc/remove-translations-by.txt'
--- lib/lp/translations/doc/remove-translations-by.txt	2010-09-30 17:57:01 +0000
+++ lib/lp/translations/doc/remove-translations-by.txt	2010-11-24 08:04:10 +0000
@@ -19,10 +19,9 @@
     >>> from pytz import timezone
     >>> def set_translation(message, pofile, text):
     ...     """Set text to be a translation for message in pofile."""
-    ...     return message.updateTranslation(
-    ...         pofile, pofile.potemplate.owner, {0: text},
-    ...         is_current_upstream=False,
-    ...         lock_timestamp=datetime.now(timezone('UTC')))
+    ...     return factory.makeCurrentTranslationMessage(
+    ...         pofile, message, pofile.potemplate.owner,
+    ...         translations={0: text})
 
     >>> def print_pofile_contents(pofile):
     ...     """Return sorted list of (singular) translations in pofile."""
@@ -55,9 +54,9 @@
 
     >>> nl_message = set_translation(
     ...     message, nl_pofile, "Maar dan in het Nederlands.")
+    >>> nl_message.is_current_upstream
+    True
     >>> nl_message.is_current_ubuntu
-    True
-    >>> nl_message.is_current_upstream
     False
     >>> print nl_message.potmsgset.msgid_singular.msgid
     My goose is undercooked.
@@ -89,8 +88,8 @@
     ...     '--potemplate=%s' % str(potemplate.id),
     ...     '--not-language',
     ...     '--language=%s' % 'de',
-    ...     '--is-current-ubuntu=%s' % 'true',
-    ...     '--is-current-upstream=%s' % 'false',
+    ...     '--is-current-ubuntu=%s' % 'false',
+    ...     '--is-current-upstream=%s' % 'true',
     ...     '--msgid=%s' % "My goose is undercooked.",
     ...     '--origin=%s' % 'ROSETTAWEB',
     ...     '--force',

=== modified file 'lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt'
--- lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt	2010-11-22 14:27:36 +0000
+++ lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt	2010-11-24 08:04:10 +0000
@@ -527,7 +527,7 @@
     ...              '+source/evolution/+pots/evolution-2.2/es/5/+translate')
     >>> packaged = find_tag_by_id(browser.contents, 'msgset_134_packaged')
     >>> print extract_text(packaged)
-    Packaged: tarjetas
+    Other: tarjetas
 
 First, we look for an existing imported translation in evolution PO file
 in Ubuntu Hoary.  We can't modify "imported" messages through web UI, so

=== modified file 'lib/lp/translations/templates/currenttranslationmessage-translate-one.pt'
--- lib/lp/translations/templates/currenttranslationmessage-translate-one.pt	2010-08-31 12:42:29 +0000
+++ lib/lp/translations/templates/currenttranslationmessage-translate-one.pt	2010-11-24 08:04:10 +0000
@@ -386,23 +386,23 @@
       </tr>
     </tal:has-submitter>
 
-    <tal:imported_translation
+    <tal:other_translation
       define="
-        section_title string:Packaged:;
-        submission translation_dictionary/imported_translation_message;
-        dismissable view/dismissable_class_packaged;
+        section_title string:Other:;
+        submission translation_dictionary/other_translation_message;
+        dismissable view/dismissable_button_class;
         form_is_writeable view/form_is_writeable;
         user_is_official_translator view/user_is_official_translator;
         ">
       <metal:suggestion
          use-macro="context/@@+translations-macros/render-suggestion" />
-    </tal:imported_translation>
+    </tal:other_translation>
     <tal:shared_translation
       condition="translation_dictionary/shared_translation_message"
       define="
         section_title string:Shared:;
         submission translation_dictionary/shared_translation_message;
-        dismissable view/dismissable_class_packaged;
+        dismissable view/dismissable_button_class;
         form_is_writeable view/form_is_writeable;
         user_is_official_translator view/user_is_official_translator;
         ">