Merge lp:~henninge/launchpad/recife-bug-611674-convert-imports into lp:~launchpad/launchpad/recife
| Status: | Merged | ||||
|---|---|---|---|---|---|
| Approved by: | Данило Шеган on 2010-10-05 | ||||
| Approved revision: | no longer in the source branch. | ||||
| Merged at revision: | 9172 | ||||
| Proposed branch: | lp:~henninge/launchpad/recife-bug-611674-convert-imports | ||||
| Merge into: | lp:~launchpad/launchpad/recife | ||||
| Diff against target: |
595 lines (+321/-83) 8 files modified
lib/lp/translations/doc/poimport-script.txt (+2/-2) lib/lp/translations/doc/rosetta-karma.txt (+5/-4) lib/lp/translations/model/pofile.py (+3/-5) lib/lp/translations/stories/translations/30-rosetta-pofile-translation-gettext-error.txt (+12/-20) lib/lp/translations/utilities/sanitize.py (+2/-0) lib/lp/translations/utilities/tests/test_file_importer.py (+151/-3) lib/lp/translations/utilities/tests/test_sanitize.py (+14/-0) lib/lp/translations/utilities/translation_import.py (+132/-49) |
||||
| To merge this branch: | bzr merge lp:~henninge/launchpad/recife-bug-611674-convert-imports | ||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Данило Шеган (community) | 2010-09-30 | Approve on 2010-10-05 | |
|
Review via email:
|
|||
Description of the Change
Bug 611674
==========
Although the bug does not say so, this branch is about converting the import code to the new models and use the new methods for adding translations and marking them as current.
The main change is in FileImporter.
1. Add the new translation as a suggestion
2. Try to validate it
3. Approve the suggestion if it validates and has no conflicts.
A large part of the diff is made up of the new property "FileImporter.
Implementation details
-------
rosetta-karma.txt:
Because of the new scheme, import karma is now awarded for adding suggestions, not for approving them. Slightly different but not much.
30-rosetta-
I don't know why gettextpo mentions "msgid_plural" nowadays. This code will pass for both "msgid" and "msgid_plural".
sanitize.py, test_sanitize.py:
A test failed because a language returned "None" for pluralforms. I am not sure if that is a bug in itself.
translation_
The new methods translations_
The flow in storeStoreTrans
Tests
-----
I ran all lp.translations tests to find breakage but I think something like this would cover most of the import code:
bin/test -vvcm lp.translations -t poimport.txt -t poimport-script.txt -t test_file_importer -t test_sanitize -t stories.
Lint
----
Lint complains about bad indention in 30-rosetta-
| Henning Eggers (henninge) wrote : | # |
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +0000
> > +++ lib/lp/
> > @@ -282,9 +282,9 @@
> >
> > >>> from lp.services.
> > >>> esperanto = getUtility(
> > - >>> foos = potemplate['Foo %s'].getLocalTr
> > + >>> suggestions = potemplate['Foo %
> > s'].getLocalTra
> > ... potemplate, esperanto)
> > - >>> sorted(
> > + >>> sorted(
> > [u'Bar', u'Bars']
>
> I don't really like "sugg" much better than "foo" (though, "suggestions"
> instead of "foos" IS MUCH better :). How about "suggestion"?
Yeah, I didn't think it would fit. It does.
>
> > === modified file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
> > @@ -181,6 +181,8 @@
> >
> > # Expected plural forms should all exist and empty translations should
> > # be normalized to None.
> > + if pluralforms is None:
> > + pluralforms = 2
> > for pluralform in range(pluralforms):
> > if pluralform not in sanitized_
> > sanitized_
>
> What's the reasoning for this? Why not default to 1 instead (i.e.
> assume it's a message with no plurals at all)?
That's what Language does. I could remove it here and use language.
Also, there is something else I was wondering about. The function will fill in the missing plural forms with None, regardless of whether there is a msgid_plural or not. I don't remember if that is intended behavior. It does no harm but seems like a waste.
>
> > === modified file
> 'lib/lp/
> ...
> > +class FileImporterSha
> > + """Class test for the sharing operation of the FileImporter base
> class."""
> > + layer = LaunchpadZopele
> > +
> > + UPSTREAM = 0
> > + UBUNTU = 1
> > + LANGCODE = 'eo'
>
> I know this is how we usually used to do stuff, but today we should be
> able to also make languages and not depend on existing ones in the
> sampledata. For instance, if you really want to keep using 'eo', I'd
> suggest you do factory.
No, I am not intend on this. Actually I defined it here so that it does not appear in the code itself. Changed it to use a constructed Language.
>
> > + POFILE = dedent("""\
> > + msgid ""
> > + msgstr ""
> > + "PO-Revision-Date: 2005-05-03 20:41+0100\\n"
> > + "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
> > + "Content-Type: text/plain; charset=UTF-8\\n"
> > + "X-Launchpad-
> > +
> > + msgid "Thank You"
> > + msgstr "Dankon"
> > + ...
| Henning Eggers (henninge) wrote : | # |
Incremental diff.
| Данило Шеган (danilo) wrote : | # |
У пет, 01. 10 2010. у 14:43 +0000, Henning Eggers пише:
> That's what Language does. I could remove it here and use
> language.
> something else I was wondering about. The function will fill in the
> missing plural forms with None, regardless of whether there is a
> msgid_plural or not. I don't remember if that is intended behavior. It
> does no harm but seems like a waste.
Let's keep it simple for now and not touch anything. It definitely
sounds a bit wasteful, but it's not a big deal.
> > I know this is how we usually used to do stuff, but today we should be
> > able to also make languages and not depend on existing ones in the
> > sampledata. For instance, if you really want to keep using 'eo', I'd
> > suggest you do factory.
>
> No, I am not intend on this. Actually I defined it here so that it does
> not appear in the code itself. Changed it to use a constructed
> Language.
Cool, thanks.
> > > + if side == self.UPSTREAM:
> > > + potemplate = self.upstream_
> > > + else:
> > > + # Create a template in a source package and link the source
> > > + # package to the upstream series to enable sharing.
> > > + ubuntu = getUtility(
> > > + distroseries =
> > self.factory.
> > > + ubuntu.
> > > + sourcepackagename = self.factory.
> > > + potemplate = self.factory.
> > > + distroseries=
> > > + sourcepackagena
> > > + name=self.
> > > + self.factory.
> > > + sourcepackagena
> > > + distroseries=
> >
> > Why is this necessary? Is it not possible to reach a sourcepackage
> > without it?
>
> For some reason I cannot use sourcepackage.
Right, it's probably useful knowledge worth sharing across the
translations team at least. Knowing the background would be even better
because then we could reconstruct it in the future :)
> >
> > > + return entry
> > > +
> > > + def test_translator
> >
> > s/perSmissions/
You seem to have forgotten this bit.
> >
> > > + def test_templates_
> > > + # Sharing between upstream and Ubuntu was set up correctly.
> > > + entry = self._makeEntry
> > > + subset = getUtility(
> > > + distribution=
> > > + sourcepackagena
> > > + self.assertCont
> > > + [entry.potemplate, self.upstream_
> > > + list(subset.
> >
> > This looks a lot like a test for the code that's not really here,
> > doesn't it? :)
> >
> > Or, is it basicall...
| Henning Eggers (henninge) wrote : | # |
Am 05.10.2010 13:34, schrieb Данило Шеган:
>>>> + self.factory.
>>>> + sourcepackagena
>>>> + distroseries=
>>>
>>> Why is this necessary? Is it not possible to reach a sourcepackage
>>> without it?
>>
>> For some reason I cannot use sourcepackage.
>
> Right, it's probably useful knowledge worth sharing across the
> translations team at least. Knowing the background would be even better
> because then we could reconstruct it in the future :)
Hm, should I put a card in the backlog to research that?
>
>>>
>>>> + return entry
>>>> +
>>>> + def test_translator
>>>
>>> s/perSmissions/
>
> You seem to have forgotten this bit.
I did, thanks. ;)
> It'd still be nice to name the test so it reflects this: eg.
> "test_makeImpor
Renamed.
>
>>> Cool stuff. It's amazing how tests can be so simple for something this
>>> intricate. :)
>>
>> I see the smiley but I am not sure if you are making fun of me or not ... ;-/
>
> No, it's a smiley of happiness. Also a credit to your "factor out stuff
> that is not being tested" (your _makeImportEntry method).
Thank you. :-)
>>>> + @cachedproperty
>>>> + def translations_
>>>> + """Are symbolic msgids being used and these are the real ones?"""
>>>
>>> This sentence is a bit confusing. If I had no idea about what this is
>>> about, I'd have even less idea about it. :)
>>
>> OK, I tried better. ;-)
>
> I think "text" is a non-countable noun, so plural "texts" sounds weird:
It can be both. In this case it is countable
>>> This is actually very interesting, and I am happy to see that you
>>> extracted it out. It actually points out that the naming for
>>> "from_upstream" is not really perfect: it should probably be
>>> "from_maintainer" or "from_trusted" or something.
>>
>> Yes, Jeroen and I had talked about that, too. I think I like from_maintainer most.
>
> Let's add a card for that then.
Done.
>>> Oh, I just read up on any() :) It seems you can drop the comparison to
>>> the empty list as well.
>>
>> Good catch! I was a bit worried about using "any" because it tests for
>> "False" but we are looking for empty strings and "None". Although
>> these are by definition "False", too, our coding standards always
>> forbade implicit bool checks like these.
>
> That was kind of my worry as well, but I guess there's no harm since the
> intent is clear enough.
I put it on the reviewer meeting agenda.
>
>>> With the new model, there will be no way to know if a translation
>>> credits message didn't validate, but is the actual one from upstream.
>>> Something to think about.
>>
>> Hm, we could still validate and mark the message accordingly, even if
>> it is used, right? I am not sure, though, if translators expect us to
>> catch bugs like that. Maybe we should discard c-format flags on
>> translation credits POTMsgSets altogether?
>
> Definitely worth thinking about some more. How about you file a bug
> about this to look into after all the "re...

Hi Henning,
Thanks for tackling this. You've done a part of another card with this
job, so good job there :)
I feel it still needs a few improvements. See below.
review needs-fixing
> A large part of the diff is made up of the new property share_with_ other_side" and its tests. The property is a
> "FileImporter.
> boolean that reflects the sharing policy for translations from the
> file that is being imported. The policy depends on where the
> translations are coming from and what they are being imported into and
> on the permissions of the uploader. This was isolated to be able to
> change this policy later. (And I admit it could have warranted an
> extra branch.)
Interesting approach. We'll need to extract this even further, but
we've already got a separate card for that. You've just made that job
simpler (though, it's not going to be identical, since we'll have to
support the specifics of the web UI as well).
> === modified file 'lib/lp/ translations/ doc/poimport- script. txt' translations/ doc/poimport- script. txt 2010-09-21 16:19:47 translations/ doc/poimport- script. txt 2010-09-30 08:53:45 +0000 worlddata. interfaces. language import ILanguageSet ILanguageSet) .getLanguageByC ode('eo' ) anslationMessag es( nslationMessage s( [foo.msgstr0. translation for foo in foos]) [sugg.msgstr0. translation for sugg in suggestions])
> --- lib/lp/
> +0000
> +++ lib/lp/
> @@ -282,9 +282,9 @@
>
> >>> from lp.services.
> >>> esperanto = getUtility(
> - >>> foos = potemplate['Foo %s'].getLocalTr
> + >>> suggestions = potemplate['Foo %
> s'].getLocalTra
> ... potemplate, esperanto)
> - >>> sorted(
> + >>> sorted(
> [u'Bar', u'Bars']
I don't really like "sugg" much better than "foo" (though, "suggestions"
instead of "foos" IS MUCH better :). How about "suggestion"?
> === modified file 'lib/lp/ translations/ utilities/ sanitize. py' translations/ utilities/ sanitize. py 2010-08-16 09:01:35 +0000 translations/ utilities/ sanitize. py 2010-09-30 08:53:45 +0000 translations: translations[ pluralform] = None
> --- lib/lp/
> +++ lib/lp/
> @@ -181,6 +181,8 @@
>
> # Expected plural forms should all exist and empty translations should
> # be normalized to None.
> + if pluralforms is None:
> + pluralforms = 2
> for pluralform in range(pluralforms):
> if pluralform not in sanitized_
> sanitized_
What's the reasoning for this? Why not default to 1 instead (i.e.
assume it's a message with no plurals at all)?
> === modified file 'lib/lp/ translations/ utilities/ tests/test_ sanitize. py' translations/ utilities/ tests/test_ sanitize. py 2010-08-23 08:41:03 +0000 translations/ utilities/ tests/test_ sanitize. py 2010-09-30 08:53:45 +0000 translations_ from_webui( self.english, translations, 3)) translations_ pluralforms_ none(self) :
> --- lib/lp/
> +++ lib/lp/
> @@ -257,6 +257,20 @@
> expected_sanitized,
> sanitize_
>
> + def test_sanitize_
> + # Some languages don't provide a plural form, so 2 is assumed.
> + translations = {
> + 0: u'Plural form 0 ',
> + }
> + expected_sanitized = {
> + 0: u'Plural form 0',
> + ...