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

Proposed by Henning Eggers
Status: Merged
Merged at revision: 9208
Proposed branch: lp:~henninge/launchpad/recife-current-tm-view-1
Merge into: lp:~launchpad/launchpad/recife
Diff against target: 683 lines (+113/-208)
9 files modified
lib/lp/testing/factory.py (+9/-5)
lib/lp/translations/browser/tests/test_translationmessage_view.py (+13/-72)
lib/lp/translations/browser/tests/translationmessage-views.txt (+3/-3)
lib/lp/translations/browser/translationmessage.py (+47/-82)
lib/lp/translations/doc/poexport-language-pack.txt (+4/-6)
lib/lp/translations/doc/potmsgset.txt (+23/-25)
lib/lp/translations/doc/remove-translations-by.txt (+7/-8)
lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt (+1/-1)
lib/lp/translations/templates/currenttranslationmessage-translate-one.pt (+6/-6)
To merge this branch: bzr merge lp:~henninge/launchpad/recife-current-tm-view-1
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) code Approve
Steve Kowalik (community) code* Approve
Review via email: mp+41690@code.launchpad.net

Description of the change

= 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.

To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :

Sorry, the following files are from a a different branch:

lib/lp/testing/factory.py
lib/lp/translations/doc/poexport-language-pack.txt
lib/lp/translations/doc/potmsgset.txt
lib/lp/translations/doc/remove-translations-by.txt

Luckily they are orthogonal to the other changes. The branch is lp:~henninge/launchpad/recife-kill-ut-in-tests-1. It is about replacing calls to "updateTranslation" in tests with calls to the factory method "makeCurrentTranslationMessage". This is quite mechanical but the factory method had to be extended to include sanitation, something that "updateTranslation" used to do.

You can chose to ignore these files or review them along with the others. Your pick. ;-)

Revision history for this message
Steve Kowalik (stevenk) wrote :

Hi Henning,

These changes look fine to me -- and a bonus about removing a lot of code.

My only concern is the use of "Other", but I'm not going to block the branch for that nitpick.

review: Approve (code*)
Revision history for this message
Henning Eggers (henninge) wrote :

Never mind my last comment. Those changes have already been reviewed, just not landed ...

/me is very forgetful atm. :(

Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve (code)
Revision history for this message
Данило Шеган (danilo) wrote :

Henning, thanks for taking care of this. I've only gone through your
MP, and wonder one thing.

У сре, 24. 11 2010. у 08:05 +0000, Henning Eggers пише:

> 2. Removal of "can_dismiss_packaged" because "other" translations cannot be dismissed. This also includes removal of related tests and a css class.

I am not so sure it can't be "dismissed": the problem is that if
date_reviewed on the current translation is older than the "other"
current translation, you'll always have one unreviewed translation. The
solution to that is to just update the date_reviewed on the current
translation. I haven't looked at the code changes, but we do want to
preserve this behavior if it works today. If it doesn't, well,
something for another day.

Revision history for this message
Henning Eggers (henninge) wrote :

Thanks for commenting on that. I had forgotten how exactly that worked and from that misjudged the situation.

I reverted this change in lp:~henninge/launchpad/recife-current-tm-view-3 and got it to work with the new model, even the test that Jeroen had to deactivate. All good but later than expected.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== 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 @@
282from lp.translations.model.translationimportqueue import (282from lp.translations.model.translationimportqueue import (
283 TranslationImportQueueEntry,283 TranslationImportQueueEntry,
284 )284 )
285from lp.translations.utilities.sanitize import (
286 sanitize_translations_from_webui
287 )
285288
286289
287SPACE = ' '290SPACE = ' '
@@ -2536,7 +2539,7 @@
2536 assert not (diverged and current_other), (2539 assert not (diverged and current_other), (
2537 "A diverged message can't be current on the other side.")2540 "A diverged message can't be current on the other side.")
2538 if pofile is None:2541 if pofile is None:
2539 pofile = self.makePOFile('nl')2542 pofile = self.makePOFile()
2540 if potmsgset is None:2543 if potmsgset is None:
2541 potmsgset = self.makePOTMsgSet(pofile.potemplate, sequence=1)2544 potmsgset = self.makePOTMsgSet(pofile.potemplate, sequence=1)
2542 if translator is None:2545 if translator is None:
@@ -2544,10 +2547,11 @@
2544 if reviewer is None:2547 if reviewer is None:
2545 reviewer = self.makePerson()2548 reviewer = self.makePerson()
2546 if translations is None:2549 if translations is None:
2547 translations = [self.getUniqueString()]2550 translations = {0: self.getUniqueString()}
2548 if isinstance(translations, list):2551 else:
2549 # Support the list-of-strings format for convenience.2552 translations = sanitize_translations_from_webui(
2550 translations = dict(enumerate(translations))2553 potmsgset.singular_text, translations,
2554 pofile.language.pluralforms)
25512555
2552 message = potmsgset.setCurrentTranslation(2556 message = potmsgset.setCurrentTranslation(
2553 pofile, translator, translations,2557 pofile, translator, translations,
25542558
=== 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 @@
66 False, False, None, None, True, pofile=self.pofile, can_edit=True)66 False, False, None, None, True, pofile=self.pofile, can_edit=True)
67 self.view.initialize()67 self.view.initialize()
6868
69 def _makeTranslation(self, translation=None,69 def _makeTranslation(self, translation=None, suggestion=False):
70 suggestion=False, is_packaged=False):
71 if translation is None:70 if translation is None:
72 translations = None71 translations = None
73 elif isinstance(translation, list):72 elif isinstance(translation, list):
@@ -81,44 +80,38 @@
81 translator=self.owner,80 translator=self.owner,
82 date_created=self.now())81 date_created=self.now())
83 else:82 else:
84 message = self.factory.makeTranslationMessage(83 message = self.factory.makeCurrentTranslationMessage(
85 self.pofile, self.potmsgset,84 self.pofile, self.potmsgset,
86 translations=translations,85 translations=translations,
87 suggestion=suggestion,86 translator=self.owner, reviewer=self.owner)
88 is_current_upstream=is_packaged,
89 translator=self.owner,
90 date_updated=self.now())
91 message.browser_pofile = self.pofile87 message.browser_pofile = self.pofile
92 return message88 return message
9389
94 def _assertConfirmEmptyPluralPackaged(self,90 def _assertConfirmEmptyPlural(self,
95 can_confirm_and_dismiss,91 can_confirm_and_dismiss,
96 can_dismiss_on_empty,92 can_dismiss_on_empty,
97 can_dismiss_on_plural,93 can_dismiss_on_plural):
98 can_dismiss_packaged):
99 assert self.view is not None94 assert self.view is not None
100 self.assertEqual(95 self.assertEqual(
101 [can_confirm_and_dismiss,96 [can_confirm_and_dismiss,
102 can_dismiss_on_empty,97 can_dismiss_on_empty,
103 can_dismiss_on_plural,98 can_dismiss_on_plural],
104 can_dismiss_packaged],
105 [self.view.can_confirm_and_dismiss,99 [self.view.can_confirm_and_dismiss,
106 self.view.can_dismiss_on_empty,100 self.view.can_dismiss_on_empty,
107 self.view.can_dismiss_on_plural,101 self.view.can_dismiss_on_plural])
108 self.view.can_dismiss_packaged])
109102
110 def test_no_suggestion(self):103 def test_no_suggestion(self):
111 # If there is no suggestion, nothing can be dismissed.104 # If there is no suggestion, nothing can be dismissed.
112 message = self._makeTranslation()105 message = self._makeTranslation()
113 self._createView(message)106 self._createView(message)
114 self._assertConfirmEmptyPluralPackaged(False, False, False, False)107 self._assertConfirmEmptyPlural(False, False, False)
115108
116 def test_local_suggestion(self):109 def test_local_suggestion(self):
117 # If there is a local suggestion, it can be dismissed.110 # If there is a local suggestion, it can be dismissed.
118 message = self._makeTranslation()111 message = self._makeTranslation()
119 suggestion = self._makeTranslation(suggestion=True)112 suggestion = self._makeTranslation(suggestion=True)
120 self._createView(message)113 self._createView(message)
121 self._assertConfirmEmptyPluralPackaged(True, False, False, False)114 self._assertConfirmEmptyPlural(True, False, False)
122115
123 def test_local_suggestion_on_empty(self):116 def test_local_suggestion_on_empty(self):
124 # If there is a local suggestion on an empty message, it is dismissed117 # If there is a local suggestion on an empty message, it is dismissed
@@ -126,7 +119,7 @@
126 message = self._makeTranslation("")119 message = self._makeTranslation("")
127 suggestion = self._makeTranslation(suggestion=True)120 suggestion = self._makeTranslation(suggestion=True)
128 self._createView(message)121 self._createView(message)
129 self._assertConfirmEmptyPluralPackaged(False, True, False, False)122 self._assertConfirmEmptyPlural(False, True, False)
130123
131 def test_local_suggestion_on_plural(self):124 def test_local_suggestion_on_plural(self):
132 # If there is a suggestion on a plural message, it is dismissed125 # If there is a suggestion on a plural message, it is dismissed
@@ -137,59 +130,7 @@
137 suggestion = self._makeTranslation(["singular_sugg", "plural_sugg"],130 suggestion = self._makeTranslation(["singular_sugg", "plural_sugg"],
138 suggestion=True)131 suggestion=True)
139 self._createView(message)132 self._createView(message)
140 self._assertConfirmEmptyPluralPackaged(False, False, True, False)133 self._assertConfirmEmptyPlural(False, False, True)
141
142 # XXX JeroenVermeulen 2010-11-22: Disabling this test
143 # temporarily. We must re-enable it before completing the
144 # migration of CurrentTranslationMessageTranslateView to the
145 # Recife model. Currently this is the only test that still
146 # breaks after a partial migration of model code and that view
147 # (as needed to complete the update of _storeTranslations).
148 def XXX_disabled_test_packaged_suggestion(self):
149 # If there is a packaged suggestion, it can be dismissed.
150 packaged = self._makeTranslation(is_packaged=True)
151 message = self._makeTranslation()
152 new_packaged = self._makeTranslation(is_packaged=True)
153 self._createView(message)
154 self._assertConfirmEmptyPluralPackaged(True, False, False, True)
155
156 def test_packaged_suggestion_on_empty(self):
157 # If there is an empty suggestion on an empty message,
158 # it is dismissed in a different place.
159 packaged = self._makeTranslation(is_packaged=True)
160 message = self._makeTranslation("")
161 new_packaged = self._makeTranslation(is_packaged=True)
162 self._createView(message)
163 self._assertConfirmEmptyPluralPackaged(False, True, False, True)
164
165 def test_packaged_suggestion_on_plural(self):
166 # If there is a suggestion on a plural message, it is dismissed
167 # in yet a different place.
168 self.potmsgset = self.factory.makePOTMsgSet(self.potemplate,
169 singular="msgid_singular", plural="msgid_plural")
170 packaged = self._makeTranslation(["singular_trans", "plural_trans"],
171 is_packaged=True)
172 message = self._makeTranslation(["singular_trans", "plural_trans"])
173 new_packaged = self._makeTranslation(["singular_new", "plural_new"],
174 is_packaged=True)
175 self._createView(message)
176 self._assertConfirmEmptyPluralPackaged(False, False, True, True)
177
178 def test_packaged_suggestion_old(self):
179 # If there is an older packaged suggestion, it cannot be dismissed.
180 packaged = self._makeTranslation(is_packaged=True)
181 message = self._makeTranslation()
182 self._createView(message)
183 self._assertConfirmEmptyPluralPackaged(False, False, False, False)
184
185 def test_packaged_old_local_new(self):
186 # If there is an older packaged suggestion, but a newer local
187 # suggestion, only the local suggestion can be dismissed.
188 packaged = self._makeTranslation(is_packaged=True)
189 message = self._makeTranslation()
190 suggestion = self._makeTranslation(suggestion=True)
191 self._createView(message)
192 self._assertConfirmEmptyPluralPackaged(True, False, False, False)
193134
194135
195class TestResetTranslations(TestCaseWithFactory):136class TestResetTranslations(TestCaseWithFactory):
196137
=== 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 @@
135 ...135 ...
136 AssertionError: There is no plural form #1 for Spanish (es) language136 AssertionError: There is no plural form #1 for Spanish (es) language
137137
138Upstream translation is defined and same as the active one.138The translation on the other side is defined and same as the active one.
139139
140 >>> subview.getImportedTranslation(0)140 >>> subview.getOtherTranslation(0)
141 u'libreta de direcciones de Evolution'141 u'libreta de direcciones de Evolution'
142142
143However, if we ask for incorrect plural form, we get an AssertionError.143However, if we ask for incorrect plural form, we get an AssertionError.
144144
145 >>> subview.getImportedTranslation(1)145 >>> subview.getOtherTranslation(1)
146 Traceback (most recent call last):146 Traceback (most recent call last):
147 ...147 ...
148 AssertionError: There is no plural form #1 for Spanish (es) language148 AssertionError: There is no plural form #1 for Spanish (es) language
149149
=== 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 @@
1017 if side_traits.other_side_traits.getFlag(self.context):1017 if side_traits.other_side_traits.getFlag(self.context):
1018 # The shared translation for the other side matches the current1018 # The shared translation for the other side matches the current
1019 # one.1019 # one.
1020 self.imported_translationmessage = self.context1020 self.other_translationmessage = None
1021 else:1021 else:
1022 self.imported_translationmessage = (1022 self.other_translationmessage = (
1023 self.context.potmsgset.getCurrentTranslation(1023 self.context.potmsgset.getCurrentTranslation(
1024 self.pofile.potemplate, self.pofile.language,1024 self.pofile.potemplate, self.pofile.language,
1025 side_traits.other_side_traits.side))1025 side_traits.other_side_traits.side))
10261026
1027 if self.context.potemplate is None:1027 if self.context.potemplate is None:
1028 # Shared translation is current.1028 # Current translation is shared.
1029 self.shared_translationmessage = None1029 self.shared_translationmessage = None
1030 else:1030 else:
1031 self.shared_translationmessage = (1031 # Current translation is diverged, find the shared one.
1032 shared_translationmessage = (
1032 self.context.potmsgset.getCurrentTranslation(1033 self.context.potmsgset.getCurrentTranslation(
1033 None, self.pofile.language, side_traits.side))1034 None, self.pofile.language, side_traits.side))
1034 if (self.shared_translationmessage ==1035 if (shared_translationmessage == self.other_translationmessage):
1035 self.imported_translationmessage):1036 # If it matches the other message, we don't care.
1036 # If it matches the imported message, we don't care.
1037 self.shared_translationmessage = None1037 self.shared_translationmessage = None
1038 else:
1039 self.shared_translationmessage = shared_translationmessage
10381040
1039 self.can_confirm_and_dismiss = False1041 self.can_confirm_and_dismiss = False
1040 self.can_dismiss_on_empty = False1042 self.can_dismiss_on_empty = False
1041 self.can_dismiss_on_plural = False1043 self.can_dismiss_on_plural = False
1042 self.can_dismiss_packaged = False
10431044
1044 # Initialize to True, allowing POFileTranslateView to override.1045 # Initialize to True, allowing POFileTranslateView to override.
1045 self.zoomed_in_view = True1046 self.zoomed_in_view = True
@@ -1093,15 +1094,12 @@
1093 self.current_series.distribution.displayname,1094 self.current_series.distribution.displayname,
1094 self.current_series.name)1095 self.current_series.name)
10951096
1096 side_traits = getUtility(ITranslationSideTraitsSet).getForTemplate(
1097 self.pofile.potemplate)
1098
1099 # Initialise the translation dictionaries used from the1097 # Initialise the translation dictionaries used from the
1100 # translation form.1098 # translation form.
1101 self.translation_dictionaries = []1099 self.translation_dictionaries = []
1102 for index in self.pluralform_indices:1100 for index in self.pluralform_indices:
1103 current_translation = self.getCurrentTranslation(index)1101 current_translation = self.getCurrentTranslation(index)
1104 imported_translation = self.getImportedTranslation(index)1102 other_translation = self.getOtherTranslation(index)
1105 shared_translation = self.getSharedTranslation(index)1103 shared_translation = self.getSharedTranslation(index)
1106 submitted_translation = self.getSubmittedTranslation(index)1104 submitted_translation = self.getSubmittedTranslation(index)
1107 if (submitted_translation is None and1105 if (submitted_translation is None and
@@ -1118,18 +1116,17 @@
1118 self.context.submitter == self.context.reviewer)1116 self.context.submitter == self.context.reviewer)
1119 is_same_date = (1117 is_same_date = (
1120 self.context.date_created == self.context.date_reviewed)1118 self.context.date_created == self.context.date_reviewed)
1121 if side_traits.other_side_traits.getFlag(self.context):1119 if self.other_translationmessage is None:
1122 # Imported one matches the current one.1120 other_submission = None
1123 imported_submission = None1121 else:
1124 elif self.imported_translationmessage is not None:
1125 pofile = (1122 pofile = (
1126 self.imported_translationmessage.ensureBrowserPOFile())1123 self.other_translationmessage.ensureBrowserPOFile())
1127 if pofile is None:1124 if pofile is None:
1128 imported_submission = None1125 other_submission = None
1129 else:1126 else:
1130 imported_submission = (1127 other_submission = (
1131 convert_translationmessage_to_submission(1128 convert_translationmessage_to_submission(
1132 message=self.imported_translationmessage,1129 message=self.other_translationmessage,
1133 current_message=self.context,1130 current_message=self.context,
1134 plural_form=index,1131 plural_form=index,
1135 pofile=pofile,1132 pofile=pofile,
@@ -1137,8 +1134,6 @@
1137 is_empty=False,1134 is_empty=False,
1138 packaged=True,1135 packaged=True,
1139 local_to_pofile=True))1136 local_to_pofile=True))
1140 else:
1141 imported_submission = None
11421137
1143 diverged_and_have_shared = (1138 diverged_and_have_shared = (
1144 self.context.potemplate is not None and1139 self.context.potemplate is not None and
@@ -1165,9 +1160,9 @@
1165 'current_translation': text_to_html(1160 'current_translation': text_to_html(
1166 current_translation, self.context.potmsgset.flags),1161 current_translation, self.context.potmsgset.flags),
1167 'submitted_translation': submitted_translation,1162 'submitted_translation': submitted_translation,
1168 'imported_translation': text_to_html(1163 'other_translation': text_to_html(
1169 imported_translation, self.context.potmsgset.flags),1164 other_translation, self.context.potmsgset.flags),
1170 'imported_translation_message': imported_submission,1165 'other_translation_message': other_submission,
1171 'shared_translation': text_to_html(1166 'shared_translation': text_to_html(
1172 shared_translation, self.context.potmsgset.flags),1167 shared_translation, self.context.potmsgset.flags),
1173 'shared_translation_message': shared_submission,1168 'shared_translation_message': shared_submission,
@@ -1181,10 +1176,9 @@
1181 self.context.makeHTMLID('translation_%d' % index),1176 self.context.makeHTMLID('translation_%d' % index),
1182 }1177 }
11831178
1184 if (not side_traits.other_side_traits.getFlag(self.context) and1179 if self.other_translationmessage is not None:
1185 self.imported_translationmessage is not None):
1186 translation_entry['html_id_imported_suggestion'] = (1180 translation_entry['html_id_imported_suggestion'] = (
1187 self.imported_translationmessage.makeHTMLID(1181 self.other_translationmessage.makeHTMLID(
1188 'suggestion'))1182 'suggestion'))
11891183
1190 if self.message_must_be_hidden:1184 if self.message_must_be_hidden:
@@ -1202,42 +1196,27 @@
1202 # HTML id for singular form of this message1196 # HTML id for singular form of this message
1203 self.html_id_singular = self.context.makeHTMLID('translation_0')1197 self.html_id_singular = self.context.makeHTMLID('translation_0')
12041198
1205 def _set_dismiss_flags(self, local_suggestions, imported):1199 def _set_dismiss_flags(self, local_suggestions):
1206 """Set dismissal flags.1200 """Set dismissal flags.
12071201
1208 The flags are all initialized as False.1202 The flags are all initialized as False.
12091203
1210 :param local_suggestions: The list of local suggestions.1204 :param local_suggestions: The list of local suggestions.
1211 :param imported: The imported (packaged) translation for this
1212 message or None if there is no such translation.
1213 """1205 """
1214 # Only official translators can dismiss anything.1206 # Only official translators can dismiss anything.
1215 if not self.user_is_official_translator:1207 if not self.user_is_official_translator:
1216 return1208 return
12171209
1218 if imported is not None:1210 # If there are no local suggestions, nothing can be dismissed.
1219 date_reviewed = self.context.date_reviewed1211 if len(local_suggestions) == 0:
1220 if date_reviewed is None:
1221 has_new_imported = True
1222 else:
1223 has_new_imported = imported.date_created > date_reviewed
1224 else:
1225 has_new_imported = False
1226
1227 # If there are no local suggestion or a newly imported string,
1228 # nothing can be dismissed.
1229 if not (len(local_suggestions) > 0 or has_new_imported):
1230 return1212 return
12311213
1232 # OK, let's set some flags.
1233 self.can_dismiss_packaged = has_new_imported
1234 if self.is_plural:1214 if self.is_plural:
1235 self.can_dismiss_on_plural = True1215 self.can_dismiss_on_plural = True
1216 elif self.getCurrentTranslation(0) is None:
1217 self.can_dismiss_on_empty = True
1236 else:1218 else:
1237 if self.getCurrentTranslation(0) is None:1219 self.can_confirm_and_dismiss = True
1238 self.can_dismiss_on_empty = True
1239 else:
1240 self.can_confirm_and_dismiss = True
12411220
1242 def _setOnePOFile(self, messages):1221 def _setOnePOFile(self, messages):
1243 """Return a list of messages that all have a browser_pofile set.1222 """Return a list of messages that all have a browser_pofile set.
@@ -1286,13 +1265,7 @@
12861265
1287 language = self.pofile.language1266 language = self.pofile.language
1288 potmsgset = self.context.potmsgset1267 potmsgset = self.context.potmsgset
1289 side_traits = getUtility(ITranslationSideTraitsSet).getForTemplate(1268 other = self.other_translationmessage
1290 self.pofile.potemplate)
1291
1292 if not side_traits.other_side_traits.getFlag(self.context):
1293 imported = self.imported_translationmessage
1294 else:
1295 imported = None
12961269
1297 # Show suggestions only when you can actually do something with them1270 # Show suggestions only when you can actually do something with them
1298 # (i.e. you are logged in and have access to at least submit1271 # (i.e. you are logged in and have access to at least submit
@@ -1308,7 +1281,7 @@
1308 key=operator.attrgetter("date_created"),1281 key=operator.attrgetter("date_created"),
1309 reverse=True)1282 reverse=True)
13101283
1311 self._set_dismiss_flags(local, imported)1284 self._set_dismiss_flags(local)
13121285
1313 for suggestion in local:1286 for suggestion in local:
1314 suggestion.setPOFile(self.pofile)1287 suggestion.setPOFile(self.pofile)
@@ -1360,8 +1333,8 @@
1360 # suggestion per plural form.1333 # suggestion per plural form.
1361 for index in self.pluralform_indices:1334 for index in self.pluralform_indices:
1362 self.seen_translations = set([self.context.translations[index]])1335 self.seen_translations = set([self.context.translations[index]])
1363 if imported:1336 if other is not None:
1364 self.seen_translations.add(imported.translations[index])1337 self.seen_translations.add(other.translations[index])
1365 local_suggestions = (1338 local_suggestions = (
1366 self._buildTranslationMessageSuggestions(1339 self._buildTranslationMessageSuggestions(
1367 'Suggestions', local, index, local_to_pofile=True))1340 'Suggestions', local, index, local_to_pofile=True))
@@ -1403,23 +1376,18 @@
1403 self.seen_translations = iterable_submissions.seen_translations1376 self.seen_translations = iterable_submissions.seen_translations
1404 return iterable_submissions1377 return iterable_submissions
14051378
1406 def getOfficialTranslation(self, index, is_current_upstream=False,1379 def getOfficialTranslation(self, index, is_other=False, is_shared=False):
1407 is_shared=False):1380 """Return current translation on either side for plural form 'index'."""
1408 """Return current or imported translation for plural form 'index'."""
1409 assert index in self.pluralform_indices, (1381 assert index in self.pluralform_indices, (
1410 'There is no plural form #%d for %s language' % (1382 'There is no plural form #%d for %s language' % (
1411 index, self.pofile.language.displayname))1383 index, self.pofile.language.displayname))
14121384
1413 if is_current_upstream:1385 if is_shared:
1414 if self.imported_translationmessage is None:
1415 return None
1416
1417 translation = self.imported_translationmessage.translations[index]
1418 elif is_shared:
1419 if self.shared_translationmessage is None:1386 if self.shared_translationmessage is None:
1420 return None1387 return None
1421
1422 translation = self.shared_translationmessage.translations[index]1388 translation = self.shared_translationmessage.translations[index]
1389 elif is_other and self.other_translationmessage is not None:
1390 translation = self.other_translationmessage.translations[index]
1423 else:1391 else:
1424 translation = self.context.translations[index]1392 translation = self.context.translations[index]
1425 # We store newlines as '\n', '\r' or '\r\n', depending on the1393 # We store newlines as '\n', '\r' or '\r\n', depending on the
@@ -1434,9 +1402,9 @@
1434 """Return the current translation for the pluralform 'index'."""1402 """Return the current translation for the pluralform 'index'."""
1435 return self.getOfficialTranslation(index)1403 return self.getOfficialTranslation(index)
14361404
1437 def getImportedTranslation(self, index):1405 def getOtherTranslation(self, index):
1438 """Return the imported translation for the pluralform 'index'."""1406 """Return the other-side translation for the pluralform 'index'."""
1439 return self.getOfficialTranslation(index, is_current_upstream=True)1407 return self.getOfficialTranslation(index, is_other=True)
14401408
1441 def getSharedTranslation(self, index):1409 def getSharedTranslation(self, index):
1442 """Return the shared translation for the pluralform 'index'."""1410 """Return the shared translation for the pluralform 'index'."""
@@ -1581,18 +1549,15 @@
1581 return 31549 return 3
15821550
1583 @property1551 @property
1552 def dismissable_button_class(self):
1553 """The class string that deactivates only buttons on dismissal."""
1554 return "%s_dismissable_button" % self.html_id
1555
1556 @property
1584 def dismissable_class(self):1557 def dismissable_class(self):
1585 """The class string for dismissable parts."""1558 """The class string for dismissable parts."""
1586 return "%s_dismissable %s_dismissable_button" % (1559 return "%s_dismissable %s" % (
1587 self.html_id, self.html_id)1560 self.html_id, self.dismissable_button_class)
1588
1589 @property
1590 def dismissable_class_packaged(self):
1591 """The class string for dismissable packaged translations."""
1592 if self.can_dismiss_packaged:
1593 return self.dismissable_class
1594 # Buttons are always dismissable.
1595 return "%s_dismissable_button" % self.html_id
15961561
15971562
1598class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):1563class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):
15991564
=== 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 @@
313313
314 >>> pofile_es = template.newPOFile('es')314 >>> pofile_es = template.newPOFile('es')
315 >>> translations = { 0: u'blah (es)' }315 >>> translations = { 0: u'blah (es)' }
316 >>> new_translation_message = potmsgset.updateTranslation(316 >>> new_translation_message = factory.makeCurrentTranslationMessage(
317 ... pofile_es, mark, translations, is_current_upstream=False,317 ... pofile_es, potmsgset, mark, translations=translations)
318 ... lock_timestamp=datetime.datetime.now(UTC))
319 >>> pofile_es.date_changed = d2000_01_01318 >>> pofile_es.date_changed = d2000_01_01
320319
321Create a Welsh PO file, with an active translation submission created on320Create a Welsh PO file, with an active translation submission created on
@@ -323,9 +322,8 @@
323322
324 >>> pofile_cy = template.newPOFile('cy')323 >>> pofile_cy = template.newPOFile('cy')
325 >>> translations = { 0: u'blah (cy)' }324 >>> translations = { 0: u'blah (cy)' }
326 >>> new_translation_message = potmsgset.updateTranslation(325 >>> new_translation_message = factory.makeCurrentTranslationMessage(
327 ... pofile_cy, mark, translations, is_current_upstream=False,326 ... pofile_cy, potmsgset, mark, translations=translations)
328 ... lock_timestamp=datetime.datetime.now(UTC))
329 >>> pofile_cy.date_changed = d2000_01_03327 >>> pofile_cy.date_changed = d2000_01_03
330 >>> transaction.commit()328 >>> transaction.commit()
331329
332330
=== 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 @@
542 ... u'%d contact', u'%d contacts')542 ... u'%d contact', u'%d contacts')
543 >>> pofile_es.plural_forms543 >>> pofile_es.plural_forms
544 2544 2
545 >>> message = plural_potmsgset.updateTranslation(pofile_es, foobar,545 >>> message = factory.makeCurrentTranslationMessage(
546 ... {0: u'foo %d', 1: None}, is_current_upstream=False,546 ... pofile_es, plural_potmsgset, foobar,
547 ... lock_timestamp=datetime.now(pytz.UTC))547 ... translations={0: u'foo %d', 1: None})
548 >>> message.is_complete548 >>> message.is_complete
549 False549 False
550 >>> message = plural_potmsgset.updateTranslation(pofile_es, foobar,550 >>> message = factory.makeCurrentTranslationMessage(
551 ... {0: None}, is_current_upstream=False,551 ... pofile_es, plural_potmsgset, foobar,
552 ... lock_timestamp=datetime.now(pytz.UTC))552 ... translations={0: None})
553 >>> message.is_complete553 >>> message.is_complete
554 False554 False
555555
@@ -580,18 +580,17 @@
580580
581The message we're looking at is translated to two plural forms.581The message we're looking at is translated to two plural forms.
582582
583 >>> message_with_two_forms = pm_potmsgset.updateTranslation(583 >>> message_with_two_forms = factory.makeCurrentTranslationMessage(
584 ... pm_translation, pm_template.owner, ['%d fu', '%d fuitl'],584 ... pm_translation, pm_potmsgset, pm_template.owner,
585 ... is_current_upstream=False, lock_timestamp=datetime.now(pytz.UTC))585 ... translations=['%d fu', '%d fuitl'])
586586
587When an otherwise identical translation with three comes along, the587When an otherwise identical translation with three comes along, the
588third form is ignored because it falls outside the current 2 forms.588third form is ignored because it falls outside the current 2 forms.
589The "new" translation message is the same one we already had.589The "new" translation message is the same one we already had.
590590
591 >>> message_with_three_forms = pm_potmsgset.updateTranslation(591 >>> message_with_three_forms = factory.makeCurrentTranslationMessage(
592 ... pm_translation, pm_template.owner,592 ... pm_translation, pm_potmsgset, pm_template.owner,
593 ... ['%d fu', '%d fuitl', '%d fuitlx'], is_current_upstream=False,593 ... translations=['%d fu', '%d fuitl', '%d fuitlx'])
594 ... lock_timestamp=datetime.now(pytz.UTC))
595 >>> message_with_three_forms == message_with_two_forms594 >>> message_with_three_forms == message_with_two_forms
596 True595 True
597596
@@ -602,10 +601,9 @@
602 >>> zap.pluralforms = 3601 >>> zap.pluralforms = 3
603 >>> zap.pluralexpression = 'n % 3'602 >>> zap.pluralexpression = 'n % 3'
604603
605 >>> message_with_three_forms = pm_potmsgset.updateTranslation(604 >>> message_with_three_forms = factory.makeCurrentTranslationMessage(
606 ... pm_translation, pm_template.owner,605 ... pm_translation, pm_potmsgset, pm_template.owner,
607 ... ['%d fu', '%d fuitl', '%d fuitlx'], is_current_upstream=False,606 ... translations=['%d fu', '%d fuitl', '%d fuitlx'])
608 ... lock_timestamp=datetime.now(pytz.UTC))
609 >>> message_with_three_forms == message_with_two_forms607 >>> message_with_three_forms == message_with_two_forms
610 False608 False
611609
@@ -618,9 +616,9 @@
618no new message is created. Instead, the closest existing match (the616no new message is created. Instead, the closest existing match (the
619one with two forms) is updated.617one with two forms) is updated.
620618
621 >>> message_with_one_form = pm_potmsgset.updateTranslation(619 >>> message_with_one_form = factory.makeCurrentTranslationMessage(
622 ... pm_translation, pm_template.owner, ['%d fu'],620 ... pm_translation, pm_potmsgset, pm_template.owner,
623 ... is_current_upstream=False, lock_timestamp=datetime.now(pytz.UTC))621 ... translations=['%d fu'])
624622
625 >>> message_with_one_form == message_with_two_forms623 >>> message_with_one_form == message_with_two_forms
626 True624 True
@@ -939,12 +937,12 @@
939 >>> spanish_pofile = alsa_potemplate.getPOFileByLang('es')937 >>> spanish_pofile = alsa_potemplate.getPOFileByLang('es')
940 >>> spanish = spanish_pofile.language938 >>> spanish = spanish_pofile.language
941939
942 >>> new_translation = translator_credits.updateTranslation(spanish_pofile,940 >>> new_translation = factory.makeCurrentTranslationMessage(
943 ... carlos, {0: u'Some Translator'}, is_current_upstream=True,941 ... spanish_pofile, translator_credits, carlos,
944 ... lock_timestamp=datetime.now(pytz.UTC))942 ... translations={0: u'Some Translator'})
945943
946 >>> current = translator_credits.getCurrentTranslationMessage(944 >>> current = translator_credits.getCurrentTranslation(
947 ... alsa_potemplate, spanish)945 ... alsa_potemplate, spanish, alsa_potemplate.translation_side)
948 >>> current.translations946 >>> current.translations
949 [u'Some Translator']947 [u'Some Translator']
950948
951949
=== 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 @@
19 >>> from pytz import timezone19 >>> from pytz import timezone
20 >>> def set_translation(message, pofile, text):20 >>> def set_translation(message, pofile, text):
21 ... """Set text to be a translation for message in pofile."""21 ... """Set text to be a translation for message in pofile."""
22 ... return message.updateTranslation(22 ... return factory.makeCurrentTranslationMessage(
23 ... pofile, pofile.potemplate.owner, {0: text},23 ... pofile, message, pofile.potemplate.owner,
24 ... is_current_upstream=False,24 ... translations={0: text})
25 ... lock_timestamp=datetime.now(timezone('UTC')))
2625
27 >>> def print_pofile_contents(pofile):26 >>> def print_pofile_contents(pofile):
28 ... """Return sorted list of (singular) translations in pofile."""27 ... """Return sorted list of (singular) translations in pofile."""
@@ -55,9 +54,9 @@
5554
56 >>> nl_message = set_translation(55 >>> nl_message = set_translation(
57 ... message, nl_pofile, "Maar dan in het Nederlands.")56 ... message, nl_pofile, "Maar dan in het Nederlands.")
57 >>> nl_message.is_current_upstream
58 True
58 >>> nl_message.is_current_ubuntu59 >>> nl_message.is_current_ubuntu
59 True
60 >>> nl_message.is_current_upstream
61 False60 False
62 >>> print nl_message.potmsgset.msgid_singular.msgid61 >>> print nl_message.potmsgset.msgid_singular.msgid
63 My goose is undercooked.62 My goose is undercooked.
@@ -89,8 +88,8 @@
89 ... '--potemplate=%s' % str(potemplate.id),88 ... '--potemplate=%s' % str(potemplate.id),
90 ... '--not-language',89 ... '--not-language',
91 ... '--language=%s' % 'de',90 ... '--language=%s' % 'de',
92 ... '--is-current-ubuntu=%s' % 'true',91 ... '--is-current-ubuntu=%s' % 'false',
93 ... '--is-current-upstream=%s' % 'false',92 ... '--is-current-upstream=%s' % 'true',
94 ... '--msgid=%s' % "My goose is undercooked.",93 ... '--msgid=%s' % "My goose is undercooked.",
95 ... '--origin=%s' % 'ROSETTAWEB',94 ... '--origin=%s' % 'ROSETTAWEB',
96 ... '--force',95 ... '--force',
9796
=== 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 @@
527 ... '+source/evolution/+pots/evolution-2.2/es/5/+translate')527 ... '+source/evolution/+pots/evolution-2.2/es/5/+translate')
528 >>> packaged = find_tag_by_id(browser.contents, 'msgset_134_packaged')528 >>> packaged = find_tag_by_id(browser.contents, 'msgset_134_packaged')
529 >>> print extract_text(packaged)529 >>> print extract_text(packaged)
530 Packaged: tarjetas530 Other: tarjetas
531531
532First, we look for an existing imported translation in evolution PO file532First, we look for an existing imported translation in evolution PO file
533in Ubuntu Hoary. We can't modify "imported" messages through web UI, so533in Ubuntu Hoary. We can't modify "imported" messages through web UI, so
534534
=== 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 @@
386 </tr>386 </tr>
387 </tal:has-submitter>387 </tal:has-submitter>
388388
389 <tal:imported_translation389 <tal:other_translation
390 define="390 define="
391 section_title string:Packaged:;391 section_title string:Other:;
392 submission translation_dictionary/imported_translation_message;392 submission translation_dictionary/other_translation_message;
393 dismissable view/dismissable_class_packaged;393 dismissable view/dismissable_button_class;
394 form_is_writeable view/form_is_writeable;394 form_is_writeable view/form_is_writeable;
395 user_is_official_translator view/user_is_official_translator;395 user_is_official_translator view/user_is_official_translator;
396 ">396 ">
397 <metal:suggestion397 <metal:suggestion
398 use-macro="context/@@+translations-macros/render-suggestion" />398 use-macro="context/@@+translations-macros/render-suggestion" />
399 </tal:imported_translation>399 </tal:other_translation>
400 <tal:shared_translation400 <tal:shared_translation
401 condition="translation_dictionary/shared_translation_message"401 condition="translation_dictionary/shared_translation_message"
402 define="402 define="
403 section_title string:Shared:;403 section_title string:Shared:;
404 submission translation_dictionary/shared_translation_message;404 submission translation_dictionary/shared_translation_message;
405 dismissable view/dismissable_class_packaged;405 dismissable view/dismissable_button_class;
406 form_is_writeable view/form_is_writeable;406 form_is_writeable view/form_is_writeable;
407 user_is_official_translator view/user_is_official_translator;407 user_is_official_translator view/user_is_official_translator;
408 ">408 ">

Subscribers

People subscribed via source and target branches