def handle(self, **options): if (not options['flush_rqdata'] and not options['flush_lru'] and not options['flush_django_cache'] and not options['flush_all']): raise CommandError("No options were provided. Use one of " "--django-cache, --rqdata, --lru " "or --all.") self.stdout.write('Flushing cache...') if options['flush_rqdata'] or options['flush_all']: # Flush all rq data, dirty counter and restore Pootle revision # value. r_con = get_redis_connection('redis') r_con.flushdb() self.stdout.write('RQ data removed.') Revision.set(Unit.max_revision()) self.stdout.write('Max unit revision restored.') if options['flush_django_cache'] or options['flush_all']: r_con = get_redis_connection('default') r_con.flushdb() self.stdout.write('All default Django cache data removed.') if options['flush_lru'] or options['flush_all']: r_con = get_redis_connection('lru') r_con.flushdb() self.stdout.write('All lru cache data removed.')
def handle_noargs(self, **options): if options["restore"]: from pootle_store.models import Unit Revision.set(Unit.max_revision()) self.stdout.write("%s" % Revision.get())
def fs_plugin_base(tutorial, tmpdir, settings, system, english, zulu): from django.core.cache import caches import pootle_fs_pytest from pootle.core.models import Revision from pootle_store.models import Unit caches["exports"].clear() Revision.set(Unit.max_revision()) dir_path = str(tmpdir.dirpath()) repo_path = os.path.join(dir_path, "__src__") src_path = os.path.abspath( os.path.join( os.path.dirname(pootle_fs_pytest.__file__), "data/fs/example_fs")) settings.POOTLE_FS_PATH = dir_path tutorial_path = os.path.join(dir_path, tutorial.code) if os.path.exists(tutorial_path): shutil.rmtree(tutorial_path) if os.path.exists(repo_path): shutil.rmtree(repo_path) return tutorial, src_path, repo_path, dir_path
def test_update_set_last_sync_revision(project0_nongnu, tp0, store0, test_fs): """Tests setting last_sync_revision after store creation. """ unit = store0.units.first() unit.target = "UPDATED TARGET" unit.save() store0.sync() # Store is already parsed and store.last_sync_revision should be equal to # max unit revision assert store0.last_sync_revision == store0.get_max_unit_revision() # store.last_sync_revision is not changed after empty update saved_last_sync_revision = store0.last_sync_revision store0.updater.update_from_disk() assert store0.last_sync_revision == saved_last_sync_revision orig = str(store0) update_file = test_fs.open( "data/po/tutorial/ru/update_set_last_sync_revision_updated.po", "r") with update_file as sourcef: with open(store0.file.path, "wb") as targetf: targetf.write(sourcef.read()) # any non-empty update sets last_sync_revision to next global revision next_revision = Revision.get() + 1 store0.updater.update_from_disk() assert store0.last_sync_revision == next_revision # store.last_sync_revision is not changed after empty update (even if it # has unsynced units) item_index = 0 next_unit_revision = Revision.get() + 1 dbunit = store0.units.first() dbunit.target = "ANOTHER DB TARGET UPDATE" dbunit.save() assert dbunit.revision == next_unit_revision store0.updater.update_from_disk() assert store0.last_sync_revision == next_revision # Non-empty update sets store.last_sync_revision to next global revision # (even the store has unsynced units). There is only one unsynced unit in # this case so its revision should be set next to store.last_sync_revision next_revision = Revision.get() + 1 with open(store0.file.path, "wb") as targetf: targetf.write(orig) store0.updater.update_from_disk() assert store0.last_sync_revision == next_revision # Get unsynced unit in DB. Its revision should be greater # than store.last_sync_revision to allow to keep this change during # update from a file dbunit = store0.units[item_index] assert dbunit.revision == store0.last_sync_revision + 1
def revision(request, clear_cache): """Sets up the cached revision counter for each test call.""" from pootle.core.models import Revision from pootle_store.models import Unit if request.node.get_marker("django_db"): Revision.set(Unit.max_revision()) else: Revision.initialize()
def test_update_set_last_sync_revision(ru_update_set_last_sync_revision_po): """Tests setting last_sync_revision after store creation. """ store = ru_update_set_last_sync_revision_po # Store is already parsed and store.last_sync_revision should be equal to # max unit revision assert store.last_sync_revision == store.get_max_unit_revision() # store.last_sync_revision is not changed after empty update saved_last_sync_revision = store.last_sync_revision store.update_from_disk() assert store.last_sync_revision == saved_last_sync_revision dir_path = os.path.join(store.translation_project.project.get_real_path(), store.translation_project.language.code) copied_initial_filepath = os.path.join( dir_path, 'update_set_last_sync_revision.po.temp' ) shutil.copy(store.file.path, copied_initial_filepath) updated_filepath = os.path.join( dir_path, 'update_set_last_sync_revision_updated.po' ) shutil.copy(updated_filepath, store.file.path) # any non-empty update sets last_sync_revision to next global revision next_revision = Revision.get() + 1 store.update_from_disk() assert store.last_sync_revision == next_revision # store.last_sync_revision is not changed after empty update (even if it # has unsynced units) item_index = 0 next_unit_revision = Revision.get() + 1 dbunit = _update_translation(store, item_index, {'target': u'first'}, sync=False) assert dbunit.revision == next_unit_revision store.update_from_disk() assert store.last_sync_revision == next_revision # Non-empty update sets store.last_sync_revision to next global revision # (even the store has unsynced units). There is only one unsynced unit in # this case so its revision should be set next to store.last_sync_revision next_revision = Revision.get() + 1 shutil.move(copied_initial_filepath, store.file.path) store.update_from_disk() assert store.last_sync_revision == next_revision # Get unsynced unit in DB. Its revision should be greater # than store.last_sync_revision to allow to keep this change during # update from a file dbunit = store.getitem(item_index) assert dbunit.revision == store.last_sync_revision + 1
def test_update_upload_new_revision(en_tutorial_po): update_store( en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) assert en_tutorial_po.units[0].target == "Hello, world UPDATED"
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 handle(self, **options): last_known_revision = Revision.get() if options["after_revision"] is not None: after_revision = int(options["after_revision"]) else: after_revision = Store.objects.all().aggregate(Max("last_sync_revision"))["last_sync_revision__max"] or -1 self.stderr.write( "Will show languages changed between revisions %s (exclusive) " "and %s (inclusive)" % (after_revision, last_known_revision) ) # if the requested revision is the same or is greater than the last # known one, return nothing if after_revision >= last_known_revision: self.stderr.write("(no known changes)") return q = ( Unit.objects.filter(revision__gt=after_revision) .values("store__translation_project__language__code") .order_by("store__translation_project__language__code") .distinct() ) languages = q.values_list("store__translation_project__language__code", flat=True) # list languages separated by comma for easy parsing self.stdout.write(",".join(languages))
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 handle(self, **options): last_known_revision = Revision.get() if options['after_revision'] is not None: after_revision = int(options['after_revision']) else: after_revision = Store.objects.all().aggregate( Max('last_sync_revision'))['last_sync_revision__max'] or -1 self.stderr.write( 'Will show languages changed between revisions %s (exclusive) ' 'and %s (inclusive)' % (after_revision, last_known_revision) ) # if the requested revision is the same or is greater than the last # known one, return nothing if after_revision >= last_known_revision: self.stderr.write('(no known changes)') return q = Unit.objects.filter( revision__gt=after_revision ).values( 'store__translation_project__language__code', ).order_by( 'store__translation_project__language__code', ).distinct() languages = q.values_list('store__translation_project__language__code', flat=True) # list languages separated by comma for easy parsing print ','.join(languages)
def test_update_upload_member_user(en_tutorial_po, member): update_store( en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], user=member, store_revision=Revision.get() + 1) assert en_tutorial_po.units[0].submitted_by == member
def _sync_to_pootle(self, merge=False, pootle_wins=None): """ Update Pootle ``Store`` with the parsed FS file. """ tmp_store = self.deserialize() if not tmp_store: logger.warn("File staged for sync has disappeared: %s", self.path) return if pootle_wins is None: resolve_conflict = ( self.store_fs.resolve_conflict or SOURCE_WINS) elif pootle_wins: resolve_conflict = POOTLE_WINS else: resolve_conflict = SOURCE_WINS if merge: revision = self.store_fs.last_sync_revision or 0 else: # We set the revision to *anything* higher than the Store's # This is analogous to the `overwrite` option in # Store.update_from_disk revision = Revision.get() + 1 update_revision, __ = self.store.update( tmp_store, submission_type=SubmissionTypes.SYSTEM, user=self.latest_user, store_revision=revision, resolve_conflict=resolve_conflict) logger.debug("Pulled file: %s", self.path) return update_revision
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 _sync_to_pootle(self, merge=False, user=None, pootle_wins=None): """ Update Pootle ``Store`` with the parsed FS file. """ User = get_user_model() if pootle_wins is None: resolve_conflict = ( self.store_fs.resolve_conflict or SOURCE_WINS) elif pootle_wins: resolve_conflict = POOTLE_WINS else: resolve_conflict = SOURCE_WINS if merge: revision = self.store_fs.last_sync_revision or 0 else: # We set the revision to *anything* higher than the Store's # This is analogous to the `overwrite` option in # Store.update_from_disk revision = Revision.get() + 1 tmp_store = self.deserialize() self.store.update( tmp_store, submission_type=SubmissionTypes.SYSTEM, user=user or User.objects.get_system_user(), store_revision=revision, resolve_conflict=resolve_conflict) logger.debug("Pulled file: %s", self.path)
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 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 test_update_upload_submission_type(en_tutorial_po): update_store( en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) assert (en_tutorial_po.units[0].submission_set.first().type == SubmissionTypes.UPLOAD)
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 test_update_upload_defaults(en_tutorial_po, system): update_store( en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], user=system, store_revision=Revision.get() + 1) assert en_tutorial_po.units[0].submitted_by == system assert (en_tutorial_po.units[0].submission_set.first().type == SubmissionTypes.SYSTEM)
def test_update_upload_member_user(store0, member): store0.state = PARSED unit_source = store0.units.first().source update_store( store0, [(unit_source, "%s UPDATED" % unit_source)], user=member, store_revision=Revision.get() + 1) assert store0.units[0].submitted_by == member
def __test_update_set_last_sync_revision(ru_update_set_last_sync_revision_po): """Tests setting last_sync_revision after store creation. """ store = ru_update_set_last_sync_revision_po # Parse a store during first update # store.last_sync_revision is set to the next global revision next_revision = Revision.get() + 1 store.update(store.file.store) assert store.last_sync_revision == next_revision assert store.get_max_unit_revision() == next_revision # store.last_sync_revision is not changed after empty update store.update(store.file.store) assert store.last_sync_revision == next_revision # any non-empty update sets last_sync_revision to next global revision store.file = 'tutorial/ru/update_set_last_sync_revision_updated.po' next_revision = Revision.get() + 1 store.update(store.file.store) assert store.last_sync_revision == next_revision # store.last_sync_revision is not changed after empty update # (even if it has unsynced units) item_index = 0 next_unit_revision = Revision.get() + 1 dbunit = _update_translation(store, item_index, {'target': u'first'}, sync=False) assert dbunit.revision == next_unit_revision store.update(store.file.store, store_revision=0) assert store.last_sync_revision == next_revision # Non-empty update sets store.last_sync_revision to next global revision # (even the store has unsynced units) # There is only one unsynced unit in this case so its revision should be set # next to store.last_sync_revision next_revision = Revision.get() + 1 store.file = 'tutorial/ru/update_set_last_sync_revision.po' store.update(store.file.store, store_revision=store.get_max_unit_revision()) assert store.last_sync_revision == next_revision unit = store.getitem(item_index) # not sure why this was store.last_sync_revision + 1 - but no longer works assert unit.revision == store.last_sync_revision
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 test_changed_languages_noargs(capfd, afrikaans_tutorial, french_tutorial): """Get changed languages since last sync.""" call_command('changed_languages') out, err = capfd.readouterr() assert "(no known changes)" in err revision = Revision.get() assert ( ("Will show languages changed between revisions %d (exclusive) and " "%d (inclusive)" % (revision, revision)) in err)
def test_max_revision(af_tutorial_po): """Tests `max_revision()` gets the latest revision.""" initial_max_revision = Unit.max_revision() initial_revision = Revision.get() assert initial_max_revision == initial_revision assert initial_max_revision == 0 # Let's make 10 translation updates, this must also update their # revision numbers for i in range(10): _update_translation(af_tutorial_po, 0, {'target': str(i)}, sync=False) end_max_revision = Unit.max_revision() end_revision = Revision.get() assert end_max_revision == end_revision assert end_max_revision != initial_max_revision assert end_revision != initial_revision assert end_revision == 10
def test_update_upload_again_new_revision(en_tutorial_po_no_file): store = en_tutorial_po_no_file assert store.state == NEW update_store( store, [("Hello, world", "Hello, world UPDATED")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) store = Store.objects.get(pk=store.pk) assert store.state == PARSED assert store.units[0].target == "Hello, world UPDATED" update_store( store, [("Hello, world", "Hello, world UPDATED AGAIN")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) store = Store.objects.get(pk=store.pk) assert store.state == PARSED assert store.units[0].target == "Hello, world UPDATED AGAIN"
def test_update_upload_submission_type(store0): store0.state = PARSED unit_source = store0.units.first().source update_store( store0, [(unit_source, "%s UPDATED" % unit_source)], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) assert ( store0.units[0].submission_set.last().type == SubmissionTypes.UPLOAD)
def test_changed_languages_noargs(capfd): """Get changed languages since last sync.""" revision = Revision.get() call_command('changed_languages') out, err = capfd.readouterr() assert out == u'language0,language1,templates\n' assert ( ("Will show languages changed between revisions -1 (exclusive) and " "%d (inclusive)" % (revision)) in err)
def test_update_upload_defaults(store0, system): store0.state = PARSED unit_source = store0.units.first().source update_store( store0, [(unit_source, "%s UPDATED" % unit_source)], user=system, store_revision=Revision.get() + 1) assert store0.units[0].submitted_by == system assert ( store0.units[0].submission_set.last().type == SubmissionTypes.SYSTEM)
def _create_submission_and_suggestion(store, user, units=None, suggestion="SUGGESTION"): from pootle.core.models import Revision # Update store as user if units is None: units = [("Hello, world", "Hello, world UPDATED")] update_store( store, units, user=user, store_revision=Revision.get() + 1) # Add a suggestion unit = store.units[0] unit.add_suggestion(suggestion, user=user) return unit
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 check_revision(app_configs=None, **kwargs): from pootle.core.models import Revision from pootle_store.models import Unit errors = [] revision = Revision.get() try: max_revision = Unit.max_revision() except (OperationalError, ProgrammingError): return errors if revision is None or revision < max_revision: errors.append( checks.Critical( _("Revision is missing or has an incorrect value."), hint=_( "Run `revision --restore` to reset the revision counter."), id="pootle.C016", )) return errors
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 test_revision_incr(store0): """Tests revision is incremented when units change.""" previous_revision = Revision.get() db_unit = store0.units.exclude(target_f="").first() db_unit.target = "CHANGED" db_unit.save() assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get() db_unit.refresh_from_db() previous_revision = Revision.get() db_unit.target = "" db_unit.save() assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get()
def test_revision_incr(store0): """Tests revision is incremented when units change.""" previous_revision = Revision.get() db_unit = _update_translation(store0, 0, {"target": [u"Fleisch"]}, sync=False) assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get() previous_revision = Revision.get() db_unit = _update_translation(store0, 0, {"target": u"Lachs"}, sync=False) assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get()
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 _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 else: self.target_store.state = old_state has_changed = any(x > 0 for x in changes.values()) self.target_store.save() 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 test_revision_incr(af_tutorial_po): """Tests revision is incremented when units change.""" previous_revision = Revision.get() db_unit = _update_translation(af_tutorial_po, 0, {'target': [u'Fleisch']}, sync=False) assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get() previous_revision = Revision.get() db_unit = _update_translation(af_tutorial_po, 0, {'target': u'Lachs'}, sync=False) assert db_unit.revision != previous_revision assert Revision.get() != previous_revision assert db_unit.revision == Revision.get()
def setup_redis(self): from pootle.core.models import Revision Revision.initialize(force=True)
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 revision(): """Sets up the revision counter for each test call.""" from pootle.core.models import Revision Revision.initialize(force=True)
def test_update_upload_submission_type(en_tutorial_po): update_store(en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) assert (en_tutorial_po.units[0].submission_set.first().type == SubmissionTypes.UPLOAD)
def test_update_upload_member_user(en_tutorial_po, member): update_store(en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], user=member, store_revision=Revision.get() + 1) assert en_tutorial_po.units[0].submitted_by == member
def test_update_upload_new_revision(en_tutorial_po): update_store(en_tutorial_po, [("Hello, world", "Hello, world UPDATED")], submission_type=SubmissionTypes.UPLOAD, store_revision=Revision.get() + 1) assert en_tutorial_po.units[0].target == "Hello, world UPDATED"
def handle(self, **options): if options['restore']: from pootle_store.models import Unit Revision.set(Unit.max_revision()) self.stdout.write('%s' % Revision.get())
def create_revision(self): Revision.initialize()
def revision(request, clear_cache): """Sets up the cached revision counter for each test call.""" from pootle.core.models import Revision from pootle_store.models import Unit if request.node.get_marker('django_db'): Revision.set(Unit.max_revision())
def revision(clear_cache): """Sets up the cached revision counter for each test call.""" from pootle.core.models import Revision from pootle_store.models import Unit Revision.set(Unit.max_revision())