From bfe82abd350440ce52cbacae3197bbf2a717f869 Mon Sep 17 00:00:00 2001 From: Kirill Lakhov Date: Thu, 13 Feb 2025 16:22:34 +0300 Subject: [PATCH] updated implementation --- cvat-core/src/about.ts | 41 +++++++++++++++++++++ cvat-core/src/api-implementation.ts | 3 +- cvat-core/src/index.ts | 3 +- cvat-core/src/server-response-types.ts | 2 +- cvat-ui/src/actions/about-actions.ts | 4 +- cvat-ui/src/components/common/cvat-logo.tsx | 2 +- cvat-ui/src/cvat-core-wrapper.ts | 2 + cvat-ui/src/reducers/index.ts | 3 +- cvat/apps/engine/serializers.py | 2 +- cvat/apps/engine/views.py | 16 +++++--- cvat/schema.yml | 4 +- cvat/settings/base.py | 10 +---- 12 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 cvat-core/src/about.ts diff --git a/cvat-core/src/about.ts b/cvat-core/src/about.ts new file mode 100644 index 000000000000..1604f825ced5 --- /dev/null +++ b/cvat-core/src/about.ts @@ -0,0 +1,41 @@ +// Copyright (C) CVAT.ai Corporation +// +// SPDX-License-Identifier: MIT + +import { SerializedAbout } from './server-response-types'; + +export default class AboutData { + #description: string; + #name: string; + #version: string; + #logoURL: string; + #subtitle: string; + + constructor(initialData: SerializedAbout) { + this.#description = initialData.description; + this.#name = initialData.name; + this.#version = initialData.version; + this.#logoURL = initialData.logo_url; + this.#subtitle = initialData.subtitle; + } + + get description(): string { + return this.#description; + } + + get name(): string { + return this.#name; + } + + get version(): string { + return this.#version; + } + + get logoURL(): string { + return this.#logoURL; + } + + get subtitle(): string { + return this.#subtitle; + } +} diff --git a/cvat-core/src/api-implementation.ts b/cvat-core/src/api-implementation.ts index 2599ca57e48f..559cb6f9f4b3 100644 --- a/cvat-core/src/api-implementation.ts +++ b/cvat-core/src/api-implementation.ts @@ -35,6 +35,7 @@ import { QualitySettingsFilter, SerializedAsset, } from './server-response-types'; import QualityReport from './quality-report'; +import AboutData from './about'; import QualityConflict, { ConflictSeverity } from './quality-conflict'; import QualitySettings from './quality-settings'; import { getFramesMeta } from './frames'; @@ -72,7 +73,7 @@ export default function implementAPI(cvat: CVATCore): CVATCore { implementationMixin(cvat.server.about, async () => { const result = await serverProxy.server.about(); - return result; + return new AboutData(result); }); implementationMixin(cvat.server.share, async (directory: string, searchPrefix?: string) => { const result = await serverProxy.server.share(directory, searchPrefix); diff --git a/cvat-core/src/index.ts b/cvat-core/src/index.ts index d2629cea33b4..52f755ce04ad 100644 --- a/cvat-core/src/index.ts +++ b/cvat-core/src/index.ts @@ -34,6 +34,7 @@ import AnalyticsReport from './analytics-report'; import AnnotationGuide from './guide'; import { JobValidationLayout, TaskValidationLayout } from './validation-layout'; import { Request } from './request'; +import AboutData from './about'; import { runAction, callAction, @@ -61,7 +62,7 @@ export default interface CVATCore { requests: typeof lambdaManager.requests; }; server: { - about: typeof serverProxy.server.about; + about: () => Promise; share: (dir: string) => Promise<{ mimeType: string; name: string; diff --git a/cvat-core/src/server-response-types.ts b/cvat-core/src/server-response-types.ts index 70a457343078..90bea042d905 100644 --- a/cvat-core/src/server-response-types.ts +++ b/cvat-core/src/server-response-types.ts @@ -177,7 +177,7 @@ export interface SerializedAbout { description: string; name: string; version: string; - logo: string; + logo_url: string; subtitle: string; } diff --git a/cvat-ui/src/actions/about-actions.ts b/cvat-ui/src/actions/about-actions.ts index eab65ca19b20..a461cda43977 100644 --- a/cvat-ui/src/actions/about-actions.ts +++ b/cvat-ui/src/actions/about-actions.ts @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT import { ActionUnion, createAction, ThunkAction } from 'utils/redux'; -import { getCore } from 'cvat-core-wrapper'; +import { AboutData, getCore } from 'cvat-core-wrapper'; const core = getCore(); @@ -15,7 +15,7 @@ export enum AboutActionTypes { const aboutActions = { getAbout: () => createAction(AboutActionTypes.GET_ABOUT), - getAboutSuccess: (server: any) => createAction(AboutActionTypes.GET_ABOUT_SUCCESS, { server }), + getAboutSuccess: (server: AboutData) => createAction(AboutActionTypes.GET_ABOUT_SUCCESS, { server }), getAboutFailed: (error: any) => createAction(AboutActionTypes.GET_ABOUT_FAILED, { error }), }; diff --git a/cvat-ui/src/components/common/cvat-logo.tsx b/cvat-ui/src/components/common/cvat-logo.tsx index a9102f9de4e1..d1fdba39adff 100644 --- a/cvat-ui/src/components/common/cvat-logo.tsx +++ b/cvat-ui/src/components/common/cvat-logo.tsx @@ -7,7 +7,7 @@ import { useSelector } from 'react-redux'; import { CombinedState } from 'reducers'; function CVATLogo(): JSX.Element { - const logo = useSelector((state: CombinedState) => state.about.server.logo); + const logo = useSelector((state: CombinedState) => state.about.server.logoURL); return (
diff --git a/cvat-ui/src/cvat-core-wrapper.ts b/cvat-ui/src/cvat-core-wrapper.ts index 73fce3ea9396..42bd9a86b65d 100644 --- a/cvat-ui/src/cvat-core-wrapper.ts +++ b/cvat-ui/src/cvat-core-wrapper.ts @@ -44,6 +44,7 @@ import { BaseShapesAction } from 'cvat-core/src/annotations-actions/base-shapes- import { BaseCollectionAction } from 'cvat-core/src/annotations-actions/base-collection-action'; import { ActionParameterType, BaseAction } from 'cvat-core/src/annotations-actions/base-action'; import { Request, RequestOperation } from 'cvat-core/src/request'; +import AboutData from 'cvat-core/src/about'; const cvat: CVATCore = _cvat; @@ -114,6 +115,7 @@ export { JobValidationLayout, TaskValidationLayout, StorageLocation, + AboutData, }; export type { diff --git a/cvat-ui/src/reducers/index.ts b/cvat-ui/src/reducers/index.ts index aaf1f6e329c8..370a468e191a 100644 --- a/cvat-ui/src/reducers/index.ts +++ b/cvat-ui/src/reducers/index.ts @@ -9,6 +9,7 @@ import { Webhook, MLModel, Organization, Job, Task, Project, Label, User, QualityConflict, FramesMetaData, RQStatus, Event, Invitation, SerializedAPISchema, Request, JobValidationLayout, QualitySettings, TaskValidationLayout, ObjectState, + AboutData, } from 'cvat-core-wrapper'; import { IntelligentScissors } from 'utils/opencv-wrapper/intelligent-scissors'; import { KeyMap, KeyMapItem } from 'utils/mousetrap-react'; @@ -336,7 +337,7 @@ export interface PluginsState { } export interface AboutState { - server: any; + server: AboutData; packageVersion: { ui: string; }; diff --git a/cvat/apps/engine/serializers.py b/cvat/apps/engine/serializers.py index a8d3917a2405..56de4b91da9e 100644 --- a/cvat/apps/engine/serializers.py +++ b/cvat/apps/engine/serializers.py @@ -2627,7 +2627,7 @@ class AboutSerializer(serializers.Serializer): name = serializers.CharField(max_length=128) description = serializers.CharField(max_length=2048) version = serializers.CharField(max_length=64) - logo = serializers.CharField() + logo_url = serializers.CharField() subtitle = serializers.CharField(max_length=1024) class FrameMetaSerializer(serializers.Serializer): diff --git a/cvat/apps/engine/views.py b/cvat/apps/engine/views.py index 165fe2d51158..fc6c356d1bfd 100644 --- a/cvat/apps/engine/views.py +++ b/cvat/apps/engine/views.py @@ -36,6 +36,7 @@ from django.utils.decorators import method_decorator from django.views.decorators.cache import never_cache from django_rq.queues import DjangoRQ +from django.core.files.storage import storages from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import ( OpenApiExample, @@ -189,9 +190,6 @@ _DATA_UPDATED_DATE_HEADER_NAME = 'X-Updated-Date' _RETRY_AFTER_TIMEOUT = 10 -def get_logo_uri(request) -> str: - return request.build_absolute_uri(f'{settings.STATIC_URL}{settings.LOGO_FILENAME}') - @extend_schema(tags=['server']) class ServerViewSet(viewsets.ViewSet): serializer_class = None @@ -213,11 +211,17 @@ def get_serializer(self, *args, **kwargs): def about(request): from cvat import __version__ as cvat_version about = { - "name": settings.ABOUT_INFO["name"], + "name": "Computer Vision Annotation Tool", "subtitle": settings.ABOUT_INFO["subtitle"], - "description": settings.ABOUT_INFO["description"], + "description": "CVAT is completely re-designed and re-implemented " + + "version of Video Annotation Tool from Irvine, California " + + "tool. It is free, online, interactive video and image annotation " + + "tool for computer vision. It is being used by our team to " + + "annotate million of objects with different properties. Many UI " + + "and UX decisions are based on feedbacks from professional data " + + "annotation team.", "version": cvat_version, - "logo": get_logo_uri(request), + "logo_url": request.build_absolute_uri(storages["staticfiles"].url(settings.LOGO_FILENAME)), } serializer = AboutSerializer(data=about) if serializer.is_valid(raise_exception=True): diff --git a/cvat/schema.yml b/cvat/schema.yml index 16be0fae4f34..d1dc9d6307a2 100644 --- a/cvat/schema.yml +++ b/cvat/schema.yml @@ -6905,14 +6905,14 @@ components: version: type: string maxLength: 64 - logo: + logo_url: type: string subtitle: type: string maxLength: 1024 required: - description - - logo + - logo_url - name - subtitle - version diff --git a/cvat/settings/base.py b/cvat/settings/base.py index 38b83ccd7873..cc4b5d9b01b5 100644 --- a/cvat/settings/base.py +++ b/cvat/settings/base.py @@ -770,15 +770,7 @@ class CVAT_QUEUES(Enum): # Indicates the maximum number of days a file or directory is retained in the temporary directory TMP_FILE_OR_DIR_RETENTION_DAYS = 3 -LOGO_FILENAME = 'logo.png' +LOGO_FILENAME = 'logo.svg' ABOUT_INFO = { - "name": "Computer Vision Annotation Tool", "subtitle": "Open Data Annotation Platform", - "description": "CVAT is completely re-designed and re-implemented " + - "version of Video Annotation Tool from Irvine, California " + - "tool. It is free, online, interactive video and image annotation " + - "tool for computer vision. It is being used by our team to " + - "annotate million of objects with different properties. Many UI " + - "and UX decisions are based on feedbacks from professional data " + - "annotation team.", }