Пример #1
0
    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))
Пример #2
0
    def update_from_unit(self, unit, pos, created):
        """Update Unit from ttkit unit."""
        component = self.translation.component
        self.is_batch_update = True
        # Get unit attributes
        try:
            location = unit.locations
            flags = unit.flags
            target = unit.target
            source = unit.source
            context = unit.context
            comment = unit.comments
            state = self.get_unit_state(unit)
            previous_source = unit.previous_source
            content_hash = unit.content_hash
        except Exception as error:
            self.translation.component.handle_parse_error(
                error, self.translation)

        # Monolingual files handling (without target change)
        if not created and unit.template is not None and target == self.target:
            if source != self.source and state >= STATE_TRANSLATED:
                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
            else:
                # We should keep calculated flags if translation was
                # not changed outside
                previous_source = self.previous_source
                state = self.state

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_source = (source == self.source and context == self.context)
        same_state = (state == self.state and flags == self.flags)

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (location == self.location and flags == self.flags and same_source
                and same_target and same_state and comment == self.comment
                and pos == self.position and content_hash == self.content_hash
                and previous_source == self.previous_source):
            return

        # Ensure we track source string
        source_info, source_created = component.get_source(self.id_hash)

        self.__dict__['source_info'] = source_info

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

        # 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,
            same_state=same_state,
        )

        # Create change object for new source string
        if source_created:
            Change.objects.create(
                action=Change.ACTION_NEW_SOURCE,
                unit=self,
            )

        # Track updated sources for source checks
        if source_created or not same_source:
            component.updated_sources[self.id_hash] = self
Пример #3
0
    def update_from_unit(self, unit, pos, created, component):
        """Update Unit from ttkit unit."""
        # Get unit attributes
        location = unit.get_locations()
        flags = unit.get_flags()
        target = unit.get_target()
        source = unit.get_source()
        comment = unit.get_comments()
        state = self.get_unit_state(unit, created)
        previous_source = unit.get_previous_source()
        content_hash = unit.get_content_hash()

        # Monolingual files handling (without target change)
        if unit.template is not None and target == self.target:
            if source != self.source and state >= STATE_TRANSLATED:
                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
            else:
                # We should keep calculated flags if translation was
                # not changed outside
                previous_source = self.previous_source
                state = self.state

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_source = source == self.source
        same_state = (state == self.state and not created)

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (not created and location == self.location and flags == self.flags
                and same_source and same_target and same_state
                and comment == self.comment and pos == self.position
                and content_hash == self.content_hash
                and previous_source == self.previous_source):
            return

        # Ensure we track source string
        source_info, source_created = Source.objects.get_or_create(
            id_hash=self.id_hash, component=component)
        contentsum_changed = self.content_hash != content_hash

        self.__dict__['source_info'] = source_info

        # Store updated values
        self.position = pos
        self.location = location
        self.flags = flags
        self.source = source
        self.target = target
        self.state = state
        self.comment = comment
        self.content_hash = content_hash
        self.previous_source = previous_source
        self.priority = source_info.priority

        # 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,
            same_state=same_state,
        )

        # Create change object for new source string
        if source_created:
            Change.objects.create(
                action=Change.ACTION_NEW_SOURCE,
                unit=self,
            )
        if contentsum_changed:
            self.update_has_failing_check(recurse=False)
            self.update_has_comment()
            self.update_has_suggestion()

        # Track updated sources for source checks
        if source_created or not same_source:
            if self.id_hash not in component.updated_sources:
                component.updated_sources[self.id_hash] = []
            component.updated_sources[self.id_hash].append(self)
Пример #4
0
    def update_from_unit(self, unit, pos, created):
        """Update Unit from ttkit unit."""
        component = self.translation.component
        self.is_batch_update = True
        # Get unit attributes
        try:
            location = unit.locations
            flags = unit.flags
            target = unit.target
            self.check_valid(split_plural(target))
            source = unit.source
            self.check_valid(split_plural(source))
            context = unit.context
            self.check_valid([context])
            note = unit.notes
            previous_source = unit.previous_source
            content_hash = unit.content_hash
        except Exception as error:
            report_error(cause="Unit update error")
            self.translation.component.handle_parse_error(
                error, self.translation)

        # Ensure we track source string for bilingual
        if not self.translation.is_source:
            source_info = component.get_source(
                self.id_hash,
                source=source,
                target=source,
                context=context,
                content_hash=calculate_hash(source, context),
                position=0,
                location=location,
                flags=flags,
            )
            self.extra_context = source_info.extra_context
            self.extra_flags = source_info.extra_flags
            self.__dict__["source_info"] = source_info

        # Calculate state
        state = self.get_unit_state(unit, flags)
        self.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 unit.template is not None and target == self.target:
            if not same_source and state >= STATE_TRANSLATED:
                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

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_state = state == self.state and flags == self.flags

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (location == self.location and flags == self.flags and same_source
                and same_target and same_state and note == self.note
                and pos == self.position and content_hash == self.content_hash
                and previous_source == self.previous_source):
            return

        # Store updated values
        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.content_hash = content_hash
        self.previous_source = previous_source
        self.update_priority(save=False)

        # 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,
            same_state=same_state,
        )
        # Track updated sources for source checks
        if self.translation.is_template:
            component.updated_sources[self.id_hash] = self
        # Update unit labels
        if not self.translation.is_source:
            self.labels.set(self.source_info.labels.all())
        # 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,
            )
Пример #5
0
    def update_from_unit(self, unit, pos, created):
        """Update Unit from ttkit unit."""
        # Get unit attributes
        location = unit.get_locations()
        flags = unit.get_flags()
        target = unit.get_target()
        source = unit.get_source()
        comment = unit.get_comments()
        state = self.get_unit_state(unit, created)
        previous_source = unit.get_previous_source()
        content_hash = unit.get_content_hash()

        # Monolingual files handling (without target change)
        if unit.template is not None and target == self.target:
            if source != self.source and state == STATE_TRANSLATED:
                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
            else:
                # We should keep calculated flags if translation was
                # not changed outside
                previous_source = self.previous_source
                state = self.state

        # Update checks on fuzzy update or on content change
        same_content = (
            target == self.target and source == self.source
        )
        same_state = (state == self.state and not created)

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (not created and
                location == self.location and
                flags == self.flags and
                same_content and same_state and
                comment == self.comment and
                pos == self.position and
                content_hash == self.content_hash and
                previous_source == self.previous_source):
            return

        # Ensure we track source string
        source_info, source_created = Source.objects.get_or_create(
            id_hash=self.id_hash,
            component=self.translation.component
        )
        contentsum_changed = self.content_hash != content_hash

        # Store updated values
        self.position = pos
        self.location = location
        self.flags = flags
        self.source = source
        self.target = target
        self.state = state
        self.comment = comment
        self.content_hash = content_hash
        self.previous_source = previous_source
        self.priority = source_info.priority

        # 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,
            backend=True,
            same_content=same_content,
            same_state=same_state,
        )

        # Create change object for new source string
        if source_created:
            Change.objects.create(
                action=Change.ACTION_NEW_SOURCE,
                unit=self,
            )
        if contentsum_changed:
            self.update_has_failing_check(recurse=False)
            self.update_has_comment()
            self.update_has_suggestion()
Пример #6
0
    def update_from_unit(self, unit, pos, created):
        """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
            content_hash = unit.content_hash
        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:
            source_unit = component.get_source(
                self.id_hash,
                create={
                    "source": source,
                    "target": source,
                    "context": context,
                    "content_hash": calculate_hash(source, context),
                    "position": pos,
                    "note": note,
                    "location": location,
                    "flags": flags,
                },
            )
            if (not source_unit.source_updated
                    and not component.has_template() and
                (pos != source_unit.position
                 or location != source_unit.location
                 or flags != source_unit.flags or note != source_unit.note)):
                source_unit.position = pos
                source_unit.source_updated = True
                source_unit.location = location
                source_unit.flags = flags
                source_unit.note = note
                source_unit.save(
                    update_fields=["position", "location", "flags", "note"],
                    same_content=True,
                    run_checks=False,
                )
            self.source_unit = source_unit

        # Calculate state
        state = self.get_unit_state(unit, flags)
        self.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

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_state = state == self.state and flags == self.flags

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (not created and same_source and same_target and same_state
                and location == self.location and flags == self.flags
                and note == self.note and pos == self.position
                and content_hash == self.content_hash
                and previous_source == self.previous_source
                and self.source_unit == old_source_unit
                and old_source_unit is not None):
            return

        # Store updated values
        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.content_hash = content_hash
        self.previous_source = previous_source
        self.update_priority(save=False)

        # 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_hash] = 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,
            )
Пример #7
0
    def update_from_unit(self, unit, pos, created):
        """Update Unit from ttkit unit."""
        component = self.translation.component
        self.is_batch_update = True
        # Get unit attributes
        location = unit.locations
        flags = unit.flags
        target = unit.target
        source = unit.source
        context = unit.context
        comment = unit.comments
        state = self.get_unit_state(unit)
        previous_source = unit.previous_source
        content_hash = unit.content_hash

        # Monolingual files handling (without target change)
        if not created and unit.template is not None and target == self.target:
            if source != self.source and state >= STATE_TRANSLATED:
                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
            else:
                # We should keep calculated flags if translation was
                # not changed outside
                previous_source = self.previous_source
                state = self.state

        # Update checks on fuzzy update or on content change
        same_target = target == self.target
        same_source = (source == self.source and context == self.context)
        same_state = (state == self.state and flags == self.flags)

        # Check if we actually need to change anything
        # pylint: disable=too-many-boolean-expressions
        if (location == self.location and
                flags == self.flags and
                same_source and same_target and same_state and
                comment == self.comment and
                pos == self.position and
                content_hash == self.content_hash and
                previous_source == self.previous_source):
            return

        # Ensure we track source string
        source_info, source_created = component.get_source(self.id_hash)

        self.__dict__['source_info'] = source_info

        # Store updated values
        self.position = pos
        self.location = location
        self.flags = flags
        self.source = source
        self.target = target
        self.state = state
        self.context = context
        self.comment = comment
        self.content_hash = content_hash
        self.previous_source = previous_source
        self.priority = source_info.priority

        # 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,
            same_state=same_state,
        )

        # Create change object for new source string
        if source_created:
            Change.objects.create(
                action=Change.ACTION_NEW_SOURCE,
                unit=self,
            )

        # Track updated sources for source checks
        if source_created or not same_source:
            component.updated_sources[self.id_hash] = self