def purge(self): """Purges user from site reverting any changes that they have made. The following steps are taken: - Delete units created by user and without other submissions. - Revert units edited by user. - Revert reviews made by user. - Revert unit comments by user. - Revert unit state changes by user. - Delete any remaining submissions and suggestions. """ stores = set() with keep_data(): stores |= self.remove_units_created() stores |= self.revert_units_edited() stores |= self.revert_units_reviewed() stores |= self.revert_units_commented() stores |= self.revert_units_state_changed() # Delete remaining submissions. logger.debug("Deleting remaining submissions for: %s", self.user) self.user.submission_set.all().delete() # Delete remaining suggestions. logger.debug("Deleting remaining suggestions for: %s", self.user) self.user.suggestions.all().delete() for store in stores: update_data.send(store.__class__, instance=store)
def setup_templates(self): from pootle.core.contextmanagers import keep_data from pootle.core.signals import update_data from pootle_project.models import Project from pootle_translationproject.contextmanagers import update_tp_after from pytest_pootle.factories import ( LanguageDBFactory, TranslationProjectFactory) tps = [] with keep_data(): templates = LanguageDBFactory(code="templates") for project in Project.objects.all(): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=templates) # As there are no files on the FS we have to currently unobsolete # the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_template_stores(tp) tps.append(tp) for tp in tps: with update_tp_after(tp): for store in tp.stores.all(): update_data.send( store.__class__, instance=store)
def _callback_handler(sender, updated, **kwargs): bulk_tps = bulk_operations(models=(get_user_model(), UserTPScore, TPData, TPChecksData)) with keep_data(signals=(update_revisions, )): @receiver(update_revisions) def update_revisions_handler(**kwargs): if updated.revisions is None: updated.revisions = set() instance = kwargs.get("instance") if isinstance(instance, Store): updated.revisions.add(kwargs["instance"].parent.pootle_path) elif isinstance(instance, Directory): updated.revisions.add(kwargs["instance"].pootle_path) with bulk_tps: _update_stores(sender, updated) if updated.tp_data: update_data.send(sender.__class__, instance=sender) if updated.tp_scores: update_scores.send(sender.__class__, instance=sender, users=updated.score_users) if updated.revisions: update_revisions.send(Directory, paths=updated.revisions, keys=["stats", "checks"])
def purge(self): """Purges user from site reverting any changes that they have made. The following steps are taken: - Delete units created by user and without other submissions. - Revert units edited by user. - Revert reviews made by user. - Revert unit comments by user. - Revert unit state changes by user. - Delete any remaining submissions and suggestions. """ stores = set() with keep_data(): stores |= self.remove_units_created() stores |= self.revert_units_edited() stores |= self.revert_units_reviewed() stores |= self.revert_units_commented() stores |= self.revert_units_state_changed() # Delete remaining submissions. logger.debug("Deleting remaining submissions for: %s", self.user) self.user.submission_set.all().delete() # Delete remaining suggestions. logger.debug("Deleting remaining suggestions for: %s", self.user) self.user.suggestions.all().delete() for store in stores: update_data.send(store.__class__, instance=store)
def handle_suggestion_accepted(**kwargs): created = kwargs.get("created") suggestion = kwargs["instance"] if created or not suggestion.is_accepted: return update_data.send(suggestion.unit.store.__class__, instance=suggestion.unit.store)
def setup_templates(self): from pootle.core.contextmanagers import keep_data from pootle.core.signals import update_data from pootle_project.models import Project from pootle_translationproject.contextmanagers import update_tp_after from pytest_pootle.factories import (LanguageDBFactory, TranslationProjectFactory) tps = [] with keep_data(): templates = LanguageDBFactory(code="templates") for project in Project.objects.all(): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=templates) # As there are no files on the FS we have to currently unobsolete # the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_template_stores(tp) tps.append(tp) for tp in tps: with update_tp_after(tp): for store in tp.stores.all(): update_data.send(store.__class__, instance=store)
def test_data_store_critical_checks(store0): qc_qs = QualityCheck.objects qc_qs = (qc_qs.filter(unit__store=store0).filter( unit__state__gt=UNTRANSLATED).filter( category=Category.CRITICAL).exclude(false_positive=True)) check_count = qc_qs.count() assert (store0.data.critical_checks == check_count) unit = store0.units.exclude(qualitycheck__isnull=True, qualitycheck__name__in=["xmltags", "endpunc"]).first() unit.target = "<foo></bar>;" unit.save() unit_critical = unit.qualitycheck_set.filter( category=Category.CRITICAL).count() assert (store0.data.critical_checks == check_count + unit_critical) # lets make another unit false positive other_qc = unit.qualitycheck_set.exclude(name="xmltags").filter( category=Category.CRITICAL).first() other_qc.false_positive = True other_qc.save() # trigger refresh update_checks.send(unit.__class__, instance=unit, keep_false_positives=True) update_data.send(unit.store.__class__, instance=unit.store, keep_false_positives=True) assert (store0.data.critical_checks == check_count + unit_critical - 1)
def handle_suggestion_accepted(**kwargs): created = kwargs.get("created") suggestion = kwargs["instance"] if created or not suggestion.is_accepted: return update_data.send( suggestion.unit.store.__class__, instance=suggestion.unit.store)
def resurrect(self, save=True): self.obsolete = False self.file_mtime = datetime_min if self.last_sync_revision is None: self.last_sync_revision = self.data.max_unit_revision if save: self.save() update_data.send(self.__class__, instance=self)
def resurrect(self, save=True): self.obsolete = False self.file_mtime = datetime_min if self.last_sync_revision is None: self.last_sync_revision = self.data.max_unit_revision if save: self.save() update_data.send(self.__class__, instance=self)
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log(user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def update_data_after(sender, **kwargs): with keep_data(): yield if "kwargs" in kwargs: kwargs.update(kwargs.pop("kwargs")) update_data.send( sender.__class__, instance=sender, **kwargs)
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log( user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def update_tps_and_revisions(self, stores): tps = {} for store in stores: if store.translation_project_id not in tps: tps[store.translation_project_id] = store.translation_project update_revisions.send(store.__class__, instance=store, keys=["stats", "checks"]) for tp in tps.values(): update_data.send(tp.__class__, instance=tp)
def handle_suggestion_accepted(**kwargs): created = kwargs.get("created") suggestion = kwargs["instance"] if created or not suggestion.is_accepted: return suggestion.submission_set.add(*suggestion.unit.submission_set.filter( revision=suggestion.unit.revision, creation_time=suggestion.review_time)) store = suggestion.unit.store update_data.send(store.__class__, instance=store)
def save(self, *args, **kwargs): created = self.id is None created_by = kwargs.pop("created_by", None) changed_with = kwargs.pop("changed_with", None) or SubmissionTypes.SYSTEM commented_by = kwargs.pop("commented_by", None) commented_on = kwargs.pop("commented_on", None) reviewed_by = kwargs.pop("reviewed_by", None) reviewed_on = kwargs.pop("reviewed_on", None) submitted_by = kwargs.pop("submitted_by", None) submitted_on = kwargs.pop("submitted_on", None) sysuser = get_user_model().objects.get_system_user() created_by = created_by or submitted_by if reviewed_by: self.reviewed_by = reviewed_by if submitted_by: self.submitted_by = submitted_by super(Unit, self).save(*args, **kwargs) submitted_on = submitted_on or self.mtime if created: unit_source = self.unit_source.model(unit=self) unit_source.created_by = created_by or sysuser unit_source.created_with = changed_with submitted_on = self.creation_time submitted_by = unit_source.created_by elif self.source_updated: unit_source = self.unit_source.get() if created or self.source_updated: unit_source.source_hash = self.source_hash unit_source.source_length = self.source_length unit_source.source_wordcount = self.source_wordcount unit_source.save() if (self.updated or reviewed_by) and not self.changed: self.change = UnitChange( unit=self, changed_with=changed_with) if self.updated or reviewed_by: if changed_with is not None: self.change.changed_with = changed_with if self.comment_updated: self.change.commented_by = commented_by or sysuser self.change.commented_on = commented_on or submitted_on update_submit = ( (self.target_updated or self.source_updated) or not self.change.submitted_on) if update_submit: self.change.submitted_by = submitted_by or sysuser self.change.submitted_on = submitted_on if reviewed_by is not None: self.change.reviewed_by = reviewed_by or submitted_by if reviewed_on is not None or reviewed_by is not None: self.change.reviewed_on = reviewed_on or submitted_on self.change.save() update_data.send( self.store.__class__, instance=self.store)
def handle_suggestion_accepted(**kwargs): created = kwargs.get("created") suggestion = kwargs["instance"] if created or not suggestion.is_accepted: return suggestion.submission_set.add( *suggestion.unit.submission_set.filter( revision=suggestion.unit.revision, creation_time=suggestion.review_time)) store = suggestion.unit.store update_data.send(store.__class__, instance=store)
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log(user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) unit_query = self.unit_set.filter(state__gt=OBSOLETE) unit_query.update(state=OBSOLETE, index=0) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def handle_stores(self, stores): stores = Store.objects.filter(pootle_path__in=stores) tps = set() for store in stores: update_data.send(store.__class__, instance=store) logger.debug("Updated data for store: %s", store.pootle_path) tps.add(store.tp) for tp in tps: update_data.send(tp.__class__, instance=tp) logger.debug("Updated data for translation project: %s", tp.pootle_path)
def resurrect(self, save=True, resurrect_units=True): self.obsolete = False self.file_mtime = datetime_min if self.last_sync_revision is None: self.last_sync_revision = self.data.max_unit_revision if resurrect_units: for unit in self.unit_set.all(): unit.resurrect() unit.save() if save: self.save() update_data.send(self.__class__, instance=self)
def resurrect(self, save=True, resurrect_units=True): self.obsolete = False self.file_mtime = datetime_min if self.last_sync_revision is None: self.last_sync_revision = self.data.max_unit_revision if resurrect_units: for unit in self.unit_set.all(): unit.resurrect() unit.save() if save: self.save() update_data.send(self.__class__, instance=self)
def update_data(self, updated): if not updated: return if self.translation_project: tps = {self.translation_project.id: self.translation_project} else: tps = self.tp_qs.filter(id__in=updated.keys()).in_bulk() for tp, stores in updated.items(): tp = tps[tp] update_data.send(tp.__class__, instance=tp, object_list=tp.stores.filter(id__in=stores))
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log( user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) unit_query = self.unit_set.filter(state__gt=OBSOLETE) unit_query.update(state=OBSOLETE, index=0) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def reject_suggestion(self, suggestion): store = suggestion.unit.store suggestion.state = SuggestionStates.REJECTED suggestion.review_time = timezone.now() suggestion.reviewer = self.reviewer suggestion.save() self.create_submission(suggestion, SubmissionTypes.SUGG_REJECT, self.reviewer, creation_time=suggestion.review_time).save() update_data.send(store.__class__, instance=store)
def update_tps_and_revisions(self, stores): tps = {} for store in stores: if store.translation_project_id not in tps: tps[store.translation_project_id] = store.translation_project update_revisions.send( store.__class__, instance=store, keys=["stats", "checks"]) for tp in tps.values(): update_data.send( tp.__class__, instance=tp)
def reject_suggestion(self, suggestion): store = suggestion.unit.store suggestion.state = SuggestionStates.REJECTED suggestion.review_time = timezone.now() suggestion.reviewer = self.reviewer suggestion.save() self.create_submission( suggestion, SubmissionTypes.SUGG_REJECT, self.reviewer, creation_time=suggestion.review_time).save() update_data.send(store.__class__, instance=store)
def handle_stores(self, stores): stores = Store.objects.filter(pootle_path__in=stores) tps = set() for store in stores: update_data.send(store.__class__, instance=store) logger.debug( "Updated data for store: %s", store.pootle_path) tps.add(store.tp) for tp in tps: update_data.send(tp.__class__, instance=tp) logger.debug( "Updated data for translation project: %s", tp.pootle_path)
def reject_suggestion(self, suggestion): store = suggestion.unit.store suggestion.state_id = self.states["rejected"] suggestion.review_time = make_aware(timezone.now()) suggestion.reviewer = self.reviewer suggestion.save() unit = suggestion.unit if unit.changed: # if the unit is translated and suggestion was rejected # set the reviewer info unit.change.reviewed_by = self.reviewer unit.change.reviewed_on = suggestion.review_time unit.change.save() update_data.send(store.__class__, instance=store)
def test_data_tp_qc_stats(tp0): units = Unit.objects.filter( state__gt=OBSOLETE, store__translation_project=tp0) qc_qs = QualityCheck.objects qc_qs = ( qc_qs.filter(unit__store__translation_project=tp0) .filter(unit__state__gt=UNTRANSLATED) .filter(category=Category.CRITICAL) .exclude(false_positive=True)) check_count = qc_qs.count() store_data = tp0.data_tool.updater.get_store_data() assert ( store_data["critical_checks"] == tp0.data.critical_checks == check_count) unit = units.exclude( qualitycheck__isnull=True, qualitycheck__name__in=["xmltags", "endpunc"]).first() unit.target = "<foo></bar>;" unit.save() unit_critical = unit.qualitycheck_set.filter( category=Category.CRITICAL).count() store_data = tp0.data_tool.updater.get_store_data() tp0.data.refresh_from_db() assert ( store_data["critical_checks"] == tp0.data.critical_checks == check_count + unit_critical) # lets make another unit false positive other_qc = unit.qualitycheck_set.exclude( name="xmltags").filter(category=Category.CRITICAL).first() other_qc.false_positive = True other_qc.save() # trigger refresh update_checks.send( unit.__class__, instance=unit, keep_false_positives=True) update_data.send( unit.store.__class__, instance=unit.store, keep_false_positives=True) store_data = tp0.data_tool.updater.get_store_data() tp0.data.refresh_from_db() assert ( store_data["critical_checks"] == tp0.data.critical_checks == check_count + unit_critical - 1)
def clone_store(self, store, target_dir): """Clone given Store to target Directory""" cloned = target_dir.child_stores.create( name=store.name, translation_project=target_dir.translation_project) with keep_data(signals=(update_checks, update_data)): cloned.update(cloned.deserialize(store.serialize())) cloned.state = store.state cloned.filetype = store.filetype cloned.save() self.clone_checks(store, cloned) update_data.send(cloned.__class__, instance=cloned) return cloned
def reject_suggestion(self, suggestion): store = suggestion.unit.store rejected = SuggestionState.objects.get(name="rejected") suggestion.state_id = rejected.id suggestion.review_time = make_aware(timezone.now()) suggestion.reviewer = self.reviewer suggestion.save() unit = suggestion.unit if unit.changed: # if the unit is translated and suggestion was rejected # set the reviewer info unit.change.reviewed_by = self.reviewer unit.change.reviewed_on = suggestion.review_time unit.change.save() update_data.send(store.__class__, instance=store)
def update_data(self, updated): if not updated: return if self.translation_project: tps = { self.translation_project.id: self.translation_project} else: tps = self.tp_qs.filter( id__in=updated.keys()).in_bulk() for tp, stores in updated.items(): tp = tps[tp] update_data.send( tp.__class__, instance=tp, object_list=tp.stores.filter(id__in=stores))
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log(user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) lang = self.translation_project.language.code unit_query = self.unit_set.filter(state__gt=OBSOLETE) unit_ids = unit_query.values_list('id', flat=True) for unit_id in unit_ids: action_log(user='******', action=UNIT_OBSOLETE, lang=lang, unit=unit_id, translation='', path=self.pootle_path) unit_query.update(state=OBSOLETE, index=0) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def _handle_update_stores(sender, updated): @receiver(update_data, sender=sender.__class__) def update_tp_data_handler(**kwargs): updated.tp_data = True update_data.disconnect( update_tp_data_handler, sender=sender.__class__) @receiver(update_scores, sender=sender.__class__) def update_tp_scores_handler(**kwargs): updated.tp_scores = True update_scores.disconnect( update_tp_scores_handler, sender=sender.__class__) if updated.checks: with keep_data(suppress=(Store, ), signals=(update_data, )): @receiver(update_data, sender=Store) def extra_update_data_handler_(**kwargs): updated.data = updated.data or {} updated.data[kwargs["instance"].id] = kwargs["instance"] with bulk_operations(QualityCheck): for to_check in updated.checks.values(): store = to_check["store"] units = ( [unit for unit in to_check["units"]] if to_check["units"] else None) update_checks.send( store.__class__, instance=store, units=units) if updated.data: stores = updated.data.values() for store in stores: update_data.send( Store, instance=store) if updated.score_stores: for store in updated.score_stores.values(): update_scores.send( store.__class__, instance=store, users=updated.score_users)
def save(self, *args, **kwargs): created = self.id is None user = ( kwargs.pop("user", None) or get_user_model().objects.get_system_user()) reviewed_by = kwargs.pop("reviewed_by", None) or user changed_with = kwargs.pop("changed_with", None) or SubmissionTypes.SYSTEM super(Unit, self).save(*args, **kwargs) timestamp = self.mtime if created: unit_source = UnitSource(unit=self) unit_source.created_by = user unit_source.created_with = changed_with timestamp = self.creation_time elif self.source_updated: unit_source = self.unit_source if created or self.source_updated: unit_source.save() if self.updated and (created or not self.changed): self.change = UnitChange( unit=self, changed_with=changed_with) if self.updated or reviewed_by != user: if changed_with is not None: self.change.changed_with = changed_with if self.comment_updated: self.change.commented_by = user self.change.commented_on = timestamp update_submit = ( (self.target_updated or self.source_updated) or not self.change.submitted_on) if update_submit: self.change.submitted_by = user self.change.submitted_on = timestamp is_review = ( reviewed_by != user or (self.state_updated and not self.target_updated) or (self.state_updated and self.state == UNTRANSLATED)) if is_review: self.change.reviewed_by = reviewed_by self.change.reviewed_on = timestamp self.change.save() update_data.send( self.store.__class__, instance=self.store)
def save(self, *args, **kwargs): created = self.id is None user = ( kwargs.pop("user", None) or get_user_model().objects.get_system_user()) reviewed_by = kwargs.pop("reviewed_by", None) or user changed_with = kwargs.pop("changed_with", None) or SubmissionTypes.SYSTEM super(Unit, self).save(*args, **kwargs) timestamp = self.mtime if created: unit_source = UnitSource(unit=self) unit_source.created_by = user unit_source.created_with = changed_with timestamp = self.creation_time elif self.source_updated: unit_source = self.unit_source if created or self.source_updated: unit_source.save() if self.updated and (created or not self.changed): self.change = UnitChange( unit=self, changed_with=changed_with) if self.updated or reviewed_by != user: if changed_with is not None: self.change.changed_with = changed_with if self.comment_updated: self.change.commented_by = user self.change.commented_on = timestamp update_submit = ( (self.target_updated or self.source_updated) or not self.change.submitted_on) if update_submit: self.change.submitted_by = user self.change.submitted_on = timestamp is_review = ( reviewed_by != user or (self.state_updated and not self.target_updated) or (self.state_updated and self.state == UNTRANSLATED)) if is_review: self.change.reviewed_by = reviewed_by self.change.reviewed_on = timestamp self.change.save() update_data.send( self.store.__class__, instance=self.store)
def reject_suggestion(self, suggestion): store = suggestion.unit.store suggestion.state = SuggestionStates.REJECTED suggestion.review_time = make_aware(timezone.now()) suggestion.reviewer = self.reviewer suggestion.save() self.create_submission(suggestion, SubmissionTypes.SUGG_REJECT, self.reviewer, creation_time=suggestion.review_time).save() unit = suggestion.unit if unit.changed: # if the unit is translated and suggestion was rejected # set the reviewer info unit.change.reviewed_by = self.reviewer unit.change.reviewed_on = suggestion.review_time unit.change.save() update_data.send(store.__class__, instance=store)
def handle(self, **options): projects = options.get("projects") languages = options.get("languages") stores = options.get("stores") tps = TranslationProject.objects.all() if stores: return self.handle_stores(stores) if projects: tps = tps.filter(project__code__in=projects) if languages: tps = tps.filter(language__code__in=languages) for tp in tps: for store in tp.stores.all(): update_data.send(store.__class__, instance=store) logger.debug("Updated data for store: %s", store.pootle_path) update_data.send(tp.__class__, instance=tp) logger.debug("Updated data for translation project: %s", tp.pootle_path)
def param_update_store_test(request, tp0, member, member2): from pootle.core.contextmanagers import keep_data from pootle.core.signals import update_data store = StoreDBFactory(translation_project=tp0, parent=tp0.directory) with keep_data(): test = _setup_store_test(store, member, member2, UPDATE_STORE_TESTS[request.param]) update_data.send(store.__class__, instance=store) with keep_data(): update_store(test[0], units=test[1], store_revision=test[2], user=member2, resolve_conflict=test[3]) update_data.send(store.__class__, instance=store) return test
def handle_toggle_quality_check(**kwargs): check = kwargs["instance"] false_positive = kwargs["false_positive"] unit = check.unit reviewer = unit.change.reviewed_by unit_lifecycle = lifecycle.get(Unit)(unit) subs = [] check.false_positive = false_positive check.save() if check.false_positive: subs.append( unit_lifecycle.sub_mute_qc(quality_check=check, submitter=reviewer)) else: subs.append( unit_lifecycle.sub_unmute_qc(quality_check=check, submitter=reviewer)) unit_lifecycle.save_subs(subs=subs) store = unit.store update_data.send(store.__class__, instance=store)
def handle_toggle_quality_check(**kwargs): check = kwargs["instance"] false_positive = kwargs["false_positive"] unit = check.unit reviewer = unit.change.reviewed_by unit_lifecycle = lifecycle.get(Unit)(unit) subs = [] check.false_positive = false_positive check.save() if check.false_positive: subs.append( unit_lifecycle.sub_mute_qc(quality_check=check, submitter=reviewer)) else: subs.append( unit_lifecycle.sub_unmute_qc(quality_check=check, submitter=reviewer)) unit_lifecycle.save_subs(subs=subs) store = unit.store update_data.send(store.__class__, instance=store)
def _callback_handler(sender, updated, **kwargs): bulk_pootle = bulk_operations( models=( get_user_model(), UserTPScore, UserStoreScore, TPData, TPChecksData, StoreData, StoreChecksData)) with keep_data(signals=(update_revisions, )): with bulk_pootle: @receiver(update_revisions) def handle_update_revisions(**kwargs): updated.revisions = True if updated.checks: update_checks.send( sender.__class__, instance=sender, units=updated.checks, **kwargs) if updated.data: update_data.send( sender.__class__, instance=sender, **kwargs) if updated.scores: update_scores.send( sender.__class__, instance=sender, users=updated.scores, **kwargs) if updated.revisions: update_revisions.send( sender.__class__, instance=sender, keys=["stats", "checks"])
def handle(self, **options): projects = options.get("projects") languages = options.get("languages") stores = options.get("stores") tps = TranslationProject.objects.all() if stores: return self.handle_stores(stores) if projects: tps = tps.filter(project__code__in=projects) if languages: tps = tps.filter(language__code__in=languages) for tp in tps: for store in tp.stores.all(): update_data.send(store.__class__, instance=store) logger.debug( "Updated data for store: %s", store.pootle_path) update_data.send(tp.__class__, instance=tp) logger.debug( "Updated data for translation project: %s", tp.pootle_path)
def makeobsolete(self): """Make this store and all its units obsolete.""" store_log(user='******', action=STORE_OBSOLETE, path=self.pootle_path, store=self.id) lang = self.translation_project.language.code unit_query = self.unit_set.filter(state__gt=OBSOLETE) unit_ids = unit_query.values_list('id', flat=True) for unit_id in unit_ids: action_log(user='******', action=UNIT_OBSOLETE, lang=lang, unit=unit_id, translation='', path=self.pootle_path) unit_query.update(state=OBSOLETE, index=0) self.obsolete = True self.save() update_data.send(self.__class__, instance=self)
def test_data_store_critical_checks(store0): qc_qs = QualityCheck.objects qc_qs = ( qc_qs.filter(unit__store=store0) .filter(unit__state__gt=UNTRANSLATED) .filter(category=Category.CRITICAL) .exclude(false_positive=True)) check_count = qc_qs.count() assert ( store0.data.critical_checks == check_count) unit = store0.units.exclude( qualitycheck__isnull=True, qualitycheck__name__in=["xmltags", "endpunc"]).first() unit.target = "<foo></bar>;" unit.save() unit_critical = unit.qualitycheck_set.filter( category=Category.CRITICAL).count() assert ( store0.data.critical_checks == check_count + unit_critical) # lets make another unit false positive other_qc = unit.qualitycheck_set.exclude( name="xmltags").filter(category=Category.CRITICAL).first() other_qc.false_positive = True other_qc.save() # trigger refresh update_checks.send( unit.__class__, instance=unit, keep_false_positives=True) update_data.send( unit.store.__class__, instance=unit.store, keep_false_positives=True) assert ( store0.data.critical_checks == check_count + unit_critical - 1)
def _handle_update_stores(sender, updated): @receiver(update_data, sender=sender.__class__) def update_tp_data_handler(**kwargs): updated.tp_data = True update_data.disconnect(update_tp_data_handler, sender=sender.__class__) @receiver(update_scores, sender=sender.__class__) def update_tp_scores_handler(**kwargs): updated.tp_scores = True update_scores.disconnect(update_tp_scores_handler, sender=sender.__class__) if updated.checks: with keep_data(suppress=(Store, ), signals=(update_data, )): @receiver(update_data, sender=Store) def extra_update_data_handler_(**kwargs): updated.data = updated.data or {} updated.data[kwargs["instance"].id] = kwargs["instance"] with bulk_operations(QualityCheck): for to_check in updated.checks.values(): store = to_check["store"] units = ([unit for unit in to_check["units"]] if to_check["units"] else None) update_checks.send(store.__class__, instance=store, units=units) if updated.data: stores = updated.data.values() for store in stores: update_data.send(Store, instance=store) if updated.score_stores: for store in updated.score_stores.values(): update_scores.send(store.__class__, instance=store, users=updated.score_users)
def scan_languages(**kwargs): instance = kwargs["instance"] created = kwargs.get("created", False) raw = kwargs.get("raw", False) if not created or raw or instance.disabled: return if not instance.filetypes.all().exists(): instance.filetypes.add(Format.objects.get(name="po")) if instance.treestyle == 'pootle_fs': return for language in Language.objects.iterator(): with keep_data(): tp = create_translation_project(language, instance) if tp is not None: with keep_data(tp, suppress=(tp.__class__, )): result = tp.update_from_disk() if result: update_data.send(tp.__class__, instance=tp) update_scores.send(tp.__class__, instance=tp)
def _callback_handler(sender, updated, **kwargs): bulk_tps = bulk_operations( models=( get_user_model(), UserTPScore, TPData, TPChecksData)) with keep_data(signals=(update_revisions, )): @receiver(update_revisions) def update_revisions_handler(**kwargs): if updated.revisions is None: updated.revisions = set() instance = kwargs.get("instance") if isinstance(instance, Store): updated.revisions.add(kwargs["instance"].parent.pootle_path) elif isinstance(instance, Directory): updated.revisions.add(kwargs["instance"].pootle_path) with bulk_tps: _update_stores(sender, updated) if updated.tp_data: update_data.send( sender.__class__, instance=sender) if updated.tp_scores: update_scores.send( sender.__class__, instance=sender, users=updated.score_users) if updated.revisions: update_revisions.send( Directory, paths=updated.revisions, keys=["stats", "checks"])
def param_update_store_test(request, tp0, member, member2): from pootle.core.contextmanagers import keep_data from pootle.core.signals import update_data store = StoreDBFactory( translation_project=tp0, parent=tp0.directory) with keep_data(): test = _setup_store_test( store, member, member2, UPDATE_STORE_TESTS[request.param]) update_data.send(store.__class__, instance=store) with keep_data(): update_store( test[0], units=test[1], store_revision=test[2], user=member2, resolve_conflict=test[3]) update_data.send(store.__class__, instance=store) return test
def test_contextmanager_keep_data(store0, no_update_data_): result = [] @receiver(update_data, sender=Store) def update_data_handler(**kwargs): store = kwargs["instance"] result.append(store) update_data.send(Store, instance=store0) assert result == [store0] result.remove(store0) # with keep_data decorator signal is suppressed with keep_data(): update_data.send(Store, instance=store0) assert result == [] # works again now update_data.send(Store, instance=store0) assert result == [store0]
def test_contextmanager_keep_data_kwargs(store0, no_update_data): result = [] with no_update_data(): @receiver(update_data, sender=Store) def update_data_handler(**kwargs): result.append(kwargs) with update_store_after(store0): update_data.send(Store, instance=store0) # update_data was not called assert result == [] # update_data called now assert len(result) == 1 assert result[0]["instance"] == store0 # you can pass args to pass to the update receiver result.remove(result[0]) with update_store_after(store0, foo="apples", bar="oranges"): update_data.send(Store, instance=store0) assert result == [] assert len(result) == 1 assert result[0]["instance"] == store0 assert result[0]["foo"] == "apples" assert result[0]["bar"] == "oranges" # you can control the kwargs passed to send inside the context result.remove(result[0]) kwargs = dict(foo="apples", bar="oranges") with update_store_after(store0, kwargs=kwargs): update_data.send(Store, instance=store0) kwargs["foo"] = "plums" assert result == [] assert len(result) == 1 assert result[0]["instance"] == store0 assert result[0]["foo"] == "plums" assert result[0]["bar"] == "oranges"
def test_contextmanager_keep_data(store0, no_update_data_): result = [] @receiver(update_data, sender=Store) def update_data_handler(**kwargs): store = kwargs["instance"] result.append(store) update_data.send(Store, instance=store0) assert result == [store0] result.remove(store0) # with keep_data decorator signal is suppressed with keep_data(): update_data.send(Store, instance=store0) assert result == [] # works again now update_data.send(Store, instance=store0) assert result == [store0]
def test_contextmanager_keep_data_kwargs(store0, no_update_data_): result = [] @receiver(update_data, sender=Store) def update_data_handler(**kwargs): result.append(kwargs) with update_data_after(store0): update_data.send(Store, instance=store0) # update_data was not called assert result == [] # update_data called now assert len(result) == 1 assert result[0]["instance"] == store0 # you can pass args to pass to the update receiver result.remove(result[0]) with update_data_after(store0, foo="apples", bar="oranges"): update_data.send(Store, instance=store0) assert result == [] assert len(result) == 1 assert result[0]["instance"] == store0 assert result[0]["foo"] == "apples" assert result[0]["bar"] == "oranges" # you can control the kwargs passed to send inside the context result.remove(result[0]) kwargs = dict(foo="apples", bar="oranges") with update_data_after(store0, kwargs=kwargs): update_data.send(Store, instance=store0) kwargs["foo"] = "plums" assert result == [] assert len(result) == 1 assert result[0]["instance"] == store0 assert result[0]["foo"] == "plums" assert result[0]["bar"] == "oranges"
def handle_storedata_save(**kwargs): tp = kwargs["instance"].store.translation_project update_data.send(tp.__class__, instance=tp)
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_tp_data_create(sender, instance, created, **kwargs): if created: update_data.send(instance.__class__, instance=instance)
def handle_suggestion_added(**kwargs): created = kwargs.get("created") if not created: return store = kwargs["instance"].unit.store update_data.send(store.__class__, instance=store)
def update_data(self, updated_stores): if not updated_stores: return update_data.send( self.store.__class__, instance=self.store)