From 6e5ac4b10b5484eaacee7f9fabd7568ac42bd252 Mon Sep 17 00:00:00 2001 From: Kirill Sizov Date: Mon, 24 Jul 2023 15:50:24 +0300 Subject: [PATCH 1/2] Fix keyframe removing (#6494) Steps to reproduce this bug: Create a track that starts on the frame i and has keyframe on the frame j (i < j) Save Remove the keyframe for the created track on the frame i Save --- CHANGELOG.md | 1 + cvat/apps/dataset_manager/task.py | 1 + tests/python/rest_api/test_tasks.py | 16 ++++++++++++++++ 3 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d530f6e285e..dd363d96d59a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed SAM plugin (403 code for workers in organizations) () - Using initial frame from query parameter to open specific frame in a job () +- Problem with first keyframe removing () - Server-side validation for attribute specifications () - \[API\] File downloading failures for filenames with special characters l() diff --git a/cvat/apps/dataset_manager/task.py b/cvat/apps/dataset_manager/task.py index 66fd499a6002..1269883e30fa 100644 --- a/cvat/apps/dataset_manager/task.py +++ b/cvat/apps/dataset_manager/task.py @@ -160,6 +160,7 @@ def _add_missing_shape(self, track, first_shape): missing_shape = deepcopy(first_shape) missing_shape["frame"] = track["frame"] missing_shape["outside"] = True + missing_shape.pop("id") track["shapes"].append(missing_shape) def _correct_frame_of_tracked_shapes(self, track): diff --git a/tests/python/rest_api/test_tasks.py b/tests/python/rest_api/test_tasks.py index 0184f66e56c9..98c443b290bd 100644 --- a/tests/python/rest_api/test_tasks.py +++ b/tests/python/rest_api/test_tasks.py @@ -517,6 +517,22 @@ def test_member_update_task_annotation( self._test_check_response(is_allow, response, data) + def test_remove_first_keyframe(self): + endpoint = "tasks/8/annotations" + shapes0 = [ + {"type": "rectangle", "frame": 1, "points": [1, 2, 3, 4]}, + {"type": "rectangle", "frame": 4, "points": [5, 6, 7, 8]}, + ] + + annotations = {"tracks": [{"label_id": 13, "frame": 0, "shapes": shapes0}]} + + response = patch_method("admin1", endpoint, annotations, action="create") + assert response.status_code == HTTPStatus.OK, response.content + + annotations["tracks"][0]["shapes"] = shapes0[1:] + response = patch_method("admin1", endpoint, annotations, action="update") + assert response.status_code == HTTPStatus.OK + @pytest.mark.usefixtures("restore_db_per_class") class TestGetTaskDataset: From d72e954b4fc28d78821583d8eb1a16beca6e5021 Mon Sep 17 00:00:00 2001 From: Andrey Zhavoronkov Date: Mon, 24 Jul 2023 19:17:13 +0300 Subject: [PATCH 2/2] Fix BrowsableAPIRenderer for server viewset (#6553) ### Motivation and context Resolved #6550 ```python ERROR:django.request:Internal Server Error: /api/server/annotation/formats Traceback (most recent call last): File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/django/core/handlers/base.py", line 220, in _get_response response = response.render() File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/django/template/response.py", line 114, in render self.content = self.rendered_content File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/response.py", line 70, in rendered_content ret = renderer.render(self.data, accepted_media_type, context) File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/renderers.py", line 723, in render context = self.get_context(data, accepted_media_type, renderer_context) File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/renderers.py", line 697, in get_context 'options_form': self.get_rendered_html_form(data, view, 'OPTIONS', request), File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/renderers.py", line 475, in get_rendered_html_form if not self.show_form_for_method(view, method, request, instance): File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/renderers.py", line 432, in show_form_for_method view.check_object_permissions(request, obj) File "/home/andrey/workspace/cvat.ai/cvat/.env/lib/python3.10/site-packages/rest_framework/views.py", line 345, in check_object_permissions if not permission.has_object_permission(request, self, obj): File "/home/andrey/workspace/cvat.ai/cvat/cvat/apps/iam/permissions.py", line 2015, in has_object_permission return self.check_permission(request, view, obj) File "/home/andrey/workspace/cvat.ai/cvat/cvat/apps/iam/permissions.py", line 1990, in check_permission iam_context = get_iam_context(request, obj) File "/home/andrey/workspace/cvat.ai/cvat/cvat/apps/iam/permissions.py", line 88, in get_iam_context organization = get_organization(request, obj) File "/home/andrey/workspace/cvat.ai/cvat/cvat/apps/iam/permissions.py", line 68, in get_organization raise exc File "/home/andrey/workspace/cvat.ai/cvat/cvat/apps/iam/permissions.py", line 61, in get_organization organization_id = getattr(obj, 'organization_id') AttributeError: 'dict' object has no attribute 'organization_id' ```` ### How has this been tested? ```terminal curl --header "Accept: text/html" --user "user:pass" http://localhost:8080/api/server/annotation/formats ``` ### Checklist - [x] I submit my changes into the `develop` branch - [ ] I have added a description of my changes into the [CHANGELOG](https://github.com/opencv/cvat/blob/develop/CHANGELOG.md) file - [ ] I have updated the documentation accordingly - [ ] I have added tests to cover my changes - [ ] I have linked related issues (see [GitHub docs]( https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)) - [x] I have increased versions of npm packages if it is necessary ([cvat-canvas](https://github.com/opencv/cvat/tree/develop/cvat-canvas#versioning), [cvat-core](https://github.com/opencv/cvat/tree/develop/cvat-core#versioning), [cvat-data](https://github.com/opencv/cvat/tree/develop/cvat-data#versioning) and [cvat-ui](https://github.com/opencv/cvat/tree/develop/cvat-ui#versioning)) ### License - [x] I submit _my code changes_ under the same [MIT License]( https://github.com/opencv/cvat/blob/develop/LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern. --- cvat/apps/engine/views.py | 4 ++-- cvat/apps/iam/permissions.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index 4d498d495a0a..3740d2a47568 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -194,13 +194,13 @@ def annotation_formats(request): }) @action(detail=False, methods=['GET'], url_path='plugins', serializer_class=PluginsSerializer) def plugins(request): - response = { + data = { 'GIT_INTEGRATION': apps.is_installed('cvat.apps.dataset_repo'), 'ANALYTICS': strtobool(os.environ.get("CVAT_ANALYTICS", '0')), 'MODELS': strtobool(os.environ.get("CVAT_SERVERLESS", '0')), 'PREDICT': False, # FIXME: it is unused anymore (for UI only) } - return Response(response) + return Response(PluginsSerializer(data).data) @extend_schema(tags=['projects']) @extend_schema_view( diff --git a/cvat/apps/iam/permissions.py b/cvat/apps/iam/permissions.py index 2a1893e8b1b9..f568415fbec9 100644 --- a/cvat/apps/iam/permissions.py +++ b/cvat/apps/iam/permissions.py @@ -62,7 +62,7 @@ def get_organization(request, obj): except AttributeError as exc: # Skip initialization of organization for those objects that don't related with organization view = request.parser_context.get('view') - if view and view.basename in ('user', 'function', 'request',): + if view and view.basename in ('user', 'function', 'request', 'server'): return request.iam_context['organization'] raise exc