diff --git a/api/sync.py b/api/sync.py index 59cf31a..3f6f339 100644 --- a/api/sync.py +++ b/api/sync.py @@ -1,4 +1,3 @@ -from django.db.models.fields.related_lookups import RelatedExact from rest_framework.views import APIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response @@ -12,9 +11,9 @@ from django.core.exceptions import ObjectDoesNotExist from collections import defaultdict from urllib.parse import unquote -from .utils import build_serializer_class, get_data, get_serialized_data +from .utils import get_serializer, build_serializer_class, get_data, get_serialized_data -from tournaments.models import ModelLog, DataAccess, BaseModel, SideStoreModel +from tournaments.models import ModelLog, BaseModel, SideStoreModel class DataApi(APIView): permission_classes = [IsAuthenticated] @@ -25,7 +24,7 @@ class DataApi(APIView): model_operation = request.data.get('operation') model_name = request.data.get('model_name') data = request.data.get('data') - store_id = request.data.get('store_id') + # store_id = request.data.get('store_id') print(f"DataApi post > {model_operation} {model_name}") @@ -33,14 +32,12 @@ class DataApi(APIView): data['last_updated_by'] = request.user.id # always refresh the user performing the operation model = apps.get_model(app_label='tournaments', model_name=model_name) - now = timezone.localtime(timezone.now()) if model_operation == 'POST': serializer = serializer_class(data=data, context={'request': request}) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) - # return self.save_and_create_log(request, serializer, model_operation, model_name, store_id, now) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif model_operation == 'PUT': @@ -52,7 +49,6 @@ class DataApi(APIView): print('>>> update') serializer.save() return Response(serializer.data, status=status.HTTP_200_OK) - # return self.save_and_create_log(request, serializer, model_operation, model_name, store_id, now) else: print('>>> return 203') return Response(serializer.data, status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION) @@ -71,6 +67,69 @@ class DataApi(APIView): else: return Response(status=status.HTTP_404_NOT_FOUND) + # def get(self, request, *args, **kwargs): + # last_update_str = request.query_params.get('last_update') + # decoded_last_update = unquote(last_update_str) + + # if not decoded_last_update: + # return Response({"error": "last_update parameter is required"}, status=status.HTTP_400_BAD_REQUEST) + + # try: + # last_update = timezone.datetime.fromisoformat(decoded_last_update) + # except ValueError: + # return Response({"error": f"Invalid date format for last_update: {decoded_last_update}"}, status=status.HTTP_400_BAD_REQUEST) + + # logs = self.query_model_logs(last_update, request.user) + + # updates = defaultdict(dict) + # deletions = defaultdict(list) + # grants = defaultdict(dict) + # revocations = defaultdict(list) + # revocation_parents = defaultdict(dict) + + # last_log_date = None + # for log in logs: + # last_log_date = log.date + # self._process_log(log, updates, deletions, grants, revocations, revocation_parents) + + # response_data = { + # "updates": {k: list(v.values()) for k, v in updates.items()}, + # "deletions": dict(deletions), + # "grants": {k: list(v.values()) for k, v in grants.items()}, + # "revocations": dict(revocations), + # "revocation_parents": {k: list(v.values()) for k, v in revocation_parents.items()}, + # "date": last_log_date + # } + + # return Response(response_data, status=status.HTTP_200_OK) + + # def _process_log(self, log, updates, deletions, grants, revocations, revocation_parents): + # try: + # if log.operation in ['POST', 'PUT']: + # data = get_serialized_data('tournaments', log.model_name, log.model_id) + # updates[log.model_name][log.model_id] = data + # elif log.operation == 'DELETE': + # deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id}) + # elif log.operation == 'GRANT_ACCESS': + # model = apps.get_model('tournaments', model_name=log.model_name) + # instance = model.objects.get(id=log.model_id) + # serializer = get_serializer(instance, log.model_name) + # grants[log.model_name][log.model_id] = serializer.data + # self.add_children_recursively(instance, grants) + # self.add_parents_recursively(instance, grants) + # elif log.operation == 'REVOKE_ACCESS': + # revocations[log.model_name].append({ + # 'model_id': log.model_id, + # 'store_id': log.store_id + # }) + # 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: + # pass def get(self, request, *args, **kwargs): last_update_str = request.query_params.get('last_update') @@ -110,8 +169,9 @@ class DataApi(APIView): model = apps.get_model('tournaments', model_name=log.model_name) instance = model.objects.get(id=log.model_id) - serializer_class = build_serializer_class(log.model_name) - serializer = serializer_class(instance) + # serializer_class = build_serializer_class(log.model_name) + # serializer = serializer_class(instance) + serializer = get_serializer(instance, log.model_name) # data = get_serialized_data('tournaments', log.model_name, log.model_id) grants[log.model_name][log.model_id] = serializer.data @@ -177,8 +237,9 @@ class DataApi(APIView): for child_model_name, children in child_models.items(): for child in children: if isinstance(child, BaseModel): - serializer_class = build_serializer_class(child_model_name) - serializer = serializer_class(child) + serializer = get_serializer(child, child_model_name) + # serializer_class = build_serializer_class(child_model_name) + # serializer = serializer_class(child) updates[child_model_name][child.id] = serializer.data self.add_children_recursively(child, updates) @@ -211,9 +272,10 @@ class DataApi(APIView): 'store_id': store_id } else: + serializer = get_serializer(parent, parent_model_name) # Add full serialized data - serializer_class = build_serializer_class(parent_model_name) - serializer = serializer_class(parent) + # 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) diff --git a/api/utils.py b/api/utils.py index 68adefc..e73eea1 100644 --- a/api/utils.py +++ b/api/utils.py @@ -6,14 +6,14 @@ def is_valid_email(email): email_regex = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$' return re.match(email_regex, email) is not None -def build_serializer_class(source): +def build_serializer_class(model_name): # Remove the 's' character at the end if present - if source.endswith('s') and not source.endswith('ss'): - source = source[:-1] + if model_name.endswith('s') and not model_name.endswith('ss'): + model_name = model_name[:-1] # Capitalize words separated by a dash - words = source.split('-') + words = model_name.split('-') capitalized_words = [word[0].upper() + word[1:] for word in words] transformed_string = ''.join(capitalized_words) @@ -23,6 +23,10 @@ def build_serializer_class(source): module = importlib.import_module('api.serializers') return getattr(module, transformed_string) +def get_serializer(instance, model_name): + serializer = build_serializer_class(model_name) + return serializer(instance) + def get_data(app_label, model_name, model_id): model = apps.get_model(app_label=app_label, model_name=model_name) return model.objects.get(id=model_id)