コード例 #1
0
    def translate(
        self,
        user,
        new_target,
        new_state,
        change_action=None,
        propagate: bool = True,
        author=None,
    ):
        """
        Store new translation of a unit.

        Propagation is currently disabled on import.
        """
        # Fetch current copy from database and lock it for update
        self.old_unit = Unit.objects.select_for_update().get(pk=self.pk)

        # Handle simple string units
        if isinstance(new_target, str):
            new_target = [new_target]

        # Apply autofixes
        if not self.translation.is_template:
            new_target, self.fixups = fix_target(new_target, self)

        # Update unit and save it
        self.target = join_plural(new_target)
        not_empty = bool(max(new_target))

        # Newlines fixup
        if "dos-eol" in self.all_flags:
            self.target = NEWLINES.sub("\r\n", self.target)

        if not_empty:
            self.state = new_state
        else:
            self.state = STATE_EMPTY
        self.original_state = self.state
        saved = self.save_backend(user,
                                  change_action=change_action,
                                  propagate=propagate,
                                  author=author)

        # Enforced checks can revert the state to needs editing (fuzzy)
        if (self.state >= STATE_TRANSLATED
                and self.translation.component.enforced_checks
                and self.all_checks_names
                & set(self.translation.component.enforced_checks)):
            self.state = self.original_state = STATE_FUZZY
            self.save(run_checks=False,
                      same_content=True,
                      update_fields=["state"])

        if (propagate and user and self.target != self.old_unit.target
                and self.state >= STATE_TRANSLATED
                and self.translation.component.is_glossary):
            transaction.on_commit(
                lambda: handle_unit_translation_change.delay(self.id, user.id))

        return saved
コード例 #2
0
ファイル: unit.py プロジェクト: brezerk/weblate
    def update_from_unit(self, unit, pos, created):  # noqa: C901
        """Update Unit from ttkit unit."""
        translation = self.translation
        component = translation.component
        self.is_batch_update = True
        self.source_updated = True
        # Get unit attributes
        try:
            location = unit.locations
            flags = unit.flags
            source = unit.source
            self.check_valid(split_plural(source))
            if not translation.is_template and translation.is_source:
                # Load target from source string for bilingual source translations
                target = source
            else:
                target = unit.target
                self.check_valid(split_plural(target))
            context = unit.context
            self.check_valid([context])
            note = unit.notes
            previous_source = unit.previous_source
        except Exception as error:
            report_error(cause="Unit update error")
            translation.component.handle_parse_error(error, translation)

        # Ensure we track source string for bilingual, this can not use
        # Unit.is_source as that depends on source_unit attribute, which
        # we set here
        old_source_unit = self.source_unit
        if not translation.is_source:
            self.update_source_unit(component, source, context, pos, note,
                                    location, flags)

        # Calculate state
        state = self.get_unit_state(unit, flags)
        original_state = self.get_unit_state(unit, None)

        # Has source changed
        same_source = source == self.source and context == self.context

        # Monolingual files handling (without target change)
        if (not created and state != STATE_READONLY
                and unit.template is not None and target == self.target):
            if not same_source and state in (STATE_TRANSLATED, STATE_APPROVED):
                if self.previous_source == self.source and self.fuzzy:
                    # Source change was reverted
                    previous_source = ""
                    state = STATE_TRANSLATED
                else:
                    # Store previous source and fuzzy flag for monolingual
                    if previous_source == "":
                        previous_source = self.source
                    state = STATE_FUZZY
            elif self.state in (STATE_FUZZY, STATE_APPROVED):
                # We should keep calculated flags if translation was
                # not changed outside
                previous_source = self.previous_source
                state = self.state
                original_state = self.original_state

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_state = state == self.state and flags == self.flags
        same_metadata = (location == self.location and note == self.note
                         and pos == self.position)
        same_data = (not created and same_source and same_target and same_state
                     and original_state == self.original_state
                     and flags == self.flags
                     and previous_source == self.previous_source
                     and self.source_unit == old_source_unit
                     and old_source_unit is not None)

        # Check if we actually need to change anything
        if same_data and same_metadata:
            return

        # Store updated values
        self.original_state = original_state
        self.position = pos
        self.location = location
        self.flags = flags
        self.source = source
        self.target = target
        self.state = state
        self.context = context
        self.note = note
        self.previous_source = previous_source
        self.update_priority(save=False)

        # Metadata update only, these do not trigger any actions in Weblate and
        # are display only
        if same_data and not same_metadata:
            self.save(same_content=True, only_save=True)
            return

        # Sanitize number of plurals
        if self.is_plural:
            self.target = join_plural(self.get_target_plurals())

        if created:
            unit_pre_create.send(sender=self.__class__, unit=self)

        # Save into database
        self.save(
            force_insert=created,
            same_content=same_source and same_target,
            run_checks=not same_source or not same_target or not same_state,
        )
        # Track updated sources for source checks
        if translation.is_template:
            component.updated_sources[self.id] = self
        # Indicate source string change
        if not same_source and previous_source:
            Change.objects.create(
                unit=self,
                action=Change.ACTION_SOURCE_CHANGE,
                old=previous_source,
                target=self.source,
            )
        # Update translation memory if needed
        if (self.state >= STATE_TRANSLATED
                and (not translation.is_source or component.intermediate)
                and (created or not same_source or not same_target)):
            transaction.on_commit(
                lambda: handle_unit_translation_change.delay(self.id))