Merge lp:~jtv/launchpad/bug-662552-get-tm-or-dummy into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 11811
Proposed branch: lp:~jtv/launchpad/bug-662552-get-tm-or-dummy
Merge into: lp:launchpad
Diff against target: 674 lines (+102/-182)
10 files modified
lib/lp/translations/browser/pofile.py (+3/-22)
lib/lp/translations/browser/tests/translationmessage-views.txt (+27/-15)
lib/lp/translations/browser/translationmessage.py (+17/-44)
lib/lp/translations/doc/canonical_url_examples.txt (+4/-4)
lib/lp/translations/doc/potmsgset.txt (+7/-29)
lib/lp/translations/doc/translationmessage.txt (+13/-12)
lib/lp/translations/interfaces/potmsgset.py (+8/-8)
lib/lp/translations/model/potmsgset.py (+7/-11)
lib/lp/translations/model/translationmessage.py (+0/-7)
lib/lp/translations/tests/test_potmsgset.py (+16/-30)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-662552-get-tm-or-dummy
Reviewer Review Type Date Requested Status
Edwin Grubbs (community) code Approve
Review via email: mp+39467@code.launchpad.net

Commit message

Streamline IPOTMsgSet.getCurrentDummyTranslationMessage.

Description of the change

= Bug 662552: Streamline getCurrentDummyTranslationMessage =

We're getting timeouts on the POFile:+translate page, so I'm fixing up a bunch of relatively non-invasive things that it wastes time on.

In this case, it's IPOTMsgSet.getCurrentDummyTranslationMessage. This method returns a DummyTranslationMessage. With a few easily fixed exceptions in one doctest, every use of this method follows the same basic pattern:

    message = potmsgset.getCurrentTranslationMessage(
        pofile.potemplate, pofile.language)
    if message is None:
        message = potmsgset.getCurrentDummyTranslationMessage(
            pofile.potemplate, pofile.language)
    else:
        message.setPOFile(pofile)

(The message.setPOFile() part is a hack to get around the fact that some code still relies on TranslationMessage.pofile even though it's been removed from the schema; we now use an alternate which is meant to be valid only within the request).

In this branch I replace the entire usage pattern with a single new method:

    message = potmsgset.getCurrentTranslationMessageOrDummy(
        pofile)

I also eliminated a few assertions that guarded the integrity of this pattern along the way, doing several redundant database lookups to ensure that there is no real current translation message before creating a dummy. That pattern is now explicit, and enshrined in a single place in the code.

About half of the branch is actually lint cleanup. There's a bit of lint left, but that's all related to blank lines around free-standing comment blocks. I'm not yet convinced that "make lint" has a creditable complaint.

Jeroen

To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

Hi Jeroen,

This branch looks good. I just have one comment on an preexisting typo.

-Edwin

>=== modified file 'lib/lp/translations/browser/tests/translationmessage-views.txt'
>--- lib/lp/translations/browser/tests/translationmessage-views.txt 2010-10-18 22:24:59 +0000
>+++ lib/lp/translations/browser/tests/translationmessage-views.txt 2010-10-27 20:18:48 +0000
>@@ -1,4 +1,5 @@
>-= TranslationMessage View =
>+TranslationMessage View
>+=======================
>
> On this section, we are going to test the view class for an
> ITranslationMessage object.
>@@ -11,13 +12,14 @@
> >>> from lp.services.worlddata.interfaces.language import ILanguageSet
> >>> from lp.translations.publisher import TranslationsLayer
>
>-All the tests will be submitted as comming from Kurem, an editor for the POFile
>-that we are going to edit.
>+All the tests will be submitted as comming from Kurem, an editor for the

s/comming/coming/

>+POFile that we are going to edit.
>
> >>> login('<email address hidden>')
>
>
>-== No plural forms ==
>+No plural forms
>+---------------
>
> We are going to see what happens if we get an entry for a language
> without the plural form information.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/translations/browser/pofile.py'
--- lib/lp/translations/browser/pofile.py 2010-08-31 11:11:09 +0000
+++ lib/lp/translations/browser/pofile.py 2010-10-28 03:59:47 +0000
@@ -87,20 +87,7 @@
87 raise NotFoundError(87 raise NotFoundError(
88 "%r is not a valid sequence number." % name)88 "%r is not a valid sequence number." % name)
8989
90 # Need to check in our database whether we have already the requested90 return potmsgset.getCurrentTranslationMessageOrDummy(self.context)
91 # TranslationMessage.
92 translationmessage = potmsgset.getCurrentTranslationMessage(
93 self.context.potemplate, self.context.language)
94
95 if translationmessage is not None:
96 # Already have a valid POMsgSet entry, just return it.
97 translationmessage.setPOFile(self.context)
98 return translationmessage
99 else:
100 # Get a fake one so we don't create new TranslationMessage just
101 # because someone is browsing the web.
102 return potmsgset.getCurrentDummyTranslationMessage(
103 self.context.potemplate, self.context.language)
10491
10592
106class POFileFacets(POTemplateFacets):93class POFileFacets(POTemplateFacets):
@@ -846,14 +833,8 @@
846 "POTMsgSets on page not in ascending sequence order")833 "POTMsgSets on page not in ascending sequence order")
847 last = potmsgset834 last = potmsgset
848835
849 translationmessage = potmsgset.getCurrentTranslationMessage(836 translationmessage = (
850 self.context.potemplate, self.context.language)837 potmsgset.getCurrentTranslationMessageOrDummy(self.context))
851 if translationmessage is None:
852 translationmessage = (
853 potmsgset.getCurrentDummyTranslationMessage(
854 self.context.potemplate, self.context.language))
855 else:
856 translationmessage.setPOFile(self.context)
857 view = self._prepareView(838 view = self._prepareView(
858 CurrentTranslationMessageView, translationmessage,839 CurrentTranslationMessageView, translationmessage,
859 self.errors.get(potmsgset))840 self.errors.get(potmsgset))
860841
=== modified file 'lib/lp/translations/browser/tests/translationmessage-views.txt'
--- lib/lp/translations/browser/tests/translationmessage-views.txt 2010-10-18 22:24:59 +0000
+++ lib/lp/translations/browser/tests/translationmessage-views.txt 2010-10-28 03:59:47 +0000
@@ -1,4 +1,5 @@
1= TranslationMessage View =1TranslationMessage View
2=======================
23
3On this section, we are going to test the view class for an4On this section, we are going to test the view class for an
4ITranslationMessage object.5ITranslationMessage object.
@@ -11,13 +12,14 @@
11 >>> from lp.services.worlddata.interfaces.language import ILanguageSet12 >>> from lp.services.worlddata.interfaces.language import ILanguageSet
12 >>> from lp.translations.publisher import TranslationsLayer13 >>> from lp.translations.publisher import TranslationsLayer
1314
14All the tests will be submitted as comming from Kurem, an editor for the POFile15All the tests will be submitted as coming from Kurem, an editor for the
15that we are going to edit.16POFile that we are going to edit.
1617
17 >>> login('kurem@debian.cz')18 >>> login('kurem@debian.cz')
1819
1920
20== No plural forms ==21No plural forms
22---------------
2123
22We are going to see what happens if we get an entry for a language24We are going to see what happens if we get an entry for a language
23without the plural form information.25without the plural form information.
@@ -29,8 +31,7 @@
29 >>> potmsgset = pofile_tlh.potemplate.getPOTMsgSetByMsgIDText(31 >>> potmsgset = pofile_tlh.potemplate.getPOTMsgSetByMsgIDText(
30 ... u'evolution addressbook')32 ... u'evolution addressbook')
31 >>> current_translationmessage = (33 >>> current_translationmessage = (
32 ... potmsgset.getCurrentDummyTranslationMessage(34 ... potmsgset.getCurrentTranslationMessageOrDummy(pofile_tlh))
33 ... pofile_tlh.potemplate, pofile_tlh.language))
34 >>> translationmessage_page_view = create_view(35 >>> translationmessage_page_view = create_view(
35 ... current_translationmessage, "+translate", layer=TranslationsLayer)36 ... current_translationmessage, "+translate", layer=TranslationsLayer)
36 >>> translationmessage_page_view.initialize()37 >>> translationmessage_page_view.initialize()
@@ -46,7 +47,8 @@
46 False47 False
4748
4849
49== Basic checks ==50Basic checks
51------------
5052
51Now, we will use objects that we have in our database, instead of53Now, we will use objects that we have in our database, instead of
52dummy ones.54dummy ones.
@@ -79,7 +81,8 @@
79 False81 False
8082
8183
82== The subview: TranslationMessageView ==84The subview: TranslationMessageView
85-----------------------------------
8386
84For the next tests, we grab the subview which is what holds information87For the next tests, we grab the subview which is what holds information
85that pertains to the POMsgSet rendering itself:88that pertains to the POMsgSet rendering itself:
@@ -145,7 +148,8 @@
145 AssertionError: There is no plural form #1 for Spanish (es) language148 AssertionError: There is no plural form #1 for Spanish (es) language
146149
147150
148== Web presentation ==151Web presentation
152----------------
149153
150Some characters are presented specially in the Web interface, and there are154Some characters are presented specially in the Web interface, and there are
151functions to determine whether to advise translators about their presence.155functions to determine whether to advise translators about their presence.
@@ -226,7 +230,8 @@
226 >>> transaction.commit()230 >>> transaction.commit()
227231
228232
229== Submitting translations ==233Submitting translations
234-----------------------
230235
231A new translation is submitted through the view.236A new translation is submitted through the view.
232237
@@ -330,7 +335,8 @@
330 [u'Foo']335 [u'Foo']
331336
332337
333== Bogus translation submission ==338Bogus translation submission
339----------------------------
334340
335What would happen if we get a submit for another msgset that isn't being341What would happen if we get a submit for another msgset that isn't being
336considered?342considered?
@@ -362,7 +368,8 @@
362 True368 True
363369
364370
365== TranslationMessageSuggestions ==371TranslationMessageSuggestions
372-----------------------------
366373
367This class keeps all suggestions available for a concrete374This class keeps all suggestions available for a concrete
368ITranslationMessage.375ITranslationMessage.
@@ -529,7 +536,8 @@
529 0536 0
530537
531538
532== Sequence number of new shared POTMsgSets ==539Sequence number of new shared POTMsgSets
540----------------------------------------
533541
534Newly added shared POTMsgSets don't have their sequence field set, but542Newly added shared POTMsgSets don't have their sequence field set, but
535they do have sequence number when being displayed with translation543they do have sequence number when being displayed with translation
@@ -556,7 +564,9 @@
556 >>> subview.sequence564 >>> subview.sequence
557 1565 1
558566
559== Ordering with unset potemplate values ==567
568Ordering with unset potemplate values
569-------------------------------------
560570
561Fix for bug #371560: can be removed after message sharing cleanup is done.571Fix for bug #371560: can be removed after message sharing cleanup is done.
562Code still uses potmsgset.potemplate when getting a sequence number, and572Code still uses potmsgset.potemplate when getting a sequence number, and
@@ -596,7 +606,9 @@
596 ... server_url=server_url)606 ... server_url=server_url)
597 >>> pofile_view.initialize()607 >>> pofile_view.initialize()
598608
599== Sharing and diverging messages ==609
610Sharing and diverging messages
611------------------------------
600612
601When there is an existing shared translation, one gets an option613When there is an existing shared translation, one gets an option
602to diverge it when on a zoomed-in view (when looking that particular614to diverge it when on a zoomed-in view (when looking that particular
603615
=== modified file 'lib/lp/translations/browser/translationmessage.py'
--- lib/lp/translations/browser/translationmessage.py 2010-09-03 16:01:01 +0000
+++ lib/lp/translations/browser/translationmessage.py 2010-10-28 03:59:47 +0000
@@ -67,10 +67,6 @@
67 )67 )
68from lp.translations.interfaces.translationsperson import ITranslationsPerson68from lp.translations.interfaces.translationsperson import ITranslationsPerson
6969
70#
71# Exceptions and helper classes
72#
73
7470
75class POTMsgSetBatchNavigator(BatchNavigator):71class POTMsgSetBatchNavigator(BatchNavigator):
7672
@@ -143,9 +139,6 @@
143 return contents139 return contents
144140
145141
146#
147# Standard UI classes
148#
149class CurrentTranslationMessageFacets(POTemplateFacets):142class CurrentTranslationMessageFacets(POTemplateFacets):
150 usedfor = ITranslationMessage143 usedfor = ITranslationMessage
151144
@@ -176,9 +169,6 @@
176 return Link('../+export', text, icon='download')169 return Link('../+export', text, icon='download')
177170
178171
179#
180# Views
181#
182class CurrentTranslationMessageIndexView:172class CurrentTranslationMessageIndexView:
183 """A view to forward to the translation form."""173 """A view to forward to the translation form."""
184174
@@ -298,16 +288,16 @@
298288
299 if self.request.method == 'POST':289 if self.request.method == 'POST':
300 if self.user is None:290 if self.user is None:
301 raise UnexpectedFormData, (291 raise UnexpectedFormData(
302 'Anonymous users or users who are not accepting our '292 "Anonymous users or users who are not accepting our "
303 'licensing terms cannot do POST submissions.')293 "licensing terms cannot do POST submissions.")
304 translations_person = ITranslationsPerson(self.user)294 translations_person = ITranslationsPerson(self.user)
305 if (translations_person.translations_relicensing_agreement295 if (translations_person.translations_relicensing_agreement
306 is not None and296 is not None and
307 not translations_person.translations_relicensing_agreement):297 not translations_person.translations_relicensing_agreement):
308 raise UnexpectedFormData, (298 raise UnexpectedFormData(
309 'Users who do not agree to licensing terms '299 "Users who do not agree to licensing terms "
310 'cannot do POST submissions.')300 "cannot do POST submissions.")
311 try:301 try:
312 # Try to get the timestamp when the submitted form was302 # Try to get the timestamp when the submitted form was
313 # created. We use it to detect whether someone else updated303 # created. We use it to detect whether someone else updated
@@ -318,9 +308,9 @@
318 except zope_datetime.DateTimeError:308 except zope_datetime.DateTimeError:
319 # invalid format. Either we don't have the timestamp in the309 # invalid format. Either we don't have the timestamp in the
320 # submitted form or it has the wrong format.310 # submitted form or it has the wrong format.
321 raise UnexpectedFormData, (311 raise UnexpectedFormData(
322 'We didn\'t find the timestamp that tells us when was'312 "We didn't find the timestamp that tells us when was"
323 ' generated the submitted form.')313 " generated the submitted form.")
324314
325 # Check if this is really the form we are listening for..315 # Check if this is really the form we are listening for..
326 if self.request.form.get("submit_translations"):316 if self.request.form.get("submit_translations"):
@@ -543,7 +533,7 @@
543 elif fallback_language is not None:533 elif fallback_language is not None:
544 # If there's a standard alternative language and no534 # If there's a standard alternative language and no
545 # user-specified language was provided, preselect it.535 # user-specified language was provided, preselect it.
546 alternative_language = fallback_language536 alternative_language = fallback_language
547 second_lang_code = fallback_language.code537 second_lang_code = fallback_language.code
548 else:538 else:
549 # The second_lang_code is None and there is no fallback_language.539 # The second_lang_code is None and there is no fallback_language.
@@ -685,12 +675,8 @@
685 # current translation, suggestion or the new translation675 # current translation, suggestion or the new translation
686 # field.676 # field.
687 current_translation_message = (677 current_translation_message = (
688 potmsgset.getCurrentTranslationMessage(678 potmsgset.getCurrentTranslationMessageOrDummy(
689 self.pofile.potemplate, self.pofile.language))679 self.pofile))
690 if current_translation_message is None:
691 current_translation_message = (
692 potmsgset.getCurrentDummyTranslationMessage(
693 self.pofile.potemplate, self.pofile.language))
694 if (selected_translation_key !=680 if (selected_translation_key !=
695 msgset_ID_LANGCODE_translation_PLURALFORM_new):681 msgset_ID_LANGCODE_translation_PLURALFORM_new):
696 # It's either current translation or an existing682 # It's either current translation or an existing
@@ -890,14 +876,6 @@
890 template = ViewPageTemplateFile(876 template = ViewPageTemplateFile(
891 '../templates/currenttranslationmessage-translate-one.pt')877 '../templates/currenttranslationmessage-translate-one.pt')
892878
893 # Relevant instance variables:
894 # self.translations
895 # self.error
896 # self.sec_lang
897 # self.second_lang_potmsgset
898 # self.suggestion_blocks
899 # self.pluralform_indices
900
901 def __init__(self, current_translation_message, request,879 def __init__(self, current_translation_message, request,
902 plural_indices_to_store, translations, force_suggestion,880 plural_indices_to_store, translations, force_suggestion,
903 force_diverge, error, second_lang_code, form_is_writeable):881 force_diverge, error, second_lang_code, form_is_writeable):
@@ -1053,7 +1031,7 @@
10531031
1054 diverged_and_have_shared = (1032 diverged_and_have_shared = (
1055 self.context.potemplate is not None and1033 self.context.potemplate is not None and
1056 self.shared_translationmessage is not None) 1034 self.shared_translationmessage is not None)
1057 if diverged_and_have_shared:1035 if diverged_and_have_shared:
1058 pofile = self.shared_translationmessage.ensureBrowserPOFile()1036 pofile = self.shared_translationmessage.ensureBrowserPOFile()
1059 if pofile is None:1037 if pofile is None:
@@ -1152,10 +1130,10 @@
11521130
1153 def _setOnePOFile(self, messages):1131 def _setOnePOFile(self, messages):
1154 """Return a list of messages that all have a browser_pofile set.1132 """Return a list of messages that all have a browser_pofile set.
1155 1133
1156 If a pofile cannot be found for a message, it is not included in1134 If a pofile cannot be found for a message, it is not included in
1157 the resulting list.1135 the resulting list.
1158 """ 1136 """
1159 result = []1137 result = []
1160 for message in messages:1138 for message in messages:
1161 if message.browser_pofile is None:1139 if message.browser_pofile is None:
@@ -1167,7 +1145,7 @@
1167 message.setPOFile(pofile)1145 message.setPOFile(pofile)
1168 result.append(message)1146 result.append(message)
1169 return result1147 return result
1170 1148
1171 def _buildAllSuggestions(self):1149 def _buildAllSuggestions(self):
1172 """Builds all suggestions and puts them into suggestions_block.1150 """Builds all suggestions and puts them into suggestions_block.
11731151
@@ -1503,7 +1481,6 @@
1503 return "%s_dismissable_button" % self.html_id1481 return "%s_dismissable_button" % self.html_id
15041482
15051483
1506
1507class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):1484class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):
1508 """A view that displays a `TranslationMessage`, but zoomed in.1485 """A view that displays a `TranslationMessage`, but zoomed in.
15091486
@@ -1533,11 +1510,6 @@
1533 return None1510 return None
15341511
15351512
1536#
1537# Pseudo-content class
1538#
1539
1540
1541class TranslationMessageSuggestions:1513class TranslationMessageSuggestions:
1542 """See `ITranslationMessageSuggestions`."""1514 """See `ITranslationMessageSuggestions`."""
15431515
@@ -1591,6 +1563,7 @@
1591class Submission:1563class Submission:
1592 """A submission generated from a TranslationMessage"""1564 """A submission generated from a TranslationMessage"""
15931565
1566
1594def convert_translationmessage_to_submission(1567def convert_translationmessage_to_submission(
1595 message, current_message, plural_form, pofile, legal_warning_needed,1568 message, current_message, plural_form, pofile, legal_warning_needed,
1596 is_empty=False, packaged=False, local_to_pofile=False):1569 is_empty=False, packaged=False, local_to_pofile=False):
15971570
=== modified file 'lib/lp/translations/doc/canonical_url_examples.txt'
--- lib/lp/translations/doc/canonical_url_examples.txt 2010-07-30 12:56:27 +0000
+++ lib/lp/translations/doc/canonical_url_examples.txt 2010-10-28 03:59:47 +0000
@@ -71,8 +71,8 @@
71Even for a dummy one.71Even for a dummy one.
7272
73 >>> potmsgset = potemplate.getPOTMsgSetBySequence(20)73 >>> potmsgset = potemplate.getPOTMsgSetBySequence(20)
74 >>> translationmessage = potmsgset.getCurrentDummyTranslationMessage(74 >>> translationmessage = potmsgset.getCurrentTranslationMessageOrDummy(
75 ... pofile.potemplate, pofile.language)75 ... pofile)
76 >>> print canonical_url(translationmessage)76 >>> print canonical_url(translationmessage)
77 http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/2077 http://transl.../hoary/+source/evolution/+pots/evolution-2.2/es/20
7878
@@ -109,8 +109,8 @@
109Even for a dummy PO msgset109Even for a dummy PO msgset
110110
111 >>> potmsgset = potemplate.getPOTMsgSetBySequence(20)111 >>> potmsgset = potemplate.getPOTMsgSetBySequence(20)
112 >>> translationmessage = potmsgset.getCurrentDummyTranslationMessage(112 >>> translationmessage = potmsgset.getCurrentTranslationMessageOrDummy(
113 ... pofile.potemplate, pofile.language)113 ... pofile)
114 >>> print canonical_url(translationmessage)114 >>> print canonical_url(translationmessage)
115 http://translations.../evolution/trunk/+pots/evolution-2.2/es/20115 http://translations.../evolution/trunk/+pots/evolution-2.2/es/20
116116
117117
=== modified file 'lib/lp/translations/doc/potmsgset.txt'
--- lib/lp/translations/doc/potmsgset.txt 2010-10-26 10:31:37 +0000
+++ lib/lp/translations/doc/potmsgset.txt 2010-10-28 03:59:47 +0000
@@ -478,8 +478,8 @@
478 ... evolution_potemplate, pt_BR_dummypofile.language)478 ... evolution_potemplate, pt_BR_dummypofile.language)
479 >>> print current479 >>> print current
480 None480 None
481 >>> pt_BR_dummy_current = potmsgset.getCurrentDummyTranslationMessage(481 >>> pt_BR_dummy_current = potmsgset.getCurrentTranslationMessageOrDummy(
482 ... evolution_potemplate, pt_BR_dummypofile.language)482 ... pt_BR_dummypofile)
483 >>> pt_BR_dummy_current.plural_forms483 >>> pt_BR_dummy_current.plural_forms
484 1484 1
485 >>> pt_BR_dummy_current.translations485 >>> pt_BR_dummy_current.translations
@@ -508,8 +508,8 @@
508 >>> print apa_dummypofile.language.pluralforms508 >>> print apa_dummypofile.language.pluralforms
509 None509 None
510 >>> apa_dummy_current = (510 >>> apa_dummy_current = (
511 ... plural_potmsgset.getCurrentDummyTranslationMessage(511 ... plural_potmsgset.getCurrentTranslationMessageOrDummy(
512 ... evolution_potemplate, apa_dummypofile.language))512 ... apa_dummypofile))
513 >>> apa_dummy_current.plural_forms513 >>> apa_dummy_current.plural_forms
514 2514 2
515 >>> apa_dummy_current.translations515 >>> apa_dummy_current.translations
@@ -519,8 +519,9 @@
519519
520 >>> language_ru = getUtility(ILanguageSet).getLanguageByCode('ru')520 >>> language_ru = getUtility(ILanguageSet).getLanguageByCode('ru')
521 >>> ru_dummypofile = evolution_potemplate.getDummyPOFile(language_ru)521 >>> ru_dummypofile = evolution_potemplate.getDummyPOFile(language_ru)
522 >>> ru_dummy_current = plural_potmsgset.getCurrentDummyTranslationMessage(522 >>> ru_dummy_current = (
523 ... evolution_potemplate, ru_dummypofile.language)523 ... plural_potmsgset.getCurrentTranslationMessageOrDummy(
524 ... ru_dummypofile))
524525
525 >>> print ru_dummypofile.language.pluralforms526 >>> print ru_dummypofile.language.pluralforms
526 3527 3
@@ -925,29 +926,6 @@
925 0926 0
926927
927928
928POTMsgSet.getCurrentDummyTranslationMessage
929-------------------------------------------
930
931Sometimes, there are POTMsgSet objects with no translations to a language,
932and we need to get dummy objects which emulate them to do read operations.
933This method give us such dummy objects.
934
935 >>> spanish_in_mexico = getUtility(ILanguageSet).getLanguageByCode(
936 ... 'es_MX')
937 >>> potmsgset.getCurrentDummyTranslationMessage(
938 ... evolution_potemplate, spanish_in_mexico) is None
939 False
940
941But, if we already have a TranslationMessage for a POTMsgSet in our database,
942and we request a dummy one, that's broken and we detect it.
943
944 >>> potmsgset.getCurrentDummyTranslationMessage(
945 ... evolution_potemplate, spanish)
946 Traceback (most recent call last):
947 ...
948 AssertionError: There is already a translation message ...
949
950
951Suggestions for translator credits929Suggestions for translator credits
952----------------------------------930----------------------------------
953931
954932
=== modified file 'lib/lp/translations/doc/translationmessage.txt'
--- lib/lp/translations/doc/translationmessage.txt 2010-10-18 22:24:59 +0000
+++ lib/lp/translations/doc/translationmessage.txt 2010-10-28 03:59:47 +0000
@@ -10,6 +10,7 @@
10 >>> from lp.translations.interfaces.translationmessage import (10 >>> from lp.translations.interfaces.translationmessage import (
11 ... ITranslationMessage)11 ... ITranslationMessage)
12 >>> from lp.translations.interfaces.translator import ITranslatorSet12 >>> from lp.translations.interfaces.translator import ITranslatorSet
13 >>> from lp.translations.model.pofile import DummyPOFile
1314
14 >>> login('carlos@canonical.com')15 >>> login('carlos@canonical.com')
15 >>> pofile_es = factory.makePOFile(language_code='es')16 >>> pofile_es = factory.makePOFile(language_code='es')
@@ -18,16 +19,15 @@
1819
19This class links the translations submitted by a translator with the20This class links the translations submitted by a translator with the
20associated POFile and POTMsgSet. TranslationMessage and21associated POFile and POTMsgSet. TranslationMessage and
21DummyTranslationMessage both implement ITranslationMessage interface:22DummyTranslationMessage both implement ITranslationMessage:
2223
23 >>> translationmessage = factory.makeTranslationMessage(24 >>> translationmessage = factory.makeTranslationMessage(
24 ... potmsgset=potmsgset, pofile=pofile_es)25 ... potmsgset=potmsgset, pofile=pofile_es)
25 >>> verifyObject(ITranslationMessage, translationmessage)26 >>> verifyObject(ITranslationMessage, translationmessage)
26 True27 True
2728
28 >>> serbian = getUtility(ILanguageSet)['sr']29 >>> dummy_message = potmsgset.getCurrentTranslationMessageOrDummy(
29 >>> dummy_message = potmsgset.getCurrentDummyTranslationMessage(30 ... factory.makePOFile('xh'))
30 ... potemplate, serbian)
31 >>> verifyObject(ITranslationMessage, dummy_message)31 >>> verifyObject(ITranslationMessage, dummy_message)
32 True32 True
3333
@@ -48,18 +48,19 @@
48the translation, no matter the number of plural forms defined for the48the translation, no matter the number of plural forms defined for the
49language:49language:
5050
51 >>> serbian = getUtility(ILanguageSet)['sr']
51 >>> serbian.pluralforms52 >>> serbian.pluralforms
52 353 3
53 >>> current_sr = potmsgset.getCurrentDummyTranslationMessage(54 >>> current_sr = potmsgset.getCurrentTranslationMessageOrDummy(
54 ... potemplate, serbian)55 ... DummyPOFile(potemplate, serbian))
55 >>> current_sr.plural_forms56 >>> current_sr.plural_forms
56 157 1
5758
58 >>> divehi = getUtility(ILanguageSet)['dv']59 >>> divehi = getUtility(ILanguageSet)['dv']
59 >>> print divehi.pluralforms60 >>> print divehi.pluralforms
60 None61 None
61 >>> current_dv = potmsgset.getCurrentDummyTranslationMessage(62 >>> current_dv = potmsgset.getCurrentTranslationMessageOrDummy(
62 ... potemplate, divehi)63 ... DummyPOFile(potemplate, divehi))
63 >>> current_dv.plural_forms64 >>> current_dv.plural_forms
64 165 1
6566
@@ -73,8 +74,8 @@
73 u'plural'74 u'plural'
74 >>> serbian.pluralforms75 >>> serbian.pluralforms
75 376 3
76 >>> current_sr = potmsgset_plural.getCurrentDummyTranslationMessage(77 >>> current_sr = potmsgset_plural.getCurrentTranslationMessageOrDummy(
77 ... potemplate, serbian)78 ... DummyPOFile(potemplate, serbian))
78 >>> current_sr.plural_forms79 >>> current_sr.plural_forms
79 380 3
8081
@@ -83,8 +84,8 @@
8384
84 >>> print divehi.pluralforms85 >>> print divehi.pluralforms
85 None86 None
86 >>> current_dv = potmsgset_plural.getCurrentDummyTranslationMessage(87 >>> current_dv = potmsgset_plural.getCurrentTranslationMessageOrDummy(
87 ... potemplate, divehi)88 ... DummyPOFile(potemplate, divehi))
88 >>> current_dv.plural_forms89 >>> current_dv.plural_forms
89 290 2
9091
9192
=== modified file 'lib/lp/translations/interfaces/potmsgset.py'
--- lib/lp/translations/interfaces/potmsgset.py 2010-08-20 20:31:18 +0000
+++ lib/lp/translations/interfaces/potmsgset.py 2010-10-28 03:59:47 +0000
@@ -65,6 +65,7 @@
65class BrokenTextError(ValueError):65class BrokenTextError(ValueError):
66 """Exception raised when we detect values on a text that aren't valid."""66 """Exception raised when we detect values on a text that aren't valid."""
6767
68
68class POTMsgSetInIncompatibleTemplatesError(Exception):69class POTMsgSetInIncompatibleTemplatesError(Exception):
69 """Raised when a POTMsgSet appears in multiple incompatible templates.70 """Raised when a POTMsgSet appears in multiple incompatible templates.
7071
@@ -134,14 +135,13 @@
134 queries that search for credits messages.135 queries that search for credits messages.
135 """))136 """))
136137
137 def getCurrentDummyTranslationMessage(potemplate, language):138 def getCurrentTranslationMessageOrDummy(pofile):
138 """Return a DummyTranslationMessage for this message language.139 """Return the current `TranslationMessage`, or a dummy.
139140
140 :param potemplate: PO template you want a translation message for.141 :param pofile: PO template you want a translation message for.
141 :param language: language we want a dummy translations for.142 :return: The current translation for `self` in `pofile`, if
142143 there is one. Otherwise, a `DummyTranslationMessage` for
143 If a TranslationMessage for this language already exists,144 `self` in `pofile`.
144 an exception is raised.
145 """145 """
146146
147 def getCurrentTranslationMessage(potemplate, language):147 def getCurrentTranslationMessage(potemplate, language):
148148
=== modified file 'lib/lp/translations/model/potmsgset.py'
--- lib/lp/translations/model/potmsgset.py 2010-10-27 07:56:41 +0000
+++ lib/lp/translations/model/potmsgset.py 2010-10-28 03:59:47 +0000
@@ -42,7 +42,6 @@
42from canonical.launchpad.interfaces.lpstorm import ISlaveStore42from canonical.launchpad.interfaces.lpstorm import ISlaveStore
43from canonical.launchpad.readonly import is_read_only43from canonical.launchpad.readonly import is_read_only
44from lp.app.errors import UnexpectedFormData44from lp.app.errors import UnexpectedFormData
45from lp.translations.interfaces.pofile import IPOFileSet
46from lp.translations.interfaces.potmsgset import (45from lp.translations.interfaces.potmsgset import (
47 BrokenTextError,46 BrokenTextError,
48 IPOTMsgSet,47 IPOTMsgSet,
@@ -237,18 +236,15 @@
237 else:236 else:
238 return self.msgid_plural.msgid237 return self.msgid_plural.msgid
239238
240 def getCurrentDummyTranslationMessage(self, potemplate, language):239 def getCurrentTranslationMessageOrDummy(self, pofile):
241 """See `IPOTMsgSet`."""240 """See `IPOTMsgSet`."""
242241 current = self.getCurrentTranslationMessage(
243 pofile = potemplate.getPOFileByLang(language.code)242 pofile.potemplate, pofile.language)
244 if pofile is None:243 if current is None:
245 pofileset = getUtility(IPOFileSet)244 return DummyTranslationMessage(pofile, self)
246 pofile = pofileset.getDummy(potemplate, language)
247 else:245 else:
248 assert self.getCurrentTranslationMessage(potemplate,246 current.setPOFile(pofile)
249 language) is None, (247 return current
250 'There is already a translation message in our database.')
251 return DummyTranslationMessage(pofile, self)
252248
253 def _getUsedTranslationMessage(self, potemplate, language, current=True):249 def _getUsedTranslationMessage(self, potemplate, language, current=True):
254 """Get a translation message which is either used in250 """Get a translation message which is either used in
255251
=== modified file 'lib/lp/translations/model/translationmessage.py'
--- lib/lp/translations/model/translationmessage.py 2010-10-04 22:56:09 +0000
+++ lib/lp/translations/model/translationmessage.py 2010-10-28 03:59:47 +0000
@@ -115,13 +115,6 @@
115 implements(ITranslationMessage)115 implements(ITranslationMessage)
116116
117 def __init__(self, pofile, potmsgset):117 def __init__(self, pofile, potmsgset):
118 # Check whether we already have a suitable TranslationMessage, in
119 # which case, the dummy one must not be used.
120 assert potmsgset.getCurrentTranslationMessage(
121 pofile.potemplate,
122 pofile.language) is None, (
123 'This translation message already exists in the database.')
124
125 self.id = None118 self.id = None
126 self.browser_pofile = pofile119 self.browser_pofile = pofile
127 self.potemplate = pofile.potemplate120 self.potemplate = pofile.potemplate
128121
=== modified file 'lib/lp/translations/tests/test_potmsgset.py'
--- lib/lp/translations/tests/test_potmsgset.py 2010-10-26 10:31:37 +0000
+++ lib/lp/translations/tests/test_potmsgset.py 2010-10-28 03:59:47 +0000
@@ -13,17 +13,13 @@
13import pytz13import pytz
14import transaction14import transaction
15from zope.component import getUtility15from zope.component import getUtility
16from zope.security.proxy import (16from zope.security.proxy import removeSecurityProxy
17 isinstance as zope_isinstance,
18 removeSecurityProxy,
19 )
2017
21from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities18from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
22from canonical.testing.layers import ZopelessDatabaseLayer19from canonical.testing.layers import ZopelessDatabaseLayer
23from lp.app.enums import ServiceUsage20from lp.app.enums import ServiceUsage
24from lp.registry.interfaces.person import IPersonSet21from lp.registry.interfaces.person import IPersonSet
25from lp.registry.interfaces.product import IProductSet22from lp.registry.interfaces.product import IProductSet
26from lp.services.worlddata.interfaces.language import ILanguageSet
27from lp.testing import TestCaseWithFactory23from lp.testing import TestCaseWithFactory
28from lp.translations.interfaces.potemplate import IPOTemplateSet24from lp.translations.interfaces.potemplate import IPOTemplateSet
29from lp.translations.interfaces.potmsgset import (25from lp.translations.interfaces.potmsgset import (
@@ -165,31 +161,21 @@
165 translation.potemplate = self.devel_potemplate161 translation.potemplate = self.devel_potemplate
166 self.assertEquals(potmsgset.singular_text, ENGLISH_STRING)162 self.assertEquals(potmsgset.singular_text, ENGLISH_STRING)
167163
168 def test_getCurrentDummyTranslationMessage(self):164 def test_getCurrentTranslationMessageOrDummy_returns_real_tm(self):
169 """Test that a DummyTranslationMessage is correctly returned."""165 pofile = self.factory.makePOFile('nl')
170166 message = self.factory.makeTranslationMessage(
171 # When there is no POFile, we get a DummyTranslationMessage inside167 pofile=pofile, suggestion=False, is_imported=True)
172 # a DummyPOFile.168
173 serbian = getUtility(ILanguageSet).getLanguageByCode('sr')169 self.assertEqual(
174 dummy = self.potmsgset.getCurrentDummyTranslationMessage(170 message,
175 self.devel_potemplate, serbian)171 message.potmsgset.getCurrentTranslationMessageOrDummy(pofile))
176 self.assertTrue(zope_isinstance(dummy, DummyTranslationMessage))172
177173 def test_getCurrentTranslationMessageOrDummy_returns_dummy_tm(self):
178 # If a POFile exists, but there is no current translation message,174 pofile = self.factory.makePOFile('nl')
179 # a dummy translation message is returned.175 potmsgset = self.factory.makePOTMsgSet(pofile.potemplate)
180 sr_pofile = self.factory.makePOFile('sr', self.devel_potemplate)176
181 dummy = self.potmsgset.getCurrentDummyTranslationMessage(177 message = potmsgset.getCurrentTranslationMessageOrDummy(pofile)
182 self.devel_potemplate, serbian)178 self.assertIsInstance(message, DummyTranslationMessage)
183 self.assertTrue(zope_isinstance(dummy, DummyTranslationMessage))
184
185 # When there is a current translation message, an exception
186 # is raised.
187 translation = self.factory.makeTranslationMessage(
188 pofile=sr_pofile, potmsgset=self.potmsgset)
189 self.assertTrue(translation.is_current)
190 self.assertRaises(AssertionError,
191 self.potmsgset.getCurrentDummyTranslationMessage,
192 self.devel_potemplate, serbian)
193179
194 def test_getCurrentTranslationMessage(self):180 def test_getCurrentTranslationMessage(self):
195 """Test how shared and diverged current translation messages181 """Test how shared and diverged current translation messages