|
|
|
@ -14,7 +14,7 @@ from urllib.parse import unquote |
|
|
|
|
|
|
|
|
|
|
|
from .utils import build_serializer_class, get_data, get_serialized_data |
|
|
|
from .utils import build_serializer_class, get_data, get_serialized_data |
|
|
|
|
|
|
|
|
|
|
|
from tournaments.models import ModelLog, DataAccess, BaseModel |
|
|
|
from tournaments.models import ModelLog, DataAccess, BaseModel, SideStoreModel |
|
|
|
|
|
|
|
|
|
|
|
class DataApi(APIView): |
|
|
|
class DataApi(APIView): |
|
|
|
permission_classes = [IsAuthenticated] |
|
|
|
permission_classes = [IsAuthenticated] |
|
|
|
@ -92,9 +92,12 @@ class DataApi(APIView): |
|
|
|
|
|
|
|
|
|
|
|
updates = defaultdict(dict) |
|
|
|
updates = defaultdict(dict) |
|
|
|
deletions = defaultdict(list) |
|
|
|
deletions = defaultdict(list) |
|
|
|
|
|
|
|
revocations = defaultdict(list) # New dictionary for revocations |
|
|
|
|
|
|
|
revocation_parents = defaultdict(dict) |
|
|
|
|
|
|
|
|
|
|
|
last_log_date = None |
|
|
|
last_log_date = None |
|
|
|
for log in logs: |
|
|
|
for log in logs: |
|
|
|
|
|
|
|
print(f'log date = {log.date}') |
|
|
|
last_log_date = log.date |
|
|
|
last_log_date = log.date |
|
|
|
try: |
|
|
|
try: |
|
|
|
if log.operation in ['POST', 'PUT']: |
|
|
|
if log.operation in ['POST', 'PUT']: |
|
|
|
@ -116,7 +119,19 @@ class DataApi(APIView): |
|
|
|
self.add_parents_recursively(instance, updates) |
|
|
|
self.add_parents_recursively(instance, updates) |
|
|
|
elif log.operation == 'REVOKE_ACCESS': |
|
|
|
elif log.operation == 'REVOKE_ACCESS': |
|
|
|
print(f'revoke access {log.model_id} - {log.store_id}') |
|
|
|
print(f'revoke access {log.model_id} - {log.store_id}') |
|
|
|
deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id}) |
|
|
|
# Add to revocations instead of deletions |
|
|
|
|
|
|
|
revocations[log.model_name].append({ |
|
|
|
|
|
|
|
'model_id': log.model_id, |
|
|
|
|
|
|
|
'store_id': log.store_id |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Get the model instance and add its parents to revocation_parents |
|
|
|
|
|
|
|
model = apps.get_model('tournaments', model_name=log.model_name) |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
instance = model.objects.get(id=log.model_id) |
|
|
|
|
|
|
|
self.add_parents_recursively(instance, revocation_parents, minimal=True) |
|
|
|
|
|
|
|
except model.DoesNotExist: |
|
|
|
|
|
|
|
pass |
|
|
|
except ObjectDoesNotExist: |
|
|
|
except ObjectDoesNotExist: |
|
|
|
pass |
|
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
@ -128,12 +143,18 @@ class DataApi(APIView): |
|
|
|
for model_name in deletions: |
|
|
|
for model_name in deletions: |
|
|
|
deletions[model_name] = deletions[model_name] |
|
|
|
deletions[model_name] = deletions[model_name] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for model_name in revocation_parents: |
|
|
|
|
|
|
|
revocation_parents[model_name] = list(revocation_parents[model_name].values()) |
|
|
|
|
|
|
|
|
|
|
|
response_data = { |
|
|
|
response_data = { |
|
|
|
"updates": dict(updates), |
|
|
|
"updates": dict(updates), |
|
|
|
"deletions": dict(deletions), |
|
|
|
"deletions": dict(deletions), |
|
|
|
|
|
|
|
"revocations": dict(revocations), |
|
|
|
|
|
|
|
"revocation_parents": dict(revocation_parents), |
|
|
|
"date": last_log_date |
|
|
|
"date": last_log_date |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f'response_data = {response_data}') |
|
|
|
return Response(response_data, status=status.HTTP_200_OK) |
|
|
|
return Response(response_data, status=status.HTTP_200_OK) |
|
|
|
|
|
|
|
|
|
|
|
def query_model_logs(self, last_update, user): |
|
|
|
def query_model_logs(self, last_update, user): |
|
|
|
@ -141,27 +162,6 @@ class DataApi(APIView): |
|
|
|
log_query = Q(date__gt=last_update) & Q(users=user) |
|
|
|
log_query = Q(date__gt=last_update) & Q(users=user) |
|
|
|
return ModelLog.objects.filter(log_query).order_by('date') |
|
|
|
return ModelLog.objects.filter(log_query).order_by('date') |
|
|
|
|
|
|
|
|
|
|
|
# get recently modified DataAccess |
|
|
|
|
|
|
|
# data_access_query = Q(last_hierarchy_update__gt=last_update) & (Q(shared_with__in=[user]) | Q(owner=user)) |
|
|
|
|
|
|
|
# data_access_list = DataAccess.objects.filter(data_access_query) #.values_list('model_id', flat=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# print(f'>> da count = {len(data_access_list)}') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# # get ids of all recently updated related instances of each shared data |
|
|
|
|
|
|
|
# model_ids = [] |
|
|
|
|
|
|
|
# for data_access in data_access_list: |
|
|
|
|
|
|
|
# model_ids.append(data_access.model_id) |
|
|
|
|
|
|
|
# try: |
|
|
|
|
|
|
|
# instance = get_data('tournaments', data_access.model_name, data_access.model_id) |
|
|
|
|
|
|
|
# related_instances = instance.related_instances() |
|
|
|
|
|
|
|
# related_ids = [ri.id for ri in instance.related_instances() if ri.last_update > last_update] |
|
|
|
|
|
|
|
# model_ids.extend(related_ids) |
|
|
|
|
|
|
|
# except ObjectDoesNotExist: |
|
|
|
|
|
|
|
# pass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# get all ModelLog list since the last_update, from the user and from the data he has access to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_children_recursively(self, instance, updates): |
|
|
|
def add_children_recursively(self, instance, updates): |
|
|
|
""" |
|
|
|
""" |
|
|
|
Recursively add all children of an instance to the updates dictionary. |
|
|
|
Recursively add all children of an instance to the updates dictionary. |
|
|
|
@ -177,19 +177,38 @@ class DataApi(APIView): |
|
|
|
updates[child_model_name][child.id] = serializer.data |
|
|
|
updates[child_model_name][child.id] = serializer.data |
|
|
|
self.add_children_recursively(child, updates) |
|
|
|
self.add_children_recursively(child, updates) |
|
|
|
|
|
|
|
|
|
|
|
def add_parents_recursively(self, instance, updates): |
|
|
|
# def add_parents_recursively(self, instance, updates): |
|
|
|
|
|
|
|
# parent_models = instance.get_parents_by_model() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# for parent_model_name, parent in parent_models.items(): |
|
|
|
|
|
|
|
# # print(f'parent = {parent_model_name}') |
|
|
|
|
|
|
|
# if isinstance(parent, BaseModel): |
|
|
|
|
|
|
|
# serializer_class = build_serializer_class(parent_model_name) |
|
|
|
|
|
|
|
# serializer = serializer_class(parent) |
|
|
|
|
|
|
|
# updates[parent_model_name][parent.id] = serializer.data |
|
|
|
|
|
|
|
# self.add_parents_recursively(parent, updates) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_parents_recursively(self, instance, dictionary, minimal=False): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
Recursively add all parents of an instance to the updates dictionary. |
|
|
|
|
|
|
|
If minimal=True, only add id and store_id. |
|
|
|
|
|
|
|
""" |
|
|
|
parent_models = instance.get_parents_by_model() |
|
|
|
parent_models = instance.get_parents_by_model() |
|
|
|
|
|
|
|
|
|
|
|
for parent_model_name, parent in parent_models.items(): |
|
|
|
for parent_model_name, parent in parent_models.items(): |
|
|
|
# print(f'parent = {parent_model_name}') |
|
|
|
|
|
|
|
if isinstance(parent, BaseModel): |
|
|
|
if isinstance(parent, BaseModel): |
|
|
|
serializer_class = build_serializer_class(parent_model_name) |
|
|
|
if minimal: |
|
|
|
serializer = serializer_class(parent) |
|
|
|
store_id = None |
|
|
|
updates[parent_model_name][parent.id] = serializer.data |
|
|
|
if isinstance(parent, SideStoreModel): |
|
|
|
self.add_parents_recursively(parent, updates) |
|
|
|
store_id = parent.store_id |
|
|
|
|
|
|
|
dictionary[parent_model_name][parent.id] = { |
|
|
|
# def get_data(self, model, log): |
|
|
|
'model_id': parent.id, |
|
|
|
# instance = model.objects.get(id=log.model_id) |
|
|
|
'store_id': store_id |
|
|
|
# serializer_class = build_serializer_class(log.model_name) |
|
|
|
} |
|
|
|
# serializer = serializer_class(instance) |
|
|
|
else: |
|
|
|
# return serializer.data |
|
|
|
# Add full serialized data |
|
|
|
|
|
|
|
serializer_class = build_serializer_class(parent_model_name) |
|
|
|
|
|
|
|
serializer = serializer_class(parent) |
|
|
|
|
|
|
|
dictionary[parent_model_name][parent.id] = serializer.data |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.add_parents_recursively(parent, dictionary, minimal) |
|
|
|
|