def testCanGetDeleted(self): with reversion.create_revision(): self.test11.delete() self.test21.delete() # Test a model with an int pk. versions = reversion.get_deleted(ReversionTestModel1) self.assertEqual(len(versions), 1) self.assertEqual(versions[0].field_dict["name"], "model1 instance1 version2") # Test a model with a str pk. versions = reversion.get_deleted(ReversionTestModel2) self.assertEqual(len(versions), 1) self.assertEqual(versions[0].field_dict["name"], "model2 instance1 version2")
def testRecoverDeleted(self): # Delete the test model. with reversion.create_revision(): self.test11.delete() self.assertEqual(TestFollowModel.objects.count(), 0) self.assertEqual(ReversionTestModel1.objects.count(), 1) # Recover the test model. with reversion.create_revision(): reversion.get_deleted(ReversionTestModel1)[0].revision.revert() # Make sure it was recovered. self.assertEqual(TestFollowModel.objects.count(), 1) self.assertEqual(ReversionTestModel1.objects.count(), 2)
def historic_tags_for_episodes(cls, episodes): """ Given a list of episodes, return a dict indexed by episode id that contains historic tags for those episodes. """ episode_ids = [e.id for e in episodes] teams = {t.id: t.name for t in Team.objects.all()} deleted = reversion.get_deleted(cls) historic = collections.defaultdict(dict) for d in deleted: data = json.loads(d.serialized_data)[0]["fields"] if data["episode"] in episode_ids: if "team" in data: if data["team"] in teams: tag_name = teams[data["team"]] else: print "Team has been deleted since it was serialised." print "We ignore these for now." continue else: try: tag_name = data["tag_name"] except KeyError: print json.dumps(data, indent=2) raise exceptions.FTWLarryError("Can't find the team in this data :(") historic[data["episode"]][tag_name] = True return historic
def historic_tags_for_episodes(cls, episodes): """ Given a list of episodes, return a dict indexed by episode id that contains historic tags for those episodes. """ episode_ids = [e.id for e in episodes] teams = {t.id: t.name for t in Team.objects.all()} deleted = reversion.get_deleted(cls) historic = collections.defaultdict(dict) for d in deleted: data = json.loads(d.serialized_data)[0]['fields'] if data['episode'] in episode_ids: if 'team' in data: if data['team'] in teams: tag_name = teams[data['team']] else: print 'Team has been deleted since it was serialised.' print 'We ignore these for now.' continue else: try: tag_name = data['tag_name'] except KeyError: print json.dumps(data, indent=2) raise exceptions.FTWLarryError( "Can't find the team in this data :(") historic[data['episode']][tag_name] = True return historic
def historic_episodes_for_tag(cls, tag): """ Given a TAG return a list of episodes that have historically been tagged with it. """ teams = {t.id: t.name for t in Team.objects.all()} deleted = reversion.get_deleted(cls) eids = set() for d in deleted: data = json.loads(d.serialized_data)[0]["fields"] try: team_index = data["team"] if team_index not in teams: print "Can't find deleted team by index - we think the team has been deleted? " print "DATA:" print json.dumps(data, indent=2) print "TEAMS:" print json.dumps(teams, indent=2) continue tag_name = teams[team_index] except KeyError: tag_name = data["tag_name"] if tag_name == tag: eids.add(data["episode"]) historic = Episode.objects.filter(id__in=eids) return historic
def historic_episodes_for_tag(cls, tag): """ Given a TAG return a list of episodes that have historically been tagged with it. """ teams = {t.id: t.name for t in Team.objects.all()} deleted = reversion.get_deleted(cls) eids = set() for d in deleted: data = json.loads(d.serialized_data)[0]['fields'] try: team_index = data['team'] if team_index not in teams: print "Can't find deleted team by index - we think the team has been deleted? " print "DATA:" print json.dumps(data, indent=2) print "TEAMS:" print json.dumps(teams, indent=2) continue tag_name = teams[team_index] except KeyError: tag_name = data['tag_name'] if tag_name == tag: eids.add(data['episode']) historic = Episode.objects.filter(id__in=eids) return historic
def clear_deleted_restaurateurs(request): if not request.user.is_authenticated() or not request.user.is_superuser: return HttpResponseRedirect("/comptes/login") deleted_revisions = reversion.get_deleted(Restaurateur).select_related('revision') for deleted_revision in deleted_revisions: Revision.objects.filter(id=deleted_revision.revision_id).delete()
def test_commands_DELETE(self): assert len(reversion.get_deleted(Lexicon)) == 0 assert Lexicon.objects.get(pk=self.lex_b.id) # exists? form_data = self.form_data form_data['c-%d' % self.lex_b.id] = "!DELETE" response = self.AuthenticatedClient.post(self.url, form_data, follow=True) with self.assertRaises(Lexicon.DoesNotExist): Lexicon.objects.get(pk=self.lex_b.id)
def get_users(pk_list): users = [] for pk in pk_list: try: u = HAWCUser.objects.get(pk=pk) except: deleted_users = reversion.get_deleted(HAWCUser) u = deleted_users.get(pk=pk) users.append(u.get_full_name()) return '<br>'.join(sorted(users))
def test_that_can_safely_restore_deleted_object(self): model = None amount = Money(100, 'GHS') with reversion.create_revision(): model = RevisionedModel.objects.create(amount=amount) model.save() model.delete() version = reversion.get_deleted(RevisionedModel)[0] version.revision.revert() model = RevisionedModel.objects.get(pk=1) self.assertEquals(model.amount, amount)
def undo_last_delete(request): if not request.user.is_authenticated() or not request.user.is_superuser: return HttpResponseRedirect("/comptes/login") delete_list = reversion.get_deleted(Restaurant) if delete_list: restaurantId = delete_list[0].object_id delete_version = delete_list.latest('revision') delete_version.revision.revert() return HttpResponse('{"success": true, "id": ' + str(restaurantId) + '}')
def testCanSaveAutoInitialOnDelete(self): self.assertEqual(Version.objects.count(), 0) with reversion.create_revision(): reversion.set_auto_initial(True, [ReversionTestModel1]) self.test11.delete() # Test that an initial is saved on delete versions = reversion.get_deleted(ReversionTestModel1) self.assertEqual(len(versions), 1) self.assertEqual(Version.objects.filter(type=VERSION_ADD).count(), 1) self.assertEqual(Version.objects.filter(type=VERSION_CHANGE).count(), 0) self.assertEqual(Version.objects.filter(type=VERSION_DELETE).count(), 1) self.assertEqual(reversion.get_for_object(self.test12).count(), 0) with reversion.create_revision(): reversion.set_auto_initial(True, [ReversionTestModel1]) self.test12.name = "model1 instance2 version2" self.test12.delete() # Test that an initial is saved on delete versions = reversion.get_deleted(ReversionTestModel1) self.assertEqual(len(versions), 2) self.assertEqual(Version.objects.filter(type=VERSION_ADD).count(), 2) self.assertEqual(Version.objects.filter(type=VERSION_CHANGE).count(), 0) self.assertEqual(Version.objects.filter(type=VERSION_DELETE).count(), 2)
def test_creates_reversion(self): form_data = self.form_data form_data['c-%d' % self.lex_b.id] = "%s" % self.cogset1.id form_data['c-%d' % self.lex_a.id] = "-%s" % self.cogset1.id response = self.AuthenticatedClient.post(self.url, form_data, follow=True) version_list = reversion.get_for_object(self.cogset1) assert len(version_list) == 1, "Cognate Version List Missing" version_list = reversion.get_for_object(self.lex_b) assert len(version_list) == 1, "Lex B Version List Missing" assert len(reversion.get_deleted(Cognate)) == 1
def get_many_to_something(self, ids, related_model, is_reverse=False): # get instance of reversion.models.Revision(): # A group of related object versions. old_revision = self.version.revision # Get a queryset with all related objects. versions = old_revision.version_set.filter( content_type=ContentType.objects.get_for_model(related_model), object_id__in=ids) if self.has_int_pk: # The primary_keys would be stored in a text field -> convert it to integers # This is interesting in different places! for version in versions: version.object_id = int(version.object_id) missing_objects = [] missing_ids = [] if self.field_name not in self.adapter.follow: # This models was not registered with follow relations # Try to fill missing related objects target_ids = set(ids) actual_ids = set([version.object_id for version in versions]) missing_ids1 = target_ids.difference(actual_ids) # logger.debug(self.field_name, "target: %s - actual: %s - missing: %s" % (target_ids, actual_ids, missing_ids1)) if missing_ids1: missing_objects = related_model.objects.all().filter( pk__in=missing_ids1) missing_ids = list( target_ids.difference( set(missing_objects.values_list('pk', flat=True)))) deleted = [] if is_reverse: true_missing_objects = [] for o in missing_objects: for ver in reversion.get_for_object(o): # An object can only be missing if it actually existed prior to this version # Otherwise its a new item if ver.revision.date_created < old_revision.date_created: true_missing_objects.append(o) missing_objects = true_missing_objects deleted = [ d for d in reversion.get_deleted(related_model) if d.revision == old_revision ] return versions, missing_objects, missing_ids, deleted
def test_issue_53(admin_client): pytest.importorskip("reversion") import reversion as revisions with revisions.create_revision(): instance = ReversionConcurrentModel.objects.create() pk = instance.pk with revisions.create_revision(): instance.delete() version_list = revisions.get_deleted(ReversionConcurrentModel) deleted_pk = version_list[0].pk admin_client.post('/admin/demo/reversionconcurrentmodel/recover/{}/'.format(deleted_pk), {'username': '******'}) assert ReversionConcurrentModel.objects.filter(id=pk).exists()
def test_issue_53(admin_client): pytest.importorskip("reversion") import reversion as revisions with revisions.create_revision(): instance = ReversionConcurrentModel.objects.create() pk = instance.pk with revisions.create_revision(): instance.delete() version_list = revisions.get_deleted(ReversionConcurrentModel) deleted_pk = version_list[0].pk admin_client.post( '/admin/demo/reversionconcurrentmodel/recover/{}/'.format(deleted_pk), {'username': '******'}) assert ReversionConcurrentModel.objects.filter(id=pk).exists()
def testDontSaveAutoInitialOnDelete(self): self.assertEqual(Version.objects.count(), 0) with reversion.create_revision(): self.test11.save() self.test12.save() self.test21.save() self.test22.save() self.assertEqual(reversion.get_for_object(self.test11).count(), 1) with reversion.create_revision(): reversion.set_auto_initial(True, [ReversionTestModel1]) self.test11.delete() # Test that no initial is saved on delete versions = reversion.get_deleted(ReversionTestModel1) self.assertEqual(len(versions), 1) self.assertEqual(Version.objects.filter(type=VERSION_ADD).count(), 0) self.assertEqual(Version.objects.filter(type=VERSION_CHANGE).count(), 4) self.assertEqual(Version.objects.filter(type=VERSION_DELETE).count(), 1)
def get_many_to_something(self, ids, related_model, is_reverse=False): # get instance of reversion.models.Revision(): # A group of related object versions. old_revision = self.version.revision # Get a queryset with all related objects. versions = old_revision.version_set.filter( content_type=ContentType.objects.get_for_model(related_model), object_id__in=ids ) if self.has_int_pk: # The primary_keys would be stored in a text field -> convert it to integers # This is interesting in different places! for version in versions: version.object_id = int(version.object_id) missing_objects = [] missing_ids = [] if self.field_name not in self.adapter.follow: # This models was not registered with follow relations # Try to fill missing related objects target_ids = set(ids) actual_ids = set([version.object_id for version in versions]) missing_ids1 = target_ids.difference(actual_ids) # logger.debug(self.field_name, "target: %s - actual: %s - missing: %s" % (target_ids, actual_ids, missing_ids1)) if missing_ids1: missing_objects = related_model.objects.all().filter(pk__in=missing_ids1) missing_ids = list(target_ids.difference(set(missing_objects.values_list('pk', flat=True)))) deleted = [] if is_reverse: true_missing_objects = [] for o in missing_objects: for ver in reversion.get_for_object(o): # An object can only be missing if it actually existed prior to this version # Otherwise its a new item if ver.revision.date_created < version.revision.date_created: true_missing_objects.append(o) missing_objects = true_missing_objects deleted = [d for d in reversion.get_deleted(related_model) if d.revision == old_revision] return versions, missing_objects, missing_ids, deleted
def post_delete_hook(sender, instance, **kwargs): """Custom post-delete hook. We want to know who was responsible for an object deletion. """ from reversion.models import Version if not reversion.is_registered(sender): return del_list = reversion.get_deleted(sender) try: version = del_list.get(object_id=instance.id) except Version.DoesNotExist: return logger = logging.getLogger("modoboa.admin") msg = _("%(object)s '%(name)s' %(action)s by user %(user)s") % { "object": unicode(version.content_type).capitalize(), "name": version.object_repr, "action": _("deleted"), "user": version.revision.user.username } logger.critical(msg)
def log_object_removal(sender, instance, **kwargs): """Custom post-delete hook. We want to know who was responsible for an object deletion. """ from reversion.models import Version from modoboa.lib.signals import get_request if not reversion.is_registered(sender): return del_list = reversion.get_deleted(sender) try: version = del_list.get(object_id=instance.id) except Version.DoesNotExist: return logger = logging.getLogger("modoboa.admin") msg = _("%(object)s '%(name)s' %(action)s by user %(user)s") % { "object": unicode(version.content_type).capitalize(), "name": version.object_repr, "action": _("deleted"), "user": get_request().user.username } logger.critical(msg)
""" Audit outputs helper command """ import collections import datetime as dt import json import sys from django.core.management.base import BaseCommand import reversion from opal.models import Tagging from elcid.tags import TAGS deleted_tags = reversion.get_deleted(Tagging) DELETED_TAG_DATA = [ json.loads(d.serialized_data)[0]['fields'] for d in deleted_tags ] class MonthlyAudit(object): def __init__(self, tag_name): self.tag_name = tag_name self.episodes = [] self.ages = collections.defaultdict(int) self.diagnoses = collections.defaultdict(int) self.length_of_stay = collections.defaultdict(int) @property def num_patients(self): return len(self.episodes)
def import_from_reversion(cls): # a one off function that syncs the tags with archived tags with the # existing tags from collections import defaultdict deleted = reversion.get_deleted(cls) episode_id_to_team_dict = defaultdict(set) episode_id_to_user_dict = defaultdict(set) for deleted_item in deleted: data = json.loads(deleted_item.serialized_data)[0]['fields'] episode_id = data["episode"] if not Episode.objects.filter(id=episode_id).exists(): continue team_id = data.get("team") if team_id and not Team.objects.filter(id=team_id).exists(): continue if "tag_name" in data: qs = Team.objects.filter(name=data["tag_name"]) if qs.exists(): team_id = qs.first().id user_id = data.get("user") if user_id and not User.objects.filter(id=user_id).exists(): continue if user_id: episode_id_to_user_dict[episode_id].add(user_id) elif team_id: episode_id_to_team_dict[episode_id].add(team_id) team_taggings = Tagging.objects.filter(episode_id__in=episode_id_to_team_dict.keys()) for tagging in team_taggings: relevent_set = episode_id_to_team_dict[tagging.episode_id] if tagging.team_id and tagging.team_id in relevent_set: relevent_set.remove(tagging.team_id) tagging_objs = [] for episode_id, team_ids in episode_id_to_team_dict.iteritems(): for team_id in team_ids: tagging_objs.append(Tagging(episode_id=episode_id, team_id=team_id, archived=True)) try: user_taggins = Tagging.objects.filter(episode_id__in=episode_id_to_user_dict.keys()) for tagging in user_taggins: relevent_set = episode_id_to_user_dict[tagging.episode_id] if tagging.user_id and tagging.user_id in relevent_set: relevent_set.remove(tagging.user_id) user_team = Team.objects.get(name="mine") for episode_id, user_ids in episode_id_to_user_dict.iteritems(): for user_id in user_ids: tagging_objs.append(Tagging( episode_id=episode_id, team_id=user_team.id, user_id=user_id, archived=True )) except Team.DoesNotExist: pass # We don't have a mine team here Tagging.objects.bulk_create(tagging_objs)
""" Audit outputs helper command """ import collections import datetime as dt import json import sys from django.core.management.base import BaseCommand import reversion from opal.models import Tagging from elcid.tags import TAGS deleted_tags = reversion.get_deleted(Tagging) DELETED_TAG_DATA = [json.loads(d.serialized_data)[0]['fields'] for d in deleted_tags] class MonthlyAudit(object): def __init__(self, tag_name): self.tag_name = tag_name self.episodes = [] self.ages = collections.defaultdict(int) self.diagnoses = collections.defaultdict(int) self.length_of_stay = collections.defaultdict(int) @property def num_patients(self): return len(self.episodes) def get_episodes(self): """
def import_from_reversion(cls): # a one off function that syncs the tags with archived tags with the # existing tags from collections import defaultdict deleted = reversion.get_deleted(cls) episode_id_to_team_dict = defaultdict(set) episode_id_to_user_dict = defaultdict(set) for deleted_item in deleted: data = json.loads(deleted_item.serialized_data)[0]['fields'] episode_id = data["episode"] if not Episode.objects.filter(id=episode_id).exists(): continue team_id = data.get("team") if team_id and not Team.objects.filter(id=team_id).exists(): continue if "tag_name" in data: qs = Team.objects.filter(name=data["tag_name"]) if qs.exists(): team_id = qs.first().id user_id = data.get("user") if user_id and not User.objects.filter(id=user_id).exists(): continue if user_id: episode_id_to_user_dict[episode_id].add(user_id) elif team_id: episode_id_to_team_dict[episode_id].add(team_id) team_taggings = Tagging.objects.filter( episode_id__in=episode_id_to_team_dict.keys()) for tagging in team_taggings: relevent_set = episode_id_to_team_dict[tagging.episode_id] if tagging.team_id and tagging.team_id in relevent_set: relevent_set.remove(tagging.team_id) tagging_objs = [] for episode_id, team_ids in episode_id_to_team_dict.iteritems(): for team_id in team_ids: tagging_objs.append( Tagging(episode_id=episode_id, team_id=team_id, archived=True)) try: user_taggins = Tagging.objects.filter( episode_id__in=episode_id_to_user_dict.keys()) for tagging in user_taggins: relevent_set = episode_id_to_user_dict[tagging.episode_id] if tagging.user_id and tagging.user_id in relevent_set: relevent_set.remove(tagging.user_id) user_team = Team.objects.get(name="mine") for episode_id, user_ids in episode_id_to_user_dict.iteritems(): for user_id in user_ids: tagging_objs.append( Tagging(episode_id=episode_id, team_id=user_team.id, user_id=user_id, archived=True)) except Team.DoesNotExist: pass # We don't have a mine team here Tagging.objects.bulk_create(tagging_objs)