Translations/Specs/UpstreamImportIntoUbuntu/FixingIsImported/setCurrentTranslation

Not logged in - Log In / Register

Clear message

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)