From 023462ec1df956b5fa48dc402bd8ec64e2122325 Mon Sep 17 00:00:00 2001 From: Oleh Korkh Date: Tue, 23 Jan 2024 16:53:17 +0200 Subject: [PATCH 1/3] session status endpoints --- mcserver/admin.py | 1 + .../migrations/0028_auto_20240123_1401.py | 24 +++++++ mcserver/models.py | 3 + mcserver/serializers.py | 17 +++++ mcserver/views.py | 67 ++++++++++++++++++- 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 mcserver/migrations/0028_auto_20240123_1401.py diff --git a/mcserver/admin.py b/mcserver/admin.py index 51f6824..6180399 100644 --- a/mcserver/admin.py +++ b/mcserver/admin.py @@ -53,6 +53,7 @@ class SessionAdmin(admin.ModelAdmin): 'id', 'user', 'subject', 'public', 'created_at', 'updated_at', 'server', + 'status', 'status_changed', 'trashed', 'trashed_at', ) raw_id_fields = ('user', 'subject') diff --git a/mcserver/migrations/0028_auto_20240123_1401.py b/mcserver/migrations/0028_auto_20240123_1401.py new file mode 100644 index 0000000..752d111 --- /dev/null +++ b/mcserver/migrations/0028_auto_20240123_1401.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.14 on 2024-01-23 14:01 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('mcserver', '0027_auto_20240105_1542'), + ] + + operations = [ + migrations.AddField( + model_name='session', + name='status', + field=models.CharField(blank=True, db_index=True, default='init', max_length=64), + ), + migrations.AddField( + model_name='session', + name='status_changed', + field=models.DateTimeField(blank=True, db_index=True, default=django.utils.timezone.now, null=True), + ), + ] diff --git a/mcserver/models.py b/mcserver/models.py index 8f0406e..9cf8de8 100644 --- a/mcserver/models.py +++ b/mcserver/models.py @@ -57,6 +57,9 @@ class Session(models.Model): public = models.BooleanField(blank=False, null=False, default=False) server = models.GenericIPAddressField(null=True, blank=True) + status = models.CharField(max_length=64, default="init", blank=True, db_index=True) + status_changed = models.DateTimeField(null=True, blank=True, default=timezone.now, db_index=True) + subject = models.ForeignKey( 'Subject', blank=True, null=True, related_name='sessions', diff --git a/mcserver/serializers.py b/mcserver/serializers.py index dd5801d..b4cb5a3 100644 --- a/mcserver/serializers.py +++ b/mcserver/serializers.py @@ -179,6 +179,23 @@ class Meta: ] +class SessionStatusSerializer(serializers.ModelSerializer): + class Meta: + model = Session + fields = ['status'] + + +class SessionIdSerializer(serializers.ModelSerializer): + class Meta: + model = Session + fields = ['id'] + + +class SessionFilteringSerializer(serializers.Serializer): + status = serializers.CharField(max_length=64, required=True) + date_range = serializers.ListField(child=serializers.DateField(), required=False) + + class SubjectSerializer(serializers.ModelSerializer): class Meta: model = Subject diff --git a/mcserver/views.py b/mcserver/views.py index 299a7f1..7b724fe 100644 --- a/mcserver/views.py +++ b/mcserver/views.py @@ -1309,7 +1309,72 @@ def neutral_img(self, request, pk): raise APIException(_("neutral_image_retrieve_error") % {"uuid": str(pk)}) return Response(data) - + + + @action(detail=False, methods=['post'], permission_classes=[IsAdmin | IsBackend | IsOwner]) + def get_session_statuses(self, request): + from .serializers import SessionIdSerializer, SessionFilteringSerializer + try: + filtering_serializer = SessionFilteringSerializer(data=request.data) + serializer = SessionIdSerializer(Session.objects.none(), many=True) + if filtering_serializer.is_valid(): + status_str = filtering_serializer.validated_data.get('status') + date_range = filtering_serializer.validated_data.get('date_range') + filter_kwargs = {'status': status_str} + if date_range: + filter_kwargs['status_changed__gte'] = date_range[0] + filter_kwargs['status_changed__lte'] = date_range[1] + if not IsAdmin().has_permission(request, self) and not IsBackend().has_permission(request, self): + filter_kwargs['user'] = request.user + + sessions = Session.objects.filter(**filter_kwargs) + serializer = SessionIdSerializer(sessions, many=True) + except Http404: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise NotFound(_("session_uuid_not_found") % {"uuid": str(pk)}) + except ValueError: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise NotFound(_("session_uuid_not_valid") % {"uuid": str(pk)}) + except Exception: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise APIException(_("session_remove_error")) + + return Response(serializer.data) + + + @action(detail=True, methods=['post'], permission_classes=[IsAdmin | IsBackend]) + def set_session_status(self, request, pk): + from .serializers import SessionStatusSerializer + try: + if pk == 'undefined': + raise ValueError(_("undefined_uuid")) + + session = get_object_or_404(Session, pk=pk) + serializer = SessionStatusSerializer(data=request.data) + if serializer.is_valid(): + session.status = serializer.validated_data['status'] + session.status_changed = timezone.now() + session.save() + + except Http404: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise NotFound(_("session_uuid_not_found") % {"uuid": str(pk)}) + except ValueError: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise NotFound(_("session_uuid_not_valid") % {"uuid": str(pk)}) + except Exception: + if settings.DEBUG: + raise Exception(_("error") % {"error_message": str(traceback.format_exc())}) + raise APIException(_("session_remove_error")) + + return Response(serializer.data) + + ## Processing machine: # A worker asks whether there is any trial to process From 03cb9186b8190620259953d8733405adc2d99525 Mon Sep 17 00:00:00 2001 From: Antoine Falisse Date: Mon, 5 Feb 2024 10:55:39 -0800 Subject: [PATCH 2/3] delete outdated migration file --- .../migrations/0028_auto_20240123_1401.py | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 mcserver/migrations/0028_auto_20240123_1401.py diff --git a/mcserver/migrations/0028_auto_20240123_1401.py b/mcserver/migrations/0028_auto_20240123_1401.py deleted file mode 100644 index 752d111..0000000 --- a/mcserver/migrations/0028_auto_20240123_1401.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.1.14 on 2024-01-23 14:01 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('mcserver', '0027_auto_20240105_1542'), - ] - - operations = [ - migrations.AddField( - model_name='session', - name='status', - field=models.CharField(blank=True, db_index=True, default='init', max_length=64), - ), - migrations.AddField( - model_name='session', - name='status_changed', - field=models.DateTimeField(blank=True, db_index=True, default=django.utils.timezone.now, null=True), - ), - ] From 9a3ca4d6f7f4650ff187778ad7fbfb6daa612b8d Mon Sep 17 00:00:00 2001 From: Oleh Korkh Date: Fri, 16 Feb 2024 11:06:27 +0200 Subject: [PATCH 3/3] added optional username argument --- mcserver/serializers.py | 1 + mcserver/views.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/mcserver/serializers.py b/mcserver/serializers.py index 7368dd7..dc19ca4 100644 --- a/mcserver/serializers.py +++ b/mcserver/serializers.py @@ -205,6 +205,7 @@ class Meta: class SessionFilteringSerializer(serializers.Serializer): status = serializers.CharField(max_length=64, required=True) date_range = serializers.ListField(child=serializers.DateField(), required=False) + username = serializers.CharField(max_length=64, required=False) class SubjectSerializer(serializers.ModelSerializer): diff --git a/mcserver/views.py b/mcserver/views.py index 657bbe4..4d31b99 100644 --- a/mcserver/views.py +++ b/mcserver/views.py @@ -1327,6 +1327,9 @@ def get_session_statuses(self, request): filter_kwargs['status_changed__lte'] = date_range[1] if not IsAdmin().has_permission(request, self) and not IsBackend().has_permission(request, self): filter_kwargs['user'] = request.user + else: + if 'username' in filtering_serializer.validated_data: + filter_kwargs['user__username'] = filtering_serializer.validated_data.get('username') sessions = Session.objects.filter(**filter_kwargs) serializer = SessionIdSerializer(sessions, many=True)