Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session status tracking #156

Merged
merged 4 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mcserver/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,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')
Expand Down
3 changes: 3 additions & 0 deletions mcserver/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,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',
Expand Down
18 changes: 18 additions & 0 deletions mcserver/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,24 @@ 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)
username = serializers.CharField(max_length=64, required=False)


class SubjectSerializer(serializers.ModelSerializer):
class Meta:
model = Subject
Expand Down
70 changes: 69 additions & 1 deletion mcserver/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,75 @@ 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want an additional parameter in the http request for user. The use case here is that we would call this as the admin and want to only return the sessions for a specific user that is not necessarily the admin. If anyone (admin, backend, or otherwise) calls this without specifying a user, it should only return the sessions for the user who made the request.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@suhlrich I added the commit. Now an optional argument username is supported.
9a3ca4d

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)
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
Expand Down