You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
587 lines
20 KiB
J���������
587 lines
20 KiB
J���������
// Copyright (C) 2020-2022 Intel Corporation
|
|
// Copyright (C) 2022-2023 CVAT.ai Corporation
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
const {
|
|
tasksDummyData,
|
|
projectsDummyData,
|
|
aboutDummyData,
|
|
formatsDummyData,
|
|
shareDummyData,
|
|
usersDummyData,
|
|
taskAnnotationsDummyData,
|
|
jobAnnotationsDummyData,
|
|
frameMetaDummyData,
|
|
cloudStoragesDummyData,
|
|
webhooksDummyData,
|
|
webhooksEventsDummyData,
|
|
jobsDummyData,
|
|
} = require('./dummy-data.mock');
|
|
|
|
function QueryStringToJSON(query, ignoreList = []) {
|
|
const pairs = [...new URLSearchParams(query).entries()];
|
|
|
|
const result = {};
|
|
for (const pair of pairs) {
|
|
const [key, value] = pair;
|
|
if (!ignoreList.includes(key)) {
|
|
if (['id'].includes(key)) {
|
|
result[key] = +value;
|
|
} else {
|
|
result[key] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return JSON.parse(JSON.stringify(result));
|
|
}
|
|
|
|
class ServerProxy {
|
|
constructor() {
|
|
async function about() {
|
|
return JSON.parse(JSON.stringify(aboutDummyData));
|
|
}
|
|
|
|
async function share(directory) {
|
|
let position = shareDummyData;
|
|
|
|
// Emulation of internal directories
|
|
if (directory.length > 1) {
|
|
const components = directory.split('/');
|
|
|
|
for (const component of components) {
|
|
const idx = position.map((x) => x.name).indexOf(component);
|
|
if (idx !== -1 && 'children' in position[idx]) {
|
|
position = position[idx].children;
|
|
} else {
|
|
throw new window.cvat.exceptions.ServerError(`${component} is not a valid directory`, 400);
|
|
}
|
|
}
|
|
}
|
|
|
|
return JSON.parse(JSON.stringify(position));
|
|
}
|
|
|
|
async function formats() {
|
|
return JSON.parse(JSON.stringify(formatsDummyData));
|
|
}
|
|
|
|
async function exception() {
|
|
return null;
|
|
}
|
|
|
|
async function login() {
|
|
return null;
|
|
}
|
|
|
|
async function logout() {
|
|
return null;
|
|
}
|
|
|
|
async function getProjects(filter = '') {
|
|
const queries = QueryStringToJSON(filter);
|
|
const result = projectsDummyData.results.filter((x) => {
|
|
for (const key in queries) {
|
|
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
// TODO: Particular match for some fields is not checked
|
|
if (queries[key] !== x[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
async function saveProject(id, projectData) {
|
|
const object = projectsDummyData.results.filter((project) => project.id === id)[0];
|
|
for (const prop in projectData) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(projectData, prop) &&
|
|
Object.prototype.hasOwnProperty.call(object, prop)
|
|
) {
|
|
if (prop === 'labels') {
|
|
object[prop] = projectData[prop].filter((label) => !label.deleted);
|
|
} else {
|
|
object[prop] = projectData[prop];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function createProject(projectData) {
|
|
const id = Math.max(...projectsDummyData.results.map((el) => el.id)) + 1;
|
|
projectsDummyData.results.push({
|
|
id,
|
|
url: `http://localhost:7000/api/projects/${id}`,
|
|
name: projectData.name,
|
|
owner: 1,
|
|
assignee: null,
|
|
bug_tracker: projectData.bug_tracker,
|
|
created_date: '2019-05-16T13:08:00.621747+03:00',
|
|
updated_date: '2019-05-16T13:08:00.621797+03:00',
|
|
status: 'annotation',
|
|
tasks: [],
|
|
labels: JSON.parse(JSON.stringify(projectData.labels)),
|
|
});
|
|
|
|
const createdProject = await getProjects(`?id=${id}`);
|
|
return createdProject[0];
|
|
}
|
|
|
|
async function deleteProject(id) {
|
|
const projects = projectsDummyData.results;
|
|
const project = projects.filter((el) => el.id === id)[0];
|
|
if (project) {
|
|
projects.splice(projects.indexOf(project), 1);
|
|
}
|
|
}
|
|
|
|
async function getTasks(filter = '') {
|
|
// Emulation of a query filter
|
|
const queries = QueryStringToJSON(filter);
|
|
const result = tasksDummyData.results.filter((x) => {
|
|
for (const key in queries) {
|
|
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
// TODO: Particular match for some fields is not checked
|
|
if (queries[key] !== x[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
async function saveTask(id, taskData) {
|
|
const object = tasksDummyData.results.filter((task) => task.id === id)[0];
|
|
for (const prop in taskData) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(taskData, prop) &&
|
|
Object.prototype.hasOwnProperty.call(object, prop)
|
|
) {
|
|
if (prop === 'labels') {
|
|
object[prop] = taskData[prop].filter((label) => !label.deleted);
|
|
} else {
|
|
object[prop] = taskData[prop];
|
|
}
|
|
}
|
|
}
|
|
|
|
const [updatedTask] = await getTasks({ id });
|
|
return updatedTask;
|
|
}
|
|
|
|
async function createTask(taskData) {
|
|
const id = Math.max(...tasksDummyData.results.map((el) => el.id)) + 1;
|
|
tasksDummyData.results.push({
|
|
id,
|
|
url: `http://localhost:7000/api/tasks/${id}`,
|
|
name: taskData.name,
|
|
project_id: taskData.project_id || null,
|
|
size: 5000,
|
|
mode: 'interpolation',
|
|
owner: {
|
|
id: 2,
|
|
username: 'bsekache',
|
|
},
|
|
assignee: null,
|
|
bug_tracker: taskData.bug_tracker,
|
|
created_date: '2019-05-16T13:08:00.621747+03:00',
|
|
updated_date: '2019-05-16T13:08:00.621797+03:00',
|
|
overlap: taskData.overlap ? taskData.overlap : 5,
|
|
segment_size: taskData.segment_size ? taskData.segment_size : 5000,
|
|
flipped: false,
|
|
status: 'annotation',
|
|
image_quality: taskData.image_quality,
|
|
labels: JSON.parse(JSON.stringify(taskData.labels)),
|
|
});
|
|
|
|
const createdTask = await getTasks(`?id=${id}`);
|
|
return createdTask[0];
|
|
}
|
|
|
|
async function deleteTask(id) {
|
|
const tasks = tasksDummyData.results;
|
|
const task = tasks.filter((el) => el.id === id)[0];
|
|
if (task) {
|
|
tasks.splice(tasks.indexOf(task), 1);
|
|
}
|
|
}
|
|
|
|
async function getJobs(filter = {}) {
|
|
function makeJsonFilter(jsonExpr) {
|
|
if (!jsonExpr) {
|
|
return (job) => true;
|
|
}
|
|
|
|
// This function only covers test cases. Extend it if needed.
|
|
function escapeRegExp(string) {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
}
|
|
let pattern = JSON.stringify({
|
|
and: [{ '==': [{ var: 'task_id' }, '<id>'] }]
|
|
});
|
|
pattern = escapeRegExp(pattern).replace('"<id>"', '(\\d+)');
|
|
const matches = jsonExpr.match(pattern);
|
|
const task_id = Number.parseInt(matches[1]);
|
|
return (job) => job.task_id === task_id;
|
|
};
|
|
|
|
const id = filter.id || null;
|
|
const jobs = jobsDummyData.results.filter(makeJsonFilter(filter.filter || null));
|
|
|
|
for (const job of jobs) {
|
|
const task = tasksDummyData.results.find((task) => task.id === job.task_id);
|
|
job.dimension = task.dimension;
|
|
job.data_compressed_chunk_type = task.data_compressed_chunk_type;
|
|
job.data_chunk_size = task.data_chunk_size;
|
|
job.bug_tracker = task.bug_tracker;
|
|
job.mode = task.mode;
|
|
job.labels = task.labels;
|
|
}
|
|
|
|
if (id !== null) {
|
|
// A specific object is requested
|
|
return jobs.filter((job) => job.id === id)[0] || null;
|
|
}
|
|
|
|
return (
|
|
jobs ? {
|
|
results: jobs,
|
|
count: jobs.length,
|
|
} : {
|
|
detail: 'Not found.',
|
|
}
|
|
);
|
|
}
|
|
|
|
async function saveJob(id, jobData) {
|
|
const object = jobsDummyData.results
|
|
.filter((job) => job.id === id)[0];
|
|
|
|
for (const prop in jobData) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(jobData, prop) &&
|
|
Object.prototype.hasOwnProperty.call(object, prop)
|
|
) {
|
|
object[prop] = jobData[prop];
|
|
}
|
|
}
|
|
|
|
return getJobs({ id });
|
|
}
|
|
|
|
async function getUsers() {
|
|
return JSON.parse(JSON.stringify(usersDummyData)).results;
|
|
}
|
|
|
|
async function getSelf() {
|
|
return JSON.parse(JSON.stringify(usersDummyData)).results[0];
|
|
}
|
|
|
|
async function getPreview() {
|
|
return 'DUMMY_IMAGE';
|
|
}
|
|
|
|
async function getData() {
|
|
return 'DUMMY_IMAGE';
|
|
}
|
|
|
|
async function getMeta(session, jid) {
|
|
if (session !== 'job') {
|
|
throw new Error('not implemented test');
|
|
}
|
|
|
|
return JSON.parse(JSON.stringify(frameMetaDummyData[jid]));
|
|
}
|
|
|
|
async function saveMeta(session, jid, meta) {
|
|
if (session !== 'job') {
|
|
throw new Error('not implemented test');
|
|
}
|
|
const object = frameMetaDummyData[jid];
|
|
for (const prop in meta) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(meta, prop) &&
|
|
Object.prototype.hasOwnProperty.call(object, prop)
|
|
) {
|
|
if (prop === 'labels') {
|
|
object[prop] = meta[prop].filter((label) => !label.deleted);
|
|
} else {
|
|
object[prop] = meta[prop];
|
|
}
|
|
}
|
|
}
|
|
|
|
return getMeta(jid);
|
|
}
|
|
|
|
async function getAnnotations(session, id) {
|
|
if (session === 'task') {
|
|
return JSON.parse(JSON.stringify(taskAnnotationsDummyData[id]));
|
|
}
|
|
|
|
if (session === 'job') {
|
|
return JSON.parse(JSON.stringify(jobAnnotationsDummyData[id]));
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function updateAnnotations(session, id, data, action) {
|
|
// Actually we do not change our dummy data
|
|
// We just update the argument in some way and return it
|
|
|
|
data.version += 1;
|
|
|
|
if (action === 'create') {
|
|
let idGenerator = 1000;
|
|
data.tracks
|
|
.concat(data.tags)
|
|
.concat(data.shapes)
|
|
.map((el) => {
|
|
el.id = ++idGenerator;
|
|
return el;
|
|
});
|
|
|
|
return data;
|
|
}
|
|
|
|
if (action === 'update') {
|
|
return data;
|
|
}
|
|
|
|
if (action === 'delete') {
|
|
return data;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function getCloudStorages(filter = '') {
|
|
const queries = QueryStringToJSON(filter);
|
|
const result = cloudStoragesDummyData.results.filter((item) => {
|
|
for (const key in queries) {
|
|
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
if (queries[key] !== item[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
async function updateCloudStorage(id, cloudStorageData) {
|
|
const cloudStorage = cloudStoragesDummyData.results.find((item) => item.id === id);
|
|
if (cloudStorage) {
|
|
for (const prop in cloudStorageData) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(cloudStorageData, prop) &&
|
|
Object.prototype.hasOwnProperty.call(cloudStorage, prop)
|
|
) {
|
|
cloudStorage[prop] = cloudStorageData[prop];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function createCloudStorage(cloudStorageData) {
|
|
const id = Math.max(...cloudStoragesDummyData.results.map((item) => item.id)) + 1;
|
|
cloudStoragesDummyData.results.push({
|
|
id,
|
|
provider_type: cloudStorageData.provider_type,
|
|
resource: cloudStorageData.resource,
|
|
display_name: cloudStorageData.display_name,
|
|
credentials_type: cloudStorageData.credentials_type,
|
|
specific_attributes: cloudStorageData.specific_attributes,
|
|
description: cloudStorageData.description,
|
|
owner: 1,
|
|
created_date: '2021-09-01T09:29:47.094244+03:00',
|
|
updated_date: '2021-09-01T09:29:47.103264+03:00',
|
|
});
|
|
|
|
const result = await getCloudStorages(`?id=${id}`);
|
|
return result[0];
|
|
}
|
|
|
|
async function deleteCloudStorage(id) {
|
|
const cloudStorages = cloudStoragesDummyData.results;
|
|
const cloudStorageId = cloudStorages.findIndex((item) => item.id === id);
|
|
if (cloudStorageId !== -1) {
|
|
cloudStorages.splice(cloudStorageId);
|
|
}
|
|
}
|
|
|
|
async function getWebhooks(filter = '') {
|
|
const queries = QueryStringToJSON(filter);
|
|
const result = webhooksDummyData.results.filter((item) => {
|
|
for (const key in queries) {
|
|
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
if (queries[key] !== item[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
async function createWebhook(webhookData) {
|
|
const id = Math.max(...webhooksDummyData.results.map((item) => item.id)) + 1;
|
|
webhooksDummyData.results.push({
|
|
id,
|
|
description: webhookData.description,
|
|
target_url: webhookData.target_url,
|
|
content_type: webhookData.content_type,
|
|
secret: webhookData.secret,
|
|
enable_ssl: webhookData.enable_ssl,
|
|
is_active: webhookData.is_active,
|
|
events: webhookData.events,
|
|
organization_id: webhookData.organization_id ? webhookData.organization_id : null,
|
|
project_id: webhookData.project_id ? webhookData.project_id : null,
|
|
type: webhookData.type,
|
|
owner: { id: 1 },
|
|
created_date: '2022-09-23T06:29:12.337276Z',
|
|
updated_date: '2022-09-23T06:29:12.337276Z',
|
|
});
|
|
|
|
const result = await getWebhooks(`?id=${id}`);
|
|
return result[0];
|
|
}
|
|
|
|
async function updateWebhook(webhookID, webhookData) {
|
|
const webhook = webhooksDummyData.results.find((item) => item.id === webhookID);
|
|
if (webhook) {
|
|
for (const prop in webhookData) {
|
|
if (
|
|
Object.prototype.hasOwnProperty.call(webhookData, prop) &&
|
|
Object.prototype.hasOwnProperty.call(webhook, prop)
|
|
) {
|
|
webhook[prop] = webhookData[prop];
|
|
}
|
|
}
|
|
}
|
|
return webhook;
|
|
}
|
|
|
|
async function receiveWebhookEvents(type) {
|
|
return webhooksEventsDummyData[type]?.events;
|
|
}
|
|
|
|
async function deleteWebhook(webhookID) {
|
|
const webhooks = webhooksDummyData.results;
|
|
const webhookIdx = webhooks.findIndex((item) => item.id === webhookID);
|
|
if (webhookIdx !== -1) {
|
|
webhooks.splice(webhookIdx);
|
|
}
|
|
}
|
|
|
|
Object.defineProperties(
|
|
this,
|
|
Object.freeze({
|
|
server: {
|
|
value: Object.freeze({
|
|
about,
|
|
share,
|
|
formats,
|
|
exception,
|
|
login,
|
|
logout,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
projects: {
|
|
value: Object.freeze({
|
|
get: getProjects,
|
|
save: saveProject,
|
|
create: createProject,
|
|
delete: deleteProject,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
tasks: {
|
|
value: Object.freeze({
|
|
get: getTasks,
|
|
save: saveTask,
|
|
create: createTask,
|
|
delete: deleteTask,
|
|
getPreview: getPreview,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
jobs: {
|
|
value: Object.freeze({
|
|
get: getJobs,
|
|
save: saveJob,
|
|
getPreview: getPreview,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
users: {
|
|
value: Object.freeze({
|
|
get: getUsers,
|
|
self: getSelf,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
frames: {
|
|
value: Object.freeze({
|
|
getData,
|
|
getMeta,
|
|
saveMeta,
|
|
getPreview,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
annotations: {
|
|
value: {
|
|
updateAnnotations,
|
|
getAnnotations,
|
|
},
|
|
},
|
|
|
|
cloudStorages: {
|
|
value: Object.freeze({
|
|
get: getCloudStorages,
|
|
update: updateCloudStorage,
|
|
create: createCloudStorage,
|
|
delete: deleteCloudStorage,
|
|
}),
|
|
writable: false,
|
|
},
|
|
|
|
webhooks: {
|
|
value: Object.freeze({
|
|
get: getWebhooks,
|
|
create: createWebhook,
|
|
update: updateWebhook,
|
|
delete: deleteWebhook,
|
|
events: receiveWebhookEvents,
|
|
}),
|
|
writable: false,
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
|
|
const serverProxy = new ServerProxy();
|
|
module.exports = serverProxy;
|