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))
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
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)
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, )
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()
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, )
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