def _update(self, store, user=None, store_revision=None, submission_type=None, resolve_conflict=POOTLE_WINS, allow_add_and_obsolete=True): logging.debug(u"Updating %s", self.target_store.pootle_path) old_state = self.target_store.state if user is None: User = get_user_model() user = User.objects.get_system_user() update_revision = None changes = {} try: diff = StoreDiff(self.target_store, store, store_revision).diff() if diff is not None: update_revision = Revision.incr() changes = self.update_from_diff( store, store_revision, diff, update_revision, user, submission_type, resolve_conflict, allow_add_and_obsolete) finally: if old_state < PARSED: self.target_store.state = PARSED self.target_store.save() has_changed = any(x > 0 for x in changes.values()) if has_changed: log(u"[update] %s units in %s [revision: %d]" % (get_change_str(changes), self.target_store.pootle_path, (self.target_store.data.max_unit_revision or 0))) return update_revision, changes
def _update(self, store, user=None, store_revision=None, submission_type=None, resolve_conflict=POOTLE_WINS, allow_add_and_obsolete=True): old_state = self.target_store.state if user is None: User = get_user_model() user = User.objects.get_system_user() update_revision = None changes = {} try: diff = StoreDiff(self.target_store, store, store_revision).diff() if diff is not None: update_revision = Revision.incr() changes = self.update_from_diff(store, store_revision, diff, update_revision, user, submission_type, resolve_conflict, allow_add_and_obsolete) finally: if old_state < PARSED: self.target_store.state = PARSED self.target_store.save() has_changed = any(x > 0 for x in changes.values()) if has_changed: logger.info(u"[update] %s units in %s [revision: %d]", get_change_str(changes), self.target_store.pootle_path, (self.target_store.data.max_unit_revision or 0)) return update_revision, changes
def revert_units_edited(self): """Revert unit edits made by a user to previous edit. """ stores = set() # Revert unit target where user is the last submitter. for unit_change in self.user.submitted.select_related("unit").iterator(): unit = unit_change.unit stores.add(unit.store) # Find the last submission by different user that updated the # unit.target. edits = unit.get_edits().exclude(submitter=self.user) updates = {} unit_updates = {} if edits.exists(): last_edit = edits.latest("pk") unit_updates["target_f"] = last_edit.new_value updates["submitted_by_id"] = last_edit.submitter_id updates["submitted_on"] = last_edit.creation_time logger.debug("Unit edit reverted: %s", repr(unit)) else: # if there is no previous submissions set the target to "" and # set the unit.change.submitted_by to None unit_updates["target_f"] = "" updates["submitted_by"] = None updates["submitted_on"] = unit.creation_time logger.debug("Unit edit removed: %s", repr(unit)) # Increment revision unit_change.__class__.objects.filter(id=unit_change.id).update( **updates) unit.__class__.objects.filter(id=unit.id).update( revision=Revision.incr(), **unit_updates) return stores
def toggle_qualitycheck(self, check_id, false_positive, user): check = self.qualitycheck_set.get(id=check_id) if check.false_positive == false_positive: return self.revision = Revision.incr() self.save( reviewed_by=user) check.false_positive = false_positive check.save() # create submission old_value = MUTED new_value = UNMUTED if false_positive: old_value = UNMUTED new_value = MUTED update_time = make_aware(timezone.now()) sub = Submission( creation_time=update_time, translation_project=self.store.translation_project, submitter=user, field=SubmissionFields.NONE, unit=self, type=SubmissionTypes.WEB, old_value=old_value, new_value=new_value, quality_check=check) sub.save()
def revert_units_edited(self): """Revert unit edits made by a user to previous edit. """ stores = set() # Revert unit target where user is the last submitter. for unit in self.user.submitted.iterator(): stores.add(unit.store) # Find the last submission by different user that updated the # unit.target. edits = unit.get_edits().exclude(submitter=self.user) if edits.exists(): last_edit = edits.latest("pk") unit.target_f = last_edit.new_value unit.submitted_by_id = last_edit.submitter_id unit.submitted_on = last_edit.creation_time logger.debug("Unit edit reverted: %s", repr(unit)) else: # if there is no previous submissions set the target to "" and # set the unit.submitted_by to None unit.target_f = "" unit.submitted_by = None unit.submitted_on = unit.creation_time logger.debug("Unit edit removed: %s", repr(unit)) # Increment revision unit.revision = Revision.incr() unit.save() return stores
def revert_units_commented(self): """Revert comments made by user on units to previous comment or else just remove the comment. """ stores = set() # Revert unit comments where self.user is latest commenter. for unit_change in self.user.commented.select_related("unit").iterator(): unit = unit_change.unit stores.add(unit.store) # Find comments by other self.users comments = unit.get_comments().exclude(submitter=self.user) change = {} if comments.exists(): # If there are previous comments by others update the # translator_comment, commented_by, and commented_on last_comment = comments.latest('pk') translator_comment = last_comment.new_value change["commented_by_id"] = last_comment.submitter_id change["commented_on"] = last_comment.creation_time logger.debug("Unit comment reverted: %s", repr(unit)) else: translator_comment = "" change["commented_by"] = None change["commented_on"] = None logger.debug("Unit comment removed: %s", repr(unit)) unit_change.__class__.objects.filter(id=unit_change.id).update( **change) unit.__class__.objects.filter(id=unit.id).update( translator_comment=translator_comment, revision=Revision.incr()) return stores
def handle_unit_pre_save(**kwargs): unit = kwargs["instance"] auto_translated = False was_fuzzy = unit._frozen.state == FUZZY sysuser = get_user_model().objects.get_system_user() if unit.source_updated: # update source related fields unit.source_hash = md5(unit.source_f.encode("utf-8")).hexdigest() unit.source_length = len(unit.source_f) wc = unit.update_wordcount() if not wc and not bool(filter(None, unit.target_f.strings)): # auto-translate untranslated strings unit.target = unit.source unit.state = FUZZY auto_translated = True if unit.target_updated: # update target related fields unit.target_wordcount = unit.counter.count_words(unit.target_f.strings) unit.target_length = len(unit.target_f) if filter(None, unit.target_f.strings): if unit.state == UNTRANSLATED: unit.state = TRANSLATED else: # if it was TRANSLATED then set to UNTRANSLATED if unit.state > FUZZY: unit.state = UNTRANSLATED if was_fuzzy: # set reviewer data if FUZZY has been removed only and # translation hasn't been updated unit.reviewed_on = make_aware(timezone.now()) unit.reviewed_by = unit.reviewed_by or sysuser elif unit.state == FUZZY: # clear reviewer data if unit has been marked as FUZZY unit.reviewed_on = None unit.reviewed_by = None elif unit.state == UNTRANSLATED: # clear reviewer and translator data if translation # has been deleted unit.reviewed_on = None unit.reviewed_by = None unit.submitted_by = None unit.submitted_on = None # Updating unit from the .po file set its revision property to # a new value (the same for all units during its store updated) # since that change doesn't require further sync but note that # auto_translated units require further sync update_revision = (unit.revision is None or (not unit.revision_updated and (unit.updated and not auto_translated))) if update_revision: unit.revision = Revision.incr() if unit.index is None: unit.index = unit.store.max_index() + 1 unitid = uniqueid.get(unit.__class__)(unit) if unitid.changed: unit.setid(unitid.getid())
def increment_unsynced_unit_revision(self, update_revision): filter_by = { 'revision__gt': self.target_store.last_sync_revision, 'revision__lt': update_revision, 'state__gt': OBSOLETE} return self.target_store.unit_set.filter( **filter_by).update( revision=Revision.incr())
def increment_unsynced_unit_revision(self, update_revision): filter_by = { 'revision__gt': self.target_store.last_sync_revision, 'revision__lt': update_revision, 'state__gt': OBSOLETE} units = self.target_store.unit_set.filter(**filter_by) units.update(revision=Revision.incr()) return units.count()
def revert_units_reviewed(self): """Revert reviews made by user on suggestions to previous state. """ stores = set() pending = SuggestionState.objects.get(name="pending") # Revert reviews by this user. for review in self.user.get_suggestion_reviews().iterator(): suggestion = review.suggestion stores.add(suggestion.unit.store) if suggestion.user_id == self.user.id: # If the suggestion was also created by this user then remove # both review and suggestion. suggestion.delete() logger.debug("Suggestion removed: %s", (suggestion)) elif suggestion.reviewer_id == self.user.id: # If the suggestion is showing as reviewed by the user, then # set the suggestion back to pending and update # reviewer/review_time. suggestion.state = pending suggestion.reviewer = None suggestion.review_time = None suggestion.save() logger.debug("Suggestion reverted: %s", (suggestion)) # Remove the review. review.delete() for unit_change in self.user.reviewed.select_related("unit").iterator(): unit = unit_change.unit stores.add(unit.store) unit.suggestion_set.filter(reviewer=self.user).update( state=SuggestionState.objects.get(name="pending"), reviewer=None) unit_updates = {} updates = {} if not unit.target: unit_updates["state"] = UNTRANSLATED updates["reviewed_by"] = None updates["reviewed_on"] = None else: old_state_sub = unit.submission_set.exclude( submitter=self.user).filter( field=SubmissionFields.STATE).order_by( "-creation_time", "-pk").first() if old_state_sub: unit_updates["state"] = old_state_sub.new_value updates["reviewed_by"] = old_state_sub.submitter updates["reviewed_on"] = old_state_sub.creation_time logger.debug("Unit reviewed_by removed: %s", repr(unit)) unit_change.__class__.objects.filter(id=unit_change.id).update( **updates) # Increment revision unit.__class__.objects.filter(id=unit.id).update( revision=Revision.incr(), **unit_updates) return stores
def increment_unsynced_unit_revision(self, store_revision, update_revision): filter_by = { 'revision__gt': store_revision or 0, 'revision__lt': update_revision, 'state__gt': OBSOLETE } return self.target_store.unit_set.filter(**filter_by).update( revision=Revision.incr())
def toggle_qualitycheck(self, check_id, false_positive, user): check = self.qualitycheck_set.get(id=check_id) if check.false_positive == false_positive: return self.revision = Revision.incr() self.save(reviewed_by=user) toggle.send(check.__class__, instance=check, false_positive=false_positive)
def incr_unit_revision(self, uid_list): """Increments the revision for units within `uid_list`. :return: the amount of units for which the revision has been incremented. """ if not uid_list: return 0 return self.target_store.unit_set.filter(id__in=uid_list).update( revision=Revision.incr())
def increment_unsynced_unit_revision(self, update_revision): filter_by = { 'revision__gt': self.target_store.last_sync_revision, 'revision__lt': update_revision, 'state__gt': OBSOLETE} units = self.target_store.unit_set.filter(**filter_by) count = units.count() if count: # we update after here to trigger a stats update # for the store after doing Unit.objects.update() units.update(revision=Revision.incr()) return count
def increment_unsynced_unit_revision(self, update_revision): filter_by = { 'revision__gt': self.target_store.last_sync_revision, 'revision__lt': update_revision, 'state__gt': OBSOLETE} units = self.target_store.unit_set.filter(**filter_by) count = units.count() if count: # we update after here to trigger a stats update # for the store after doing Unit.objects.update() with update_data_after(self.target_store): units.update(revision=Revision.incr()) return count
def update_store(self, source, target): """Update a target Store from a given source Store""" source_revision = target.data.max_unit_revision + 1 differ = StoreDiff(target, source, source_revision) diff = differ.diff() if diff is None: return system = User.objects.get_system_user() update_revision = Revision.incr() return target.updater.update_from_diff(source, source_revision, diff, update_revision, system, SubmissionTypes.SYSTEM, SOURCE_WINS, True)
def revert_units_reviewed(self): """Revert reviews made by user on suggestions to previous state. """ stores = set() # Revert reviews by this user. for review in self.user.get_suggestion_reviews().iterator(): suggestion = review.suggestion stores.add(suggestion.unit.store) if suggestion.user_id == self.user.id: # If the suggestion was also created by this user then remove # both review and suggestion. suggestion.delete() logger.debug("Suggestion removed: %s", (suggestion)) elif suggestion.reviewer_id == self.user.id: # If the suggestion is showing as reviewed by the user, then # set the suggestion back to pending and update # reviewer/review_time. suggestion.state = SuggestionStates.PENDING suggestion.reviewer = None suggestion.review_time = None suggestion.save() logger.debug("Suggestion reverted: %s", (suggestion)) # Remove the review. review.delete() for unit in self.user.reviewed.iterator(): stores.add(unit.store) reviews = unit.get_suggestion_reviews().exclude( submitter=self.user) revision = None if reviews.exists(): previous_review = reviews.latest('pk') unit.reviewed_by_id = previous_review.submitter_id unit.reviewed_on = previous_review.creation_time logger.debug("Unit reviewed_by reverted: %s", repr(unit)) else: unit.reviewed_by = None unit.reviewed_on = None # Increment revision revision = Revision.incr() logger.debug("Unit reviewed_by removed: %s", repr(unit)) unit.revision = revision unit.save() return stores
def update_store(self, source, target): source_revision = target.get_max_unit_revision() + 1 differ = StoreDiff(target, source, source_revision) diff = differ.diff() if diff is None: return system = User.objects.get_system_user() update_revision = Revision.incr() return target.update_from_diff( source, source_revision, diff, update_revision, system, SubmissionTypes.SYSTEM, SOURCE_WINS, True)
def revert_units_reviewed(self): """Revert reviews made by user on suggestions to previous state. """ stores = set() pending = SuggestionState.objects.get(name="pending") # Revert reviews by this user. for review in self.user.get_suggestion_reviews().iterator(): suggestion = review.suggestion stores.add(suggestion.unit.store) if suggestion.user_id == self.user.id: # If the suggestion was also created by this user then remove # both review and suggestion. suggestion.delete() logger.debug("Suggestion removed: %s", (suggestion)) elif suggestion.reviewer_id == self.user.id: # If the suggestion is showing as reviewed by the user, then # set the suggestion back to pending and update # reviewer/review_time. suggestion.state = pending suggestion.reviewer = None suggestion.review_time = None suggestion.save() logger.debug("Suggestion reverted: %s", (suggestion)) # Remove the review. review.delete() for unit in self.user.reviewed.iterator(): stores.add(unit.store) unit.suggestion_set.filter(reviewer=self.user).update( state=SuggestionState.objects.get(name="pending"), reviewer=None) revision = None unit.reviewed_by = None unit.reviewed_on = None # Increment revision revision = Revision.incr() logger.debug("Unit reviewed_by removed: %s", repr(unit)) unit.revision = revision unit.save() return stores
def update_store(self, source, target): """Update a target Store from a given source Store""" source_revision = target.data.max_unit_revision + 1 differ = StoreDiff(target, source, source_revision) diff = differ.diff() if diff is None: return system = User.objects.get_system_user() update_revision = Revision.incr() with update_data_after(target): return target.updater.update_from_diff( source, source_revision, diff, update_revision, system, SubmissionTypes.SYSTEM, SOURCE_WINS, True)
def update(self, store, user=None, store_revision=None, submission_type=None): logging.debug(u"Updating %s", self.target_store.pootle_path) old_state = self.target_store.state if user is None: User = get_user_model() user = User.objects.get_system_user() update_revision = None changes = {} unsynced_uids = [] try: diff = StoreDiff(self.target_store, store, store_revision).diff() if diff is not None: update_revision = Revision.incr() changes, unsynced_uids = self.update_from_diff( store, store_revision, diff, update_revision, user, submission_type, ) finally: if old_state < PARSED: self.target_store.state = PARSED else: self.target_store.state = old_state has_changed = any(x > 0 for x in changes.values()) self.target_store.save(update_cache=has_changed) if has_changed: log(u"[update] %s units in %s [revision: %d]" % ( get_change_str(changes), self.target_store.pootle_path, self.target_store.get_max_unit_revision(), )) return update_revision, changes, unsynced_uids
def handle_unit_pre_save(**kwargs): unit = kwargs["instance"] auto_translated = False if unit.source_updated: # update source related fields wc = unit.counter.count_words(unit.source_f.strings) if not wc and not bool(filter(None, unit.target_f.strings)): # auto-translate untranslated strings unit.target = unit.source unit.state = FUZZY auto_translated = True if unit.target_updated: # update target related fields unit.target_wordcount = unit.counter.count_words( unit.target_f.strings) unit.target_length = len(unit.target_f) if filter(None, unit.target_f.strings): if unit.state == UNTRANSLATED: unit.state = TRANSLATED else: # if it was TRANSLATED then set to UNTRANSLATED if unit.state > FUZZY: unit.state = UNTRANSLATED # Updating unit from the .po file set its revision property to # a new value (the same for all units during its store updated) # since that change doesn't require further sync but note that # auto_translated units require further sync update_revision = ( unit.revision is None or (not unit.revision_updated and (unit.updated and not auto_translated))) if update_revision: unit.revision = Revision.incr() if unit.index is None: unit.index = unit.store.max_index() + 1 unitid = uniqueid.get(unit.__class__)(unit) if unitid.changed: unit.setid(unitid.getid())
def revert_units_state_changed(self): """Revert unit edits made by a user to previous edit. """ stores = set() # Delete orphaned submissions. self.user.submission_set.filter(unit__isnull=True).delete() for submission in self.user.get_unit_states_changed().iterator(): unit = submission.unit stores.add(unit.store) # We have to get latest by pk as on mysql precision is not to # microseconds - so creation_time can be ambiguous if submission != unit.get_state_changes().latest('pk'): # If the unit has been changed more recently we don't need to # revert the unit state. submission.delete() return submission.delete() other_submissions = (unit.get_state_changes() .exclude(submitter=self.user)) if other_submissions.exists(): new_state = other_submissions.latest('pk').new_value else: new_state = UNTRANSLATED if new_state != unit.state: if unit.state == FUZZY: unit.markfuzzy(False) elif new_state == FUZZY: unit.markfuzzy(True) unit.state = new_state # Increment revision unit.revision = Revision.incr() unit.save() logger.debug("Unit state reverted: %s", repr(unit)) return stores
def revert_units_state_changed(self): """Revert unit edits made by a user to previous edit. """ stores = set() # Delete orphaned submissions. self.user.submission_set.filter(unit__isnull=True).delete() for submission in self.user.get_unit_states_changed().iterator(): unit = submission.unit stores.add(unit.store) # We have to get latest by pk as on mysql precision is not to # microseconds - so creation_time can be ambiguous if submission != unit.get_state_changes().latest('pk'): # If the unit has been changed more recently we don't need to # revert the unit state. submission.delete() return submission.delete() other_submissions = (unit.get_state_changes() .exclude(submitter=self.user)) if other_submissions.exists(): new_state = other_submissions.latest('pk').new_value else: new_state = UNTRANSLATED if new_state != unit.state: if unit.state == FUZZY: unit.markfuzzy(False) elif new_state == FUZZY: unit.markfuzzy(True) unit.state = new_state # Increment revision unit.__class__.objects.filter(id=unit.id).update( revision=Revision.incr()) logger.debug("Unit state reverted: %s", repr(unit)) return stores
def save(self, *args, **kwargs): created = self.id is None source_updated = kwargs.pop("source_updated", None) or self._source_updated target_updated = kwargs.pop("target_updated", None) or self._target_updated state_updated = kwargs.pop("state_updated", None) or self._state_updated auto_translated = (kwargs.pop("auto_translated", None) or self._auto_translated) comment_updated = (kwargs.pop("comment_updated", None) or self._comment_updated) action = kwargs.pop("action", None) or getattr(self, "_save_action", None) if not hasattr(self, '_log_user'): User = get_user_model() self._log_user = User.objects.get_system_user() user = kwargs.pop("user", self._log_user) if created: action = UNIT_ADDED if source_updated: # update source related fields self.source_hash = md5(self.source_f.encode("utf-8")).hexdigest() self.source_length = len(self.source_f) self.update_wordcount(auto_translate=True) if target_updated: # update target related fields self.target_wordcount = count_words(self.target_f.strings) self.target_length = len(self.target_f) if filter(None, self.target_f.strings): if self.state == UNTRANSLATED: self.state = TRANSLATED action = action or TRANSLATION_ADDED else: action = action or TRANSLATION_CHANGED else: action = TRANSLATION_DELETED # if it was TRANSLATED then set to UNTRANSLATED if self.state > FUZZY: self.state = UNTRANSLATED # Updating unit from the .po file set its revision property to # a new value (the same for all units during its store updated) # since that change doesn't require further sync but note that # auto_translated units require further sync revision = kwargs.pop('revision', None) if revision is not None and not auto_translated: self.revision = revision elif target_updated or state_updated or comment_updated: self.revision = Revision.incr() if not created and action: action_log(user=self._log_user, action=action, lang=self.store.translation_project.language.code, unit=self.id, translation=self.target_f, path=self.store.pootle_path) was_fuzzy = (state_updated and self.state == TRANSLATED and action == TRANSLATION_CHANGED and not target_updated) if was_fuzzy: # set reviewer data if FUZZY has been removed only and # translation hasn't been updated self.reviewed_on = timezone.now() self.reviewed_by = self._log_user elif self.state == FUZZY: # clear reviewer data if unit has been marked as FUZZY self.reviewed_on = None self.reviewed_by = None elif self.state == UNTRANSLATED: # clear reviewer and translator data if translation # has been deleted self.reviewed_on = None self.reviewed_by = None self.submitted_by = None self.submitted_on = None super(Unit, self).save(*args, **kwargs) if action and action == UNIT_ADDED: action_log(user=self._log_user, action=action, lang=self.store.translation_project.language.code, unit=self.id, translation=self.target_f, path=self.store.pootle_path) self.add_initial_submission(user=user) if source_updated or target_updated: if not (created and self.state == UNTRANSLATED): self.update_qualitychecks() if self.istranslated(): self.update_tmserver() # done processing source/target update remove flag self._source_updated = False self._target_updated = False self._state_updated = False self._comment_updated = False self._auto_translated = False update_data.send(self.store.__class__, instance=self.store)
def save(self, *args, **kwargs): created = self.id is None source_updated = kwargs.pop("source_updated", None) or self._source_updated target_updated = kwargs.pop("target_updated", None) or self._target_updated state_updated = kwargs.pop("state_updated", None) or self._state_updated auto_translated = ( kwargs.pop("auto_translated", None) or self._auto_translated) comment_updated = ( kwargs.pop("comment_updated", None) or self._comment_updated) action = kwargs.pop("action", None) or getattr(self, "_save_action", None) if not hasattr(self, '_log_user'): User = get_user_model() self._log_user = User.objects.get_system_user() user = kwargs.pop("user", self._log_user) if created: action = UNIT_ADDED if source_updated: # update source related fields self.source_hash = md5(self.source_f.encode("utf-8")).hexdigest() self.source_length = len(self.source_f) self.update_wordcount(auto_translate=True) if target_updated: # update target related fields self.target_wordcount = count_words(self.target_f.strings) self.target_length = len(self.target_f) if filter(None, self.target_f.strings): if self.state == UNTRANSLATED: self.state = TRANSLATED action = action or TRANSLATION_ADDED else: action = action or TRANSLATION_CHANGED else: action = TRANSLATION_DELETED # if it was TRANSLATED then set to UNTRANSLATED if self.state > FUZZY: self.state = UNTRANSLATED # Updating unit from the .po file set its revision property to # a new value (the same for all units during its store updated) # since that change doesn't require further sync but note that # auto_translated units require further sync revision = kwargs.pop('revision', None) if revision is not None and not auto_translated: self.revision = revision elif target_updated or state_updated or comment_updated: self.revision = Revision.incr() if not created and action: action_log( user=self._log_user, action=action, lang=self.store.translation_project.language.code, unit=self.id, translation=self.target_f, path=self.store.pootle_path) was_fuzzy = ( state_updated and self.state == TRANSLATED and action == TRANSLATION_CHANGED and not target_updated) if was_fuzzy: # set reviewer data if FUZZY has been removed only and # translation hasn't been updated self.reviewed_on = timezone.now() self.reviewed_by = self._log_user elif self.state == FUZZY: # clear reviewer data if unit has been marked as FUZZY self.reviewed_on = None self.reviewed_by = None elif self.state == UNTRANSLATED: # clear reviewer and translator data if translation # has been deleted self.reviewed_on = None self.reviewed_by = None self.submitted_by = None self.submitted_on = None super(Unit, self).save(*args, **kwargs) if action and action == UNIT_ADDED: action_log( user=self._log_user, action=action, lang=self.store.translation_project.language.code, unit=self.id, translation=self.target_f, path=self.store.pootle_path) self.add_initial_submission(user=user) if source_updated or target_updated: if not (created and self.state == UNTRANSLATED): self.update_qualitychecks() if self.istranslated(): self.update_tmserver() # done processing source/target update remove flag self._source_updated = False self._target_updated = False self._state_updated = False self._comment_updated = False self._auto_translated = False update_data.send( self.store.__class__, instance=self.store)
def handle_unit_pre_save(**kwargs): unit = kwargs["instance"] auto_translated = False was_fuzzy = unit._frozen.state == FUZZY sysuser = get_user_model().objects.get_system_user() if unit.source_updated: # update source related fields unit.source_hash = md5(unit.source_f.encode("utf-8")).hexdigest() unit.source_length = len(unit.source_f) wc = unit.update_wordcount() if not wc and not bool(filter(None, unit.target_f.strings)): # auto-translate untranslated strings unit.target = unit.source unit.state = FUZZY auto_translated = True if unit.target_updated: # update target related fields unit.target_wordcount = unit.counter.count_words( unit.target_f.strings) unit.target_length = len(unit.target_f) if filter(None, unit.target_f.strings): if unit.state == UNTRANSLATED: unit.state = TRANSLATED else: # if it was TRANSLATED then set to UNTRANSLATED if unit.state > FUZZY: unit.state = UNTRANSLATED if was_fuzzy: # set reviewer data if FUZZY has been removed only and # translation hasn't been updated unit.reviewed_on = make_aware(timezone.now()) unit.reviewed_by = unit.reviewed_by or sysuser elif unit.state == FUZZY: # clear reviewer data if unit has been marked as FUZZY unit.reviewed_on = None unit.reviewed_by = None elif unit.state == UNTRANSLATED: # clear reviewer and translator data if translation # has been deleted unit.reviewed_on = None unit.reviewed_by = None unit.submitted_by = None unit.submitted_on = None # Updating unit from the .po file set its revision property to # a new value (the same for all units during its store updated) # since that change doesn't require further sync but note that # auto_translated units require further sync update_revision = ( unit.revision is None or (not unit.revision_updated and (unit.updated and not auto_translated))) if update_revision: unit.revision = Revision.incr() if unit.index is None: unit.index = unit.store.max_index() + 1 unitid = uniqueid.get(unit.__class__)(unit) if unitid.changed: unit.setid(unitid.getid())