Diff for "Translations/Specs/UpstreamImportIntoUbuntu/FixingIsImported/setCurrentTranslation"

Not logged in - Log In / Register

Differences between revisions 27 and 36 (spanning 9 versions)
Revision 27 as of 2010-06-09 13:55:30
Size: 5933
Editor: jtv
Comment:
Revision 36 as of 2010-06-19 03:51:36
Size: 6051
Editor: jtv
Comment:
Deletions are marked like this. Additions are marked like this.
Line 25: Line 25:
 1. '''Tracking''': the POFile's shared translation is also the other side's shared translation (including the case where neither side has a shared translation). The other side may still have diverged messages, as may other POFiles on the POFile's own side, but those are not relevant here. The "flag-stealing policy" determines whether a new translation should also be shared on the other side. So `setCurrentTranslation` may break the tracking or maintain it, but never cause divergence.  1. '''Tracking''': the POFile's shared translation is also the other side's shared translation (including the case where neither side has a shared translation). The other side may still have diverged messages, as may other POFiles on the POFile's own side, but those are not relevant here. The "merging policy" determines whether a new translation should also be shared on the other side. So `setCurrentTranslation` may break the tracking or maintain it, but never cause divergence.
Line 27: Line 27:
=== Capture the Flag ===

Open questions
:
 *
In the shared state, if the flag-stealing policy allows it, should `setCurrentTranslation` steal the other side's flag (and thus move to the tracking state) if the other side has no translation yet?
'''(NEW/CHANGED)''' Exception: In the shared state, if the other side has no shared translation and the merging policy allows it, `setCurrentTranslation` steals the other side's flag (and thus moves the message to the tracking state).
Line 92: Line 89:
⊕. MERGING POLICY determines if we need to do:
   Look for shared translation with the is_other flag set: 'other'
   If found, steal its flag. If not, take the flag anyway:
== Capture the Flag ==

Look for a shared translation with the `is_other` flag set: '`other`'.

*.
If the merging policy says so and the other side is untranslated, assume the other flag as well:
Line 96: Line 95:
    if other is not None:
       other.is_other = False
   new.is_other = True
    if other is None:
        new.is_other = True
}}}

⊕. Tracking. If the merging policy says so, steal the other flag:
{{{
other.is_other = False
    new.is_other = True
Line 107: Line 111:
Parenthesized elements are actually no-ops. Parenthesized elements are no-ops in their specific situations.
Line 111: Line 115:
||<|4>CURRENT || None || (Z)1 || (Z)4 || (Z)7 || (Z)4() ||
|| shared || B1 || B4 || B7 || B4 ||
||<|4>CURRENT || None || Z1* || Z4* || Z7* || Z4(*) ||
|| shared || B1* || B4* || B7* || B4(*) ||
Line 114: Line 118:
|| upstream shared || B1⊕ || B4⊕ || B7⊕ || Ø || || upstream shared || B1⊕ || B4⊕ || B7⊕ || (B4⊕) ||
Line 134: Line 138:
If the flag-stealing policy approves, the newly activated instruction will also receive the "other flag" if there is no current translation to steal it from. If the merging policy approves, the newly activated instruction will also receive the "other flag" if there is no current translation to steal it from.

Setting a translation

Assumptions

We're not setting a translation that's identical to the current one.

We've checked that lock_timestamp is newer than the last update date.

Messages have been validated against gettext (otherwise you wouldn't be setting them as current).

A diverged message cannot be both the current Ubuntu message and the current upstream message. Those would be diverged in different templates.

When we look for an "identical" message, we look for one that is either shared, or diverged in the same template that we're looking at. We completely ignore messages that are diverged to other templates.

Guiding principles

There are two sides to translation: the Ubuntu side and the upstream side. A POFile is always either on the one side or on the other, though it can share translations with the other side. Each side can have its own shared translations, and each POFile can have its own diverged translations.

For a given POTMsgSet in a given POFile, its relationship with the other translation side can be in one of three states:

  1. Diverged: the current translation in the POFile is diverged from the shared translation for the POFile's own side. New translations should stay diverged, unless they match existing shared translations (in which case the translation converges with the matching existing translation). So setCurrentTranslation may end or maintain a divergence, but never introduce a new one. It may however create a diverged clone of an existing translation message in order to maintain a divergence.

  2. Shared: the current translation is shared with other POFiles on the POFile's own side—but not with the other side. New translations should stay shared on the POFile's own side, but only converge with those on the other side if the new translation is identical to that side's shared translation. So setCurrentTranslation may keep the translation shared, or bring it into the "tracking" state described below.

  3. Tracking: the POFile's shared translation is also the other side's shared translation (including the case where neither side has a shared translation). The other side may still have diverged messages, as may other POFiles on the POFile's own side, but those are not relevant here. The "merging policy" determines whether a new translation should also be shared on the other side. So setCurrentTranslation may break the tracking or maintain it, but never cause divergence.

(NEW/CHANGED) Exception: In the shared state, if the other side has no shared translation and the merging policy allows it, setCurrentTranslation steals the other side's flag (and thus moves the message to the tracking state).

What happens to the existing current message

A: Deactivate & converge.

  If there is already a shared message identical to current:
    current.delete()
  else:
    current.is_current = False
    current.potemplate = None

B: Deactivate.

  current.is_current = False

Z: Do nothing. There is no incumbent message.

What happens to the new current message

Some numbers are unused because their scenarios have collapsed into other ones.

1. Create & activate.

create TM 'new'
new.is_current = True

2. Create, diverge, activate.

create TM 'new'
new.is_current = True
new.potemplate = current.potemplate

4. Activate.

new.is_current = True

5. (NEW/CHANGED) If other is not current, it's a suggestion. Diverge & activate. (If it is current, deactivating the old diverged current message has already unmasked it).

if not new.is_current: (2)

6. (NEW/CHANGED) If other is not already current, fork a diverged message. (If it is current, deactivating the old diverged current message has already unmasked it).

if not new.is_current:
    new.potemplate = current.potemplate
    new.is_current = True

7. Converge & activate.

new.potemplate = None # (watch for existing identical TM)
new.is_current = True

Capture the Flag

Look for a shared translation with the is_other flag set: 'other'.

*. If the merging policy says so and the other side is untranslated, assume the other flag as well:

    if other is None:
        new.is_other = True

⊕. Tracking. If the merging policy says so, steal the other flag:

    other.is_other = False
    new.is_other = True

By default, the policy should approve the change on is_other if working on upstream; or if working on Ubuntu but with privileges to edit both.

Execution matrix

Parenthesized elements are no-ops in their specific situations.

IDENTICAL EXISTING TM 'new'

None

shared

diverged

upstream shared

CURRENT

None

Z1*

Z4*

Z7*

Z4(*)

shared

B1*

B4*

B7*

B4(*)

diverged

A2

A5

A4

A6

upstream shared

B1⊕

B4⊕

B7⊕

(B4⊕)

Notes

A diverged message can mask a similar shared message as well. We tried to take this into account throughout, and believe we covered it. Conditionals in the numbered parts ("what happens to the new current message") may warrant splitting rows or columns later.

Karma is being handled.

Implementation notes

See lp:~jtv/launchpad/recife-552639

This implements two methods: one for setting the upstream translation, and one for setting the Ubuntu translation. An upstream translation also overrides Ubuntu translations; whether the converse also happens when translating in Ubuntu is determined by an optional argument.

The code calls the "current" message the "incumbent," and the "existing" message the "twin."

If the merging policy approves, the newly activated instruction will also receive the "other flag" if there is no current translation to steal it from.

Translations/Specs/UpstreamImportIntoUbuntu/FixingIsImported/setCurrentTranslation (last edited 2010-06-19 03:51:36 by jtv)