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.
380 lines
12 KiB
JavaScript
380 lines
12 KiB
JavaScript
/*
|
|
* Copyright (C) 2019-2020 Intel Corporation
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
/* global
|
|
require:false
|
|
*/
|
|
|
|
(() => {
|
|
const serverProxy = require('./server-proxy');
|
|
const Collection = require('./annotations-collection');
|
|
const AnnotationsSaver = require('./annotations-saver');
|
|
const AnnotationsHistory = require('./annotations-history');
|
|
const { checkObjectType } = require('./common');
|
|
const { Task } = require('./session');
|
|
const {
|
|
Loader,
|
|
Dumper,
|
|
} = require('./annotation-formats.js');
|
|
const {
|
|
ScriptingError,
|
|
DataError,
|
|
ArgumentError,
|
|
} = require('./exceptions');
|
|
|
|
const jobCache = new WeakMap();
|
|
const taskCache = new WeakMap();
|
|
|
|
function getCache(sessionType) {
|
|
if (sessionType === 'task') {
|
|
return taskCache;
|
|
}
|
|
|
|
if (sessionType === 'job') {
|
|
return jobCache;
|
|
}
|
|
|
|
throw new ScriptingError(
|
|
`Unknown session type was received ${sessionType}`,
|
|
);
|
|
}
|
|
|
|
async function getAnnotationsFromServer(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (!cache.has(session)) {
|
|
const rawAnnotations = await serverProxy.annotations
|
|
.getAnnotations(sessionType, session.id);
|
|
|
|
// Get meta information about frames
|
|
const startFrame = sessionType === 'job' ? session.startFrame : 0;
|
|
const stopFrame = sessionType === 'job' ? session.stopFrame : session.size - 1;
|
|
const frameMeta = {};
|
|
for (let i = startFrame; i <= stopFrame; i++) {
|
|
frameMeta[i] = await session.frames.get(i);
|
|
}
|
|
|
|
const history = new AnnotationsHistory();
|
|
const collection = new Collection({
|
|
labels: session.labels || session.task.labels,
|
|
history,
|
|
startFrame,
|
|
stopFrame,
|
|
frameMeta,
|
|
});
|
|
collection.import(rawAnnotations);
|
|
|
|
const saver = new AnnotationsSaver(rawAnnotations.version, collection, session);
|
|
|
|
cache.set(session, {
|
|
collection,
|
|
saver,
|
|
history,
|
|
});
|
|
}
|
|
}
|
|
|
|
async function closeSession(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
cache.delete(session);
|
|
}
|
|
}
|
|
|
|
async function getAnnotations(session, frame, allTracks, filters) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.get(frame, allTracks, filters);
|
|
}
|
|
|
|
await getAnnotationsFromServer(session);
|
|
return cache.get(session).collection.get(frame, allTracks, filters);
|
|
}
|
|
|
|
async function saveAnnotations(session, onUpdate) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
await cache.get(session).saver.save(onUpdate);
|
|
}
|
|
|
|
// If a collection wasn't uploaded, than it wasn't changed, finally we shouldn't save it
|
|
}
|
|
|
|
function searchAnnotations(session, filters, frameFrom, frameTo) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.search(filters, frameFrom, frameTo);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function mergeAnnotations(session, objectStates) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.merge(objectStates);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function splitAnnotations(session, objectState, frame) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.split(objectState, frame);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function groupAnnotations(session, objectStates, reset) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.group(objectStates, reset);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function hasUnsavedChanges(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).saver.hasUnsavedChanges();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
async function clearAnnotations(session, reload) {
|
|
checkObjectType('reload', reload, 'boolean', null);
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
cache.get(session).collection.clear();
|
|
}
|
|
|
|
if (reload) {
|
|
cache.delete(session);
|
|
await getAnnotationsFromServer(session);
|
|
}
|
|
}
|
|
|
|
function annotationsStatistics(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.statistics();
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function putAnnotations(session, objectStates) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.put(objectStates);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function selectObject(session, objectStates, x, y) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.select(objectStates, x, y);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
async function uploadAnnotations(session, file, loader) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
if (!(loader instanceof Loader)) {
|
|
throw new ArgumentError(
|
|
'A loader must be instance of Loader class',
|
|
);
|
|
}
|
|
await serverProxy.annotations.uploadAnnotations(sessionType, session.id, file, loader.name);
|
|
}
|
|
|
|
async function dumpAnnotations(session, name, dumper) {
|
|
if (!(dumper instanceof Dumper)) {
|
|
throw new ArgumentError(
|
|
'A dumper must be instance of Dumper class',
|
|
);
|
|
}
|
|
|
|
let result = null;
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
if (sessionType === 'job') {
|
|
result = await serverProxy.annotations
|
|
.dumpAnnotations(session.task.id, name, dumper.name);
|
|
} else {
|
|
result = await serverProxy.annotations
|
|
.dumpAnnotations(session.id, name, dumper.name);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function importAnnotations(session, data) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.import(data);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function exportAnnotations(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).collection.export();
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
async function exportDataset(session, format) {
|
|
if (!(format instanceof String || typeof format === 'string')) {
|
|
throw new ArgumentError(
|
|
'Format must be a string',
|
|
);
|
|
}
|
|
if (!(session instanceof Task)) {
|
|
throw new ArgumentError(
|
|
'A dataset can only be created from a task',
|
|
);
|
|
}
|
|
|
|
let result = null;
|
|
result = await serverProxy.tasks
|
|
.exportDataset(session.id, format);
|
|
|
|
return result;
|
|
}
|
|
|
|
function undoActions(session, count) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).history.undo(count);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function redoActions(session, count) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).history.redo(count);
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function clearActions(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).history.clear();
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
function getActions(session) {
|
|
const sessionType = session instanceof Task ? 'task' : 'job';
|
|
const cache = getCache(sessionType);
|
|
|
|
if (cache.has(session)) {
|
|
return cache.get(session).history.get();
|
|
}
|
|
|
|
throw new DataError(
|
|
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
|
|
);
|
|
}
|
|
|
|
module.exports = {
|
|
getAnnotations,
|
|
putAnnotations,
|
|
saveAnnotations,
|
|
hasUnsavedChanges,
|
|
mergeAnnotations,
|
|
searchAnnotations,
|
|
splitAnnotations,
|
|
groupAnnotations,
|
|
clearAnnotations,
|
|
annotationsStatistics,
|
|
selectObject,
|
|
uploadAnnotations,
|
|
dumpAnnotations,
|
|
importAnnotations,
|
|
exportAnnotations,
|
|
exportDataset,
|
|
undoActions,
|
|
redoActions,
|
|
clearActions,
|
|
getActions,
|
|
closeSession,
|
|
};
|
|
})();
|