diff --git a/cvat-core/README.md b/cvat-core/README.md
index f2d22d21..5f00bc03 100644
--- a/cvat-core/README.md
+++ b/cvat-core/README.md
@@ -13,7 +13,7 @@ npm install
- Building the module from sources in the ```dist``` directory:
```bash
-npm run-script build
+npm run build
npm run build -- --mode=development # without a minification
```
diff --git a/cvat-core/package.json b/cvat-core/package.json
index 4573565b..48ee0d0d 100644
--- a/cvat-core/package.json
+++ b/cvat-core/package.json
@@ -27,11 +27,10 @@
},
"dependencies": {
"axios": "^0.18.0",
- "browser-env": "^3.2.6",
"error-stack-parser": "^2.0.2",
+ "form-data": "^2.5.0",
"jest-config": "^24.8.0",
"js-cookie": "^2.2.0",
- "platform": "^1.3.5",
- "stacktrace-gps": "^3.0.2"
+ "platform": "^1.3.5"
}
}
diff --git a/cvat-core/src/annotations-collection.js b/cvat-core/src/annotations-collection.js
index fc03e725..7a5db6f0 100644
--- a/cvat-core/src/annotations-collection.js
+++ b/cvat-core/src/annotations-collection.js
@@ -24,6 +24,18 @@
} = require('./annotations-objects');
const { checkObjectType } = require('./common');
const Statistics = require('./statistics');
+ const { Label } = require('./labels');
+ const {
+ DataError,
+ ArgumentError,
+ ScriptingError,
+ } = require('./exceptions');
+
+ const {
+ ObjectShape,
+ ObjectType,
+ } = require('./enums');
+ const ObjectState = require('./object-state');
const colors = [
'#0066FF', '#AF593E', '#01A368', '#FF861F', '#ED0A3F', '#FF3F34', '#76D7EA',
@@ -62,7 +74,7 @@
shapeModel = new PointsShape(shapeData, clientID, color, injection);
break;
default:
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`An unexpected type of shape "${type}"`,
);
}
@@ -91,7 +103,7 @@
trackModel = new PointsTrack(trackData, clientID, color, injection);
break;
default:
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`An unexpected type of track "${type}"`,
);
}
@@ -209,10 +221,10 @@
checkObjectType('shapes for merge', objectStates, null, Array);
if (!objectStates.length) return;
const objectsForMerge = objectStates.map((state) => {
- checkObjectType('object state', state, null, window.cvat.classes.ObjectState);
+ checkObjectType('object state', state, null, ObjectState);
const object = this.objects[state.clientID];
if (typeof (object) === 'undefined') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'The object has not been saved yet. Call ObjectState.put([state]) before you can merge it',
);
}
@@ -222,13 +234,13 @@
const keyframes = {}; // frame: position
const { label, shapeType } = objectStates[0];
if (!(label.id in this.labels)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Unknown label for the task: ${label.id}`,
);
}
- if (!Object.values(window.cvat.enums.ObjectShape).includes(shapeType)) {
- throw new window.cvat.exceptions.ArgumentError(
+ if (!Object.values(ObjectShape).includes(shapeType)) {
+ throw new ArgumentError(
`Got unknown shapeType "${shapeType}"`,
);
}
@@ -243,13 +255,13 @@
const object = objectsForMerge[i];
const state = objectStates[i];
if (state.label.id !== label.id) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`All shape labels are expected to be ${label.name}, but got ${state.label.name}`,
);
}
if (state.shapeType !== shapeType) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`All shapes are expected to be ${shapeType}, but got ${state.shapeType}`,
);
}
@@ -258,7 +270,7 @@
if (object instanceof Shape) {
// Frame already saved and it is not outside
if (object.frame in keyframes && !keyframes[object.frame].outside) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Expected only one visible shape per frame',
);
}
@@ -303,7 +315,7 @@
continue;
}
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Expected only one visible shape per frame',
);
}
@@ -338,7 +350,7 @@
};
}
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Trying to merge unknown object type: ${object.constructor.name}. `
+ 'Only shapes and tracks are expected.',
);
@@ -389,17 +401,17 @@
}
split(objectState, frame) {
- checkObjectType('object state', objectState, null, window.cvat.classes.ObjectState);
+ checkObjectType('object state', objectState, null, ObjectState);
checkObjectType('frame', frame, 'integer', null);
const object = this.objects[objectState.clientID];
if (typeof (object) === 'undefined') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'The object has not been saved yet. Call annotations.put([state]) before',
);
}
- if (objectState.objectType !== window.cvat.enums.ObjectType.TRACK) {
+ if (objectState.objectType !== ObjectType.TRACK) {
return;
}
@@ -478,10 +490,10 @@
checkObjectType('shapes for group', objectStates, null, Array);
const objectsForGroup = objectStates.map((state) => {
- checkObjectType('object state', state, null, window.cvat.classes.ObjectState);
+ checkObjectType('object state', state, null, ObjectState);
const object = this.objects[state.clientID];
if (typeof (object) === 'undefined') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'The object has not been saved yet. Call annotations.put([state]) before',
);
}
@@ -549,7 +561,7 @@
} else if (object instanceof Tag) {
objectType = 'tag';
} else {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
`Unexpected object type: "${objectType}"`,
);
}
@@ -637,11 +649,11 @@
}
for (const state of objectStates) {
- checkObjectType('object state', state, null, window.cvat.classes.ObjectState);
+ checkObjectType('object state', state, null, ObjectState);
checkObjectType('state client ID', state.clientID, 'undefined', null);
checkObjectType('state frame', state.frame, 'integer', null);
checkObjectType('state attributes', state.attributes, null, Object);
- checkObjectType('state label', state.label, null, window.cvat.classes.Label);
+ checkObjectType('state label', state.label, null, Label);
const attributes = Object.keys(state.attributes)
.reduce(convertAttributes.bind(state), []);
@@ -666,10 +678,10 @@
checkObjectType('point coordinate', coord, 'number', null);
}
- if (!Object.values(window.cvat.enums.ObjectShape).includes(state.shapeType)) {
- throw new window.cvat.exceptions.ArgumentError(
+ if (!Object.values(ObjectShape).includes(state.shapeType)) {
+ throw new ArgumentError(
'Object shape must be one of: '
- + `${JSON.stringify(Object.values(window.cvat.enums.ObjectShape))}`,
+ + `${JSON.stringify(Object.values(ObjectShape))}`,
);
}
@@ -703,9 +715,9 @@
}],
});
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Object type must be one of: '
- + `${JSON.stringify(Object.values(window.cvat.enums.ObjectType))}`,
+ + `${JSON.stringify(Object.values(ObjectType))}`,
);
}
}
@@ -723,12 +735,12 @@
let minimumDistance = null;
let minimumState = null;
for (const state of objectStates) {
- checkObjectType('object state', state, null, window.cvat.classes.ObjectState);
+ checkObjectType('object state', state, null, ObjectState);
if (state.outside) continue;
const object = this.objects[state.clientID];
if (typeof (object) === 'undefined') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'The object has not been saved yet. Call annotations.put([state]) before',
);
}
diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js
index 71fa42cf..a70553a7 100644
--- a/cvat-core/src/annotations-objects.js
+++ b/cvat-core/src/annotations-objects.js
@@ -10,6 +10,19 @@
(() => {
const ObjectState = require('./object-state');
const { checkObjectType } = require('./common');
+ const {
+ ObjectShape,
+ ObjectType,
+ AttributeType,
+ } = require('./enums');
+
+ const {
+ DataError,
+ ArgumentError,
+ ScriptingError,
+ } = require('./exceptions');
+
+ const { Label } = require('./labels');
// Called with the Annotation context
function objectStateFactory(frame, data) {
@@ -26,32 +39,32 @@
}
function checkNumberOfPoints(shapeType, points) {
- if (shapeType === window.cvat.enums.ObjectShape.RECTANGLE) {
+ if (shapeType === ObjectShape.RECTANGLE) {
if (points.length / 2 !== 2) {
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`Rectangle must have 2 points, but got ${points.length / 2}`,
);
}
- } else if (shapeType === window.cvat.enums.ObjectShape.POLYGON) {
+ } else if (shapeType === ObjectShape.POLYGON) {
if (points.length / 2 < 3) {
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`Polygon must have at least 3 points, but got ${points.length / 2}`,
);
}
- } else if (shapeType === window.cvat.enums.ObjectShape.POLYLINE) {
+ } else if (shapeType === ObjectShape.POLYLINE) {
if (points.length / 2 < 2) {
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`Polyline must have at least 2 points, but got ${points.length / 2}`,
);
}
- } else if (shapeType === window.cvat.enums.ObjectShape.POINTS) {
+ } else if (shapeType === ObjectShape.POINTS) {
if (points.length / 2 < 1) {
- throw new window.cvat.exceptions.DataError(
+ throw new DataError(
`Points must have at least 1 points, but got ${points.length / 2}`,
);
}
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Unknown value of shapeType has been recieved ${shapeType}`,
);
}
@@ -61,7 +74,7 @@
const MIN_SHAPE_LENGTH = 3;
const MIN_SHAPE_AREA = 9;
- if (shapeType === window.cvat.enums.ObjectShape.POINTS) {
+ if (shapeType === ObjectShape.POINTS) {
return true;
}
@@ -77,7 +90,7 @@
ymax = Math.max(ymax, points[i + 1]);
}
- if (shapeType === window.cvat.enums.ObjectShape.POLYLINE) {
+ if (shapeType === ObjectShape.POLYLINE) {
const length = Math.max(
xmax - xmin,
ymax - ymin,
@@ -95,18 +108,18 @@
const type = attr.inputType;
if (typeof (value) !== 'string') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Attribute value is expected to be string, but got ${typeof (value)}`,
);
}
- if (type === window.cvat.enums.AttributeType.NUMBER) {
+ if (type === AttributeType.NUMBER) {
return +value >= +values[0]
&& +value <= +values[1]
&& !((+value - +values[0]) % +values[2]);
}
- if (type === window.cvat.enums.AttributeType.CHECKBOX) {
+ if (type === AttributeType.CHECKBOX) {
return ['true', 'false'].includes(value.toLowerCase());
}
@@ -171,19 +184,19 @@
}
save() {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Is not implemented',
);
}
get() {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Is not implemented',
);
}
toJSON() {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Is not implemented',
);
}
@@ -241,13 +254,13 @@
// Method is used to construct ObjectState objects
get(frame) {
if (frame !== this.frame) {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Got frame is not equal to the frame of the shape',
);
}
return {
- objectType: window.cvat.enums.ObjectType.SHAPE,
+ objectType: ObjectType.SHAPE,
shapeType: this.shapeType,
clientID: this.clientID,
serverID: this.serverID,
@@ -264,7 +277,7 @@
save(frame, data) {
if (frame !== this.frame) {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Got frame is not equal to the frame of the shape',
);
}
@@ -278,7 +291,7 @@
const updated = data.updateFlags;
if (updated.label) {
- checkObjectType('label', data.label, null, window.cvat.classes.Label);
+ checkObjectType('label', data.label, null, Label);
copy.label = data.label;
copy.attributes = {};
this.appendDefaultAttributes.call(copy, copy.label);
@@ -297,7 +310,7 @@
&& validateAttributeValue(value, labelAttributes[attrID])) {
copy.attributes[attrID] = value;
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Trying to save unknown attribute with id ${attrID} and value ${value}`,
);
}
@@ -352,7 +365,7 @@
if (updated.color) {
checkObjectType('color', data.color, 'string', null);
if (/^#[0-9A-F]{6}$/i.test(data.color)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Got invalid color value: "${data.color}"`,
);
}
@@ -456,7 +469,7 @@
{
attributes: this.getAttributes(frame),
group: this.group,
- objectType: window.cvat.enums.ObjectType.TRACK,
+ objectType: ObjectType.TRACK,
shapeType: this.shapeType,
clientID: this.clientID,
serverID: this.serverID,
@@ -537,7 +550,7 @@
let positionUpdated = false;
if (updated.label) {
- checkObjectType('label', data.label, null, window.cvat.classes.Label);
+ checkObjectType('label', data.label, null, Label);
copy.label = data.label;
copy.attributes = {};
@@ -558,7 +571,7 @@
&& validateAttributeValue(value, labelAttributes[attrID])) {
copy.attributes[attrID] = value;
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Trying to save unknown attribute with id ${attrID} and value ${value}`,
);
}
@@ -622,7 +635,7 @@
if (updated.color) {
checkObjectType('color', data.color, 'string', null);
if (/^#[0-9A-F]{6}$/i.test(data.color)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Got invalid color value: "${data.color}"`,
);
}
@@ -762,7 +775,7 @@
};
}
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
`No one neightbour frame found for the track with client ID: "${this.id}"`,
);
}
@@ -808,13 +821,13 @@
// Method is used to construct ObjectState objects
get(frame) {
if (frame !== this.frame) {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Got frame is not equal to the frame of the shape',
);
}
return {
- objectType: window.cvat.enums.ObjectType.TAG,
+ objectType: ObjectType.TAG,
clientID: this.clientID,
serverID: this.serverID,
lock: this.lock,
@@ -826,7 +839,7 @@
save(frame, data) {
if (frame !== this.frame) {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'Got frame is not equal to the frame of the shape',
);
}
@@ -840,7 +853,7 @@
const updated = data.updateFlags;
if (updated.label) {
- checkObjectType('label', data.label, null, window.cvat.classes.Label);
+ checkObjectType('label', data.label, null, Label);
copy.label = data.label;
copy.attributes = {};
this.appendDefaultAttributes.call(copy, copy.label);
@@ -882,7 +895,7 @@
class RectangleShape extends Shape {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.RECTANGLE;
+ this.shapeType = ObjectShape.RECTANGLE;
checkNumberOfPoints(this.shapeType, this.points);
}
@@ -908,7 +921,7 @@
class PolygonShape extends PolyShape {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POLYGON;
+ this.shapeType = ObjectShape.POLYGON;
checkNumberOfPoints(this.shapeType, this.points);
}
@@ -983,7 +996,7 @@
class PolylineShape extends PolyShape {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POLYLINE;
+ this.shapeType = ObjectShape.POLYLINE;
checkNumberOfPoints(this.shapeType, this.points);
}
@@ -1027,7 +1040,7 @@
class PointsShape extends PolyShape {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POINTS;
+ this.shapeType = ObjectShape.POINTS;
checkNumberOfPoints(this.shapeType, this.points);
}
@@ -1049,7 +1062,7 @@
class RectangleTrack extends Track {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.RECTANGLE;
+ this.shapeType = ObjectShape.RECTANGLE;
for (const shape of Object.values(this.shapes)) {
checkNumberOfPoints(this.shapeType, shape.points);
}
@@ -1374,7 +1387,7 @@
if (!targetMatched.length) {
// Prevent infinity loop
- throw new window.cvat.exceptions.ScriptingError('Interpolation mapping is empty');
+ throw new ScriptingError('Interpolation mapping is empty');
}
while (!targetMatched.includes(prev)) {
@@ -1463,7 +1476,7 @@
class PolygonTrack extends PolyTrack {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POLYGON;
+ this.shapeType = ObjectShape.POLYGON;
for (const shape of Object.values(this.shapes)) {
checkNumberOfPoints(this.shapeType, shape.points);
}
@@ -1473,7 +1486,7 @@
class PolylineTrack extends PolyTrack {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POLYLINE;
+ this.shapeType = ObjectShape.POLYLINE;
for (const shape of Object.values(this.shapes)) {
checkNumberOfPoints(this.shapeType, shape.points);
}
@@ -1483,7 +1496,7 @@
class PointsTrack extends PolyTrack {
constructor(data, clientID, color, injection) {
super(data, clientID, color, injection);
- this.shapeType = window.cvat.enums.ObjectShape.POINTS;
+ this.shapeType = ObjectShape.POINTS;
for (const shape of Object.values(this.shapes)) {
checkNumberOfPoints(this.shapeType, shape.points);
}
diff --git a/cvat-core/src/annotations-saver.js b/cvat-core/src/annotations-saver.js
index 49233646..4d76f1fb 100644
--- a/cvat-core/src/annotations-saver.js
+++ b/cvat-core/src/annotations-saver.js
@@ -9,10 +9,12 @@
(() => {
const serverProxy = require('./server-proxy');
+ const { Task } = require('./session');
+ const { ScriptingError } = ('./exceptions');
class AnnotationsSaver {
constructor(version, collection, session) {
- this.sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ this.sessionType = session instanceof Task ? 'task' : 'job';
this.id = session.id;
this.version = version;
this.collection = collection;
@@ -102,7 +104,7 @@
} else if (typeof (object.id) === 'undefined') {
splitted.created[type].push(object);
} else {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
`Id of object is defined "${object.id}"`
+ 'but it absents in initial state',
);
@@ -140,7 +142,7 @@
+ indexes.shapes.length + indexes.tags.length;
if (indexesLength !== savedLength) {
- throw new window.cvat.exception.ScriptingError(
+ throw new ScriptingError(
'Number of indexes is differed by number of saved objects'
+ `${indexesLength} vs ${savedLength}`,
);
diff --git a/cvat-core/src/annotations.js b/cvat-core/src/annotations.js
index dd8edb6f..059ff006 100644
--- a/cvat-core/src/annotations.js
+++ b/cvat-core/src/annotations.js
@@ -12,6 +12,11 @@
const Collection = require('./annotations-collection');
const AnnotationsSaver = require('./annotations-saver');
const { checkObjectType } = require('./common');
+ const { Task } = require('./session');
+ const {
+ ScriptingError,
+ DataError,
+ } = require('./exceptions');
const jobCache = new WeakMap();
const taskCache = new WeakMap();
@@ -25,13 +30,13 @@
return jobCache;
}
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
`Unknown session type was received ${sessionType}`,
);
}
async function getAnnotationsFromServer(session) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (!cache.has(session)) {
@@ -65,13 +70,13 @@
async function getAnnotations(session, frame, filter) {
await getAnnotationsFromServer(session);
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
return cache.get(session).collection.get(frame, filter);
}
async function saveAnnotations(session, onUpdate) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
@@ -82,46 +87,46 @@
}
function mergeAnnotations(session, objectStates) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
return cache.get(session).collection.merge(objectStates);
}
- throw new window.cvat.exceptions.DataError(
+ 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 window.cvat.classes.Task ? 'task' : 'job';
+ 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 window.cvat.exceptions.DataError(
+ 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 window.cvat.classes.Task ? 'task' : 'job';
+ 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 window.cvat.exceptions.DataError(
+ throw new DataError(
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
);
}
function hasUnsavedChanges(session) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
@@ -133,7 +138,7 @@
async function clearAnnotations(session, reload) {
checkObjectType('reload', reload, 'boolean', null);
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
@@ -147,51 +152,51 @@
}
function annotationsStatistics(session) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
return cache.get(session).collection.statistics();
}
- throw new window.cvat.exceptions.DataError(
+ 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 window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const cache = getCache(sessionType);
if (cache.has(session)) {
return cache.get(session).collection.put(objectStates);
}
- throw new window.cvat.exceptions.DataError(
+ 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 window.cvat.classes.Task ? 'task' : 'job';
+ 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 window.cvat.exceptions.DataError(
+ throw new DataError(
'Collection has not been initialized yet. Call annotations.get() or annotations.clear(true) before',
);
}
async function uploadAnnotations(session, file, format) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
await serverProxy.annotations.uploadAnnotations(sessionType, session.id, file, format);
}
async function dumpAnnotations(session, name, format) {
- const sessionType = session instanceof window.cvat.classes.Task ? 'task' : 'job';
+ const sessionType = session instanceof Task ? 'task' : 'job';
const result = await serverProxy.annotations
.dumpAnnotations(sessionType, session.id, name, format);
return result;
diff --git a/cvat-core/src/api-implementation.js b/cvat-core/src/api-implementation.js
index 0a7d8bb7..fde9c25b 100644
--- a/cvat-core/src/api-implementation.js
+++ b/cvat-core/src/api-implementation.js
@@ -21,9 +21,18 @@
checkFilter,
} = require('./common');
+ const {
+ TaskStatus,
+ TaskMode,
+ } = require('./enums');
+
+ const User = require('./user');
+ const { ArgumentError } = require('./exceptions');
+ const { Task } = require('./session');
+
function implementAPI(cvat) {
cvat.plugins.list.implementation = PluginRegistry.list;
- cvat.plugins.register.implementation = PluginRegistry.register;
+ cvat.plugins.register.implementation = PluginRegistry.register.bind(cvat);
cvat.server.about.implementation = async () => {
const result = await serverProxy.server.about();
@@ -56,7 +65,7 @@
users = await serverProxy.users.getUsers();
}
- users = users.map(user => new window.cvat.classes.User(user));
+ users = users.map(user => new User(user));
return users;
};
@@ -67,13 +76,13 @@
});
if (('taskID' in filter) && ('jobID' in filter)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Only one of fields "taskID" and "jobID" allowed simultaneously',
);
}
if (!Object.keys(filter).length) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Job filter must not be empty',
);
}
@@ -90,7 +99,7 @@
// If task was found by its id, then create task instance and get Job instance from it
if (tasks !== null && tasks.length) {
- const task = new window.cvat.classes.Task(tasks[0]);
+ const task = new Task(tasks[0]);
return filter.jobID ? task.jobs.filter(job => job.id === filter.jobID) : task.jobs;
}
@@ -105,13 +114,13 @@
owner: isString,
assignee: isString,
search: isString,
- status: isEnum.bind(window.cvat.enums.TaskStatus),
- mode: isEnum.bind(window.cvat.enums.TaskMode),
+ status: isEnum.bind(TaskStatus),
+ mode: isEnum.bind(TaskMode),
});
if ('search' in filter && Object.keys(filter).length > 1) {
if (!('page' in filter && Object.keys(filter).length === 2)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Do not use the filter field "search" with others',
);
}
@@ -119,7 +128,7 @@
if ('id' in filter && Object.keys(filter).length > 1) {
if (!('page' in filter && Object.keys(filter).length === 2)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Do not use the filter field "id" with others',
);
}
@@ -133,7 +142,7 @@
}
const tasksData = await serverProxy.tasks.getTasks(searchParams.toString());
- const tasks = tasksData.map(task => new window.cvat.classes.Task(task));
+ const tasks = tasksData.map(task => new Task(task));
tasks.count = tasksData.count;
return tasks;
diff --git a/cvat-core/src/api.js b/cvat-core/src/api.js
index af53cf6f..bf61f409 100644
--- a/cvat-core/src/api.js
+++ b/cvat-core/src/api.js
@@ -12,7 +12,7 @@
* @module API
*/
-(() => {
+function build() {
const PluginRegistry = require('./plugins');
const User = require('./user');
const ObjectState = require('./object-state');
@@ -41,7 +41,7 @@
} = require('./exceptions');
const pjson = require('../package.json');
- const clientID = +Date.now().toString().substr(-6);
+ const config = require('./config');
/**
* API entrypoint
@@ -274,7 +274,7 @@
* put: {
* // The first argument "self" is a plugin, like in a case above
* // The second argument is an argument of the
- * // cvat.Job.annotations.put()
+ * // Job.annotations.put()
* // It contains an array of objects to put
* // In this sample we round objects coordinates and save them
* enter(self, objects) {
@@ -301,7 +301,7 @@
* internal: {
* async getPlugins() {
* // Collect information about installed plugins
- * const plugins = await window.cvat.plugins.list();
+ * const plugins = await cvat.plugins.list();
* return plugins.map((el) => {
* return {
* name: el.name,
@@ -362,12 +362,32 @@
* value which is displayed in a logs
* @memberof module:API.cvat.config
*/
- backendAPI: 'http://localhost:7000/api/v1',
- proxy: false,
- taskID: undefined,
- jobID: undefined,
- clientID: {
- get: () => clientID,
+ get backendAPI() {
+ return config.backendAPI;
+ },
+ set backendAPI(value) {
+ config.backendAPI = value;
+ },
+ get proxy() {
+ return config.proxy;
+ },
+ set proxy(value) {
+ config.proxy = value;
+ },
+ get taskID() {
+ return config.taskID;
+ },
+ set taskID(value) {
+ config.taskID = value;
+ },
+ get jobID() {
+ return config.jobID;
+ },
+ set jobID(value) {
+ config.jobID = value;
+ },
+ get clientID() {
+ return config.clientID;
},
},
/**
@@ -439,18 +459,15 @@
cvat.plugins = Object.freeze(cvat.plugins);
cvat.client = Object.freeze(cvat.client);
cvat.enums = Object.freeze(cvat.enums);
- cvat.Job = Object.freeze(cvat.Job);
- cvat.Task = Object.freeze(cvat.Task);
const implementAPI = require('./api-implementation');
- if (typeof (window) === 'undefined') {
- // Dummy browser environment
- require('browser-env')();
- }
Math.clamp = function (value, min, max) {
return Math.min(Math.max(value, min), max);
};
- window.cvat = Object.freeze(implementAPI(cvat));
-})();
+ const implemented = Object.freeze(implementAPI(cvat));
+ return implemented;
+}
+
+module.exports = build();
diff --git a/cvat-core/src/common.js b/cvat-core/src/common.js
index dadbbf52..b0e6f014 100644
--- a/cvat-core/src/common.js
+++ b/cvat-core/src/common.js
@@ -3,7 +3,13 @@
* SPDX-License-Identifier: MIT
*/
+/* global
+ require:false
+*/
+
(() => {
+ const { ArgumentError } = require('./exceptions');
+
function isBoolean(value) {
return typeof (value) === 'boolean';
}
@@ -33,11 +39,11 @@
for (const prop in filter) {
if (Object.prototype.hasOwnProperty.call(filter, prop)) {
if (!(prop in fields)) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Unsupported filter property has been recieved: "${prop}"`,
);
} else if (!fields[prop](filter[prop])) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Received filter property "${prop}" is not satisfied for checker`,
);
}
@@ -53,20 +59,20 @@
return;
}
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`"${name}" is expected to be "${type}", but "${typeof (value)}" has been got.`,
);
}
} else if (instance) {
if (!(value instanceof instance)) {
if (value !== undefined) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`"${name}" is expected to be ${instance.name}, but `
+ `"${value.constructor.name}" has been got`,
);
}
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`"${name}" is expected to be ${instance.name}, but "undefined" has been got.`,
);
}
diff --git a/cvat-core/src/config.js b/cvat-core/src/config.js
new file mode 100644
index 00000000..30a86de3
--- /dev/null
+++ b/cvat-core/src/config.js
@@ -0,0 +1,12 @@
+/*
+* Copyright (C) 2018 Intel Corporation
+* SPDX-License-Identifier: MIT
+*/
+
+module.exports = {
+ backendAPI: 'http://localhost:7000/api/v1',
+ proxy: false,
+ taskID: undefined,
+ jobID: undefined,
+ clientID: +Date.now().toString().substr(-6),
+};
diff --git a/cvat-core/src/exceptions.js b/cvat-core/src/exceptions.js
index e10c6bae..e80c4ce0 100644
--- a/cvat-core/src/exceptions.js
+++ b/cvat-core/src/exceptions.js
@@ -10,6 +10,7 @@
(() => {
const Platform = require('platform');
const ErrorStackParser = require('error-stack-parser');
+ const config = require('./config');
/**
* Base exception class
@@ -35,7 +36,7 @@
jobID,
taskID,
clientID,
- } = window.cvat.config;
+ } = config;
const projID = undefined; // wasn't implemented
diff --git a/cvat-core/src/frames.js b/cvat-core/src/frames.js
index 5381fa8a..8a672387 100644
--- a/cvat-core/src/frames.js
+++ b/cvat-core/src/frames.js
@@ -11,6 +11,7 @@
(() => {
const PluginRegistry = require('./plugins');
const serverProxy = require('./server-proxy');
+ const { ArgumentError } = require('./exceptions');
// This is the frames storage
const frameDataCache = {};
@@ -78,11 +79,11 @@
if (!(this.number in frameCache[this.tid])) {
const frame = await serverProxy.frames.getData(this.tid, this.number);
- if (window.URL.createObjectURL) { // browser env
- const url = window.URL.createObjectURL(new Blob([frame]));
- frameCache[this.tid][this.number] = url;
- } else {
+ if (typeof (module) !== 'undefined' && module.exports) {
frameCache[this.tid][this.number] = global.Buffer.from(frame, 'binary').toString('base64');
+ } else {
+ const url = URL.createObjectURL(new Blob([frame]));
+ frameCache[this.tid][this.number] = url;
}
}
@@ -103,14 +104,14 @@
[size] = frameDataCache[taskID].meta;
} else if (mode === 'annotation') {
if (frame >= frameDataCache[taskID].meta.length) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Meta information about frame ${frame} can't be received from the server`,
);
} else {
size = frameDataCache[taskID].meta[frame];
}
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Invalid mode is specified ${mode}`,
);
}
diff --git a/cvat-core/src/labels.js b/cvat-core/src/labels.js
index 35c31278..de6ba99c 100644
--- a/cvat-core/src/labels.js
+++ b/cvat-core/src/labels.js
@@ -3,7 +3,14 @@
* SPDX-License-Identifier: MIT
*/
+/* global
+ require:false
+*/
+
(() => {
+ const { AttributeType } = require('./enums');
+ const { ArgumentError } = require('./exceptions');
+
/**
* Class representing an attribute
* @memberof module:API.cvat.classes
@@ -32,8 +39,8 @@
}
}
- if (!Object.values(window.cvat.enums.AttributeType).includes(data.input_type)) {
- throw new window.cvat.exceptions.ArgumentError(
+ if (!Object.values(AttributeType).includes(data.input_type)) {
+ throw new ArgumentError(
`Got invalid attribute type ${data.input_type}`,
);
}
@@ -144,7 +151,7 @@
if (Object.prototype.hasOwnProperty.call(initialData, 'attributes')
&& Array.isArray(initialData.attributes)) {
for (const attrData of initialData.attributes) {
- data.attributes.push(new window.cvat.classes.Attribute(attrData));
+ data.attributes.push(new Attribute(attrData));
}
}
diff --git a/cvat-core/src/object-state.js b/cvat-core/src/object-state.js
index 23c406c0..0f6ddb64 100644
--- a/cvat-core/src/object-state.js
+++ b/cvat-core/src/object-state.js
@@ -9,6 +9,7 @@
(() => {
const PluginRegistry = require('./plugins');
+ const { ArgumentError } = require('./exceptions');
/**
* Class representing a state of an object on a specific frame
@@ -162,7 +163,7 @@
data.updateFlags.points = true;
data.points = [...points];
} else {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Points are expected to be an array '
+ `but got ${typeof (points) === 'object'
? points.constructor.name : typeof (points)}`,
@@ -261,7 +262,7 @@
get: () => data.attributes,
set: (attributes) => {
if (typeof (attributes) !== 'object') {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Attributes are expected to be an object '
+ `but got ${typeof (attributes) === 'object'
? attributes.constructor.name : typeof (attributes)}`,
diff --git a/cvat-core/src/plugins.js b/cvat-core/src/plugins.js
index e1054853..7dc08384 100644
--- a/cvat-core/src/plugins.js
+++ b/cvat-core/src/plugins.js
@@ -14,7 +14,7 @@
class PluginRegistry {
static async apiWrapper(wrappedFunc, ...args) {
// I have to optimize the wrapper
- const pluginList = await window.cvat.plugins.list.implementation();
+ const pluginList = await PluginRegistry.list();
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions
.filter(obj => obj.callback === wrappedFunc)[0];
@@ -52,6 +52,7 @@
return result;
}
+ // Called with cvat context
static async register(plug) {
const functions = [];
@@ -92,7 +93,7 @@
functions.push(decorator);
}
}(plug, {
- cvat: window.cvat,
+ cvat: this,
}));
Object.defineProperty(plug, 'functions', {
diff --git a/cvat-core/src/server-proxy.js b/cvat-core/src/server-proxy.js
index 32dec01d..a7b18b3e 100644
--- a/cvat-core/src/server-proxy.js
+++ b/cvat-core/src/server-proxy.js
@@ -9,6 +9,14 @@
*/
(() => {
+ const FormData = require('form-data');
+ const {
+ ServerError,
+ ScriptingError,
+ } = require('./exceptions');
+
+ const config = require('./config');
+
class ServerProxy {
constructor() {
const Cookie = require('js-cookie');
@@ -25,16 +33,16 @@
}
async function about() {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/server/about`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get "about" information from the server',
code,
);
@@ -44,17 +52,17 @@
}
async function share(directory) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
directory = encodeURIComponent(directory);
let response = null;
try {
response = await Axios.get(`${backendAPI}/server/share?directory=${directory}`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get "share" information from the server',
code,
);
@@ -64,18 +72,18 @@
}
async function exception(exceptionObject) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
try {
await Axios.post(`${backendAPI}/server/exception`, JSON.stringify(exceptionObject), {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
headers: {
'Content-Type': 'application/json',
},
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not send an exception to the server',
code,
);
@@ -111,7 +119,7 @@
if (csrftoken) {
setCSRFHeader(csrftoken);
} else {
- throw new window.cvat.exceptions.ScriptingError(
+ throw new ScriptingError(
'An environment has been detected as a browser'
+ ', but CSRF token has not been found in cookies',
);
@@ -120,15 +128,15 @@
}
}
- const host = window.cvat.config.backendAPI.slice(0, -7);
+ const host = config.backendAPI.slice(0, -7);
let csrf = null;
try {
csrf = await Axios.get(`${host}/auth/csrf`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get CSRF token from a server',
code,
);
@@ -148,7 +156,7 @@
authentificationData,
{
'Content-Type': 'application/x-www-form-urlencoded',
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
// do not redirect to a dashboard,
// otherwise we don't get a session id in a response
maxRedirects: 0,
@@ -161,7 +169,7 @@
} else {
const code = errorData.response
? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not login on a server',
code,
);
@@ -170,7 +178,7 @@
// TODO: Perhaps we should redesign the authorization method on the server.
if (authentificationResponse.data.includes('didn\'t match')) {
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'The pair login/password is invalid',
403,
);
@@ -180,15 +188,15 @@
}
async function logout() {
- const host = window.cvat.config.backendAPI.slice(0, -7);
+ const host = config.backendAPI.slice(0, -7);
try {
await Axios.get(`${host}/auth/logout`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not logout from the server',
code,
);
@@ -196,16 +204,16 @@
}
async function getTasks(filter = '') {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/tasks?${filter}`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get tasks from a server',
code,
);
@@ -216,18 +224,18 @@
}
async function saveTask(id, taskData) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
try {
await Axios.patch(`${backendAPI}/tasks/${id}`, JSON.stringify(taskData), {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
headers: {
'Content-Type': 'application/json',
},
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not save the task on the server',
code,
);
@@ -235,13 +243,13 @@
}
async function deleteTask(id) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
try {
await Axios.delete(`${backendAPI}/tasks/${id}`);
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not delete the task from the server',
code,
);
@@ -249,7 +257,7 @@
}
async function createTask(taskData, files, onUpdate) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
async function wait(id) {
return new Promise((resolve, reject) => {
@@ -266,14 +274,14 @@
} else if (response.data.state === 'Failed') {
// If request has been successful, but task hasn't been created
// Then passed data is wrong and we can pass code 400
- reject(new window.cvat.exceptions.ServerError(
+ reject(new ServerError(
'Could not create the task on the server',
400,
));
} else {
// If server has another status, it is unexpected
// Therefore it is server error and we can pass code 500
- reject(new window.cvat.exceptions.ServerError(
+ reject(new ServerError(
`Unknown task state has been recieved: ${response.data.state}`,
500,
));
@@ -282,7 +290,7 @@
const code = errorData.response
? errorData.response.status : errorData.code;
- reject(new window.cvat.exceptions.ServerError(
+ reject(new ServerError(
'Data uploading error occured',
code,
));
@@ -293,7 +301,7 @@
});
}
- const batchOfFiles = new window.FormData();
+ const batchOfFiles = new FormData();
for (const key in files) {
if (Object.prototype.hasOwnProperty.call(files, key)) {
for (let i = 0; i < files[key].length; i++) {
@@ -307,14 +315,14 @@
onUpdate('The task is being created on the server..');
try {
response = await Axios.post(`${backendAPI}/tasks`, JSON.stringify(taskData), {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
headers: {
'Content-Type': 'application/json',
},
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not put task to the server',
code,
);
@@ -323,12 +331,12 @@
onUpdate('The data is being uploaded to the server..');
try {
await Axios.post(`${backendAPI}/tasks/${response.data.id}/data`, batchOfFiles, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
await deleteTask(response.data.id);
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not put data to the server',
code,
);
@@ -347,16 +355,16 @@
}
async function getJob(jobID) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/jobs/${jobID}`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get jobs from a server',
code,
);
@@ -366,18 +374,18 @@
}
async function saveJob(id, jobData) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
try {
await Axios.patch(`${backendAPI}/jobs/${id}`, JSON.stringify(jobData), {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
headers: {
'Content-Type': 'application/json',
},
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not save the job on the server',
code,
);
@@ -385,16 +393,16 @@
}
async function getUsers() {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/users`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get users from the server',
code,
);
@@ -404,16 +412,16 @@
}
async function getSelf() {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/users/self`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
'Could not get users from the server',
code,
);
@@ -423,17 +431,17 @@
}
async function getData(tid, frame) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/tasks/${tid}/frames/${frame}`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
responseType: 'blob',
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
`Could not get frame ${frame} for the task ${tid} from the server`,
code,
);
@@ -443,16 +451,16 @@
}
async function getMeta(tid) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/tasks/${tid}/frames/meta`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
`Could not get frame meta info for the task ${tid} from the server`,
code,
);
@@ -463,16 +471,16 @@
// Session is 'task' or 'job'
async function getAnnotations(session, id) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let response = null;
try {
response = await Axios.get(`${backendAPI}/${session}s/${id}/annotations`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
`Could not get annotations for the ${session} ${id} from the server`,
code,
);
@@ -483,7 +491,7 @@
// Session is 'task' or 'job'
async function updateAnnotations(session, id, data, action) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let requestFunc = null;
let url = null;
if (action.toUpperCase() === 'PUT') {
@@ -497,14 +505,14 @@
let response = null;
try {
response = await requestFunc(url, JSON.stringify(data), {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
headers: {
'Content-Type': 'application/json',
},
});
} catch (errorData) {
const code = errorData.response ? errorData.response.status : errorData.code;
- throw new window.cvat.exceptions.ServerError(
+ throw new ServerError(
`Could not updated annotations for the ${session} ${id} on the server`,
code,
);
@@ -515,7 +523,7 @@
// Session is 'task' or 'job'
async function uploadAnnotations(session, id, file, format) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
let annotationData = new FormData();
annotationData.append('annotation_file', file);
@@ -525,7 +533,7 @@
try {
const response = await Axios
.post(`${backendAPI}/${session}s/${id}/annotations?upload_format=${format}`, annotationData, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
if (response.status === 202) {
annotationData = new FormData();
@@ -536,7 +544,7 @@
} catch (errorData) {
const code = errorData.response
? errorData.response.status : errorData.code;
- const error = new window.cvat.exceptions.ServerError(
+ const error = new ServerError(
`Could not upload annotations for the ${session} ${id}`,
code,
);
@@ -550,7 +558,7 @@
// Session is 'task' or 'job'
async function dumpAnnotations(id, name, format) {
- const { backendAPI } = window.cvat.config;
+ const { backendAPI } = config;
const filename = name.replace(/\//g, '_');
let url = `${backendAPI}/tasks/${id}/annotations/${filename}?dump_format=${format}`;
@@ -559,7 +567,7 @@
try {
const response = await Axios
.get(`${url}`, {
- proxy: window.cvat.config.proxy,
+ proxy: config.proxy,
});
if (response.status === 202) {
setTimeout(request, 3000);
@@ -570,7 +578,7 @@
} catch (errorData) {
const code = errorData.response
? errorData.response.status : errorData.code;
- const error = new window.cvat.exceptions.ServerError(
+ const error = new ServerError(
`Could not dump annotations for the task ${id} from the server`,
code,
);
diff --git a/cvat-core/src/session.js b/cvat-core/src/session.js
index 5c764eb4..0bb3a12d 100644
--- a/cvat-core/src/session.js
+++ b/cvat-core/src/session.js
@@ -11,20 +11,9 @@
const PluginRegistry = require('./plugins');
const serverProxy = require('./server-proxy');
const { getFrame } = require('./frames');
- const {
- getAnnotations,
- putAnnotations,
- saveAnnotations,
- hasUnsavedChanges,
- mergeAnnotations,
- splitAnnotations,
- groupAnnotations,
- clearAnnotations,
- selectObject,
- annotationsStatistics,
- uploadAnnotations,
- dumpAnnotations,
- } = require('./annotations');
+ const { ArgumentError } = require('./exceptions');
+ const { TaskStatus } = require('./enums');
+ const { Label } = require('./labels');
function buildDublicatedAPI(prototype) {
Object.defineProperties(prototype, {
@@ -509,7 +498,7 @@
}
if (data[property] === undefined) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
`Job field "${property}" was not initialized`,
);
}
@@ -539,7 +528,7 @@
get: () => data.assignee,
set: () => (assignee) => {
if (!Number.isInteger(assignee) || assignee < 0) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Value must be a non negative integer',
);
}
@@ -556,7 +545,7 @@
status: {
get: () => data.status,
set: (status) => {
- const type = window.cvat.enums.TaskStatus;
+ const type = TaskStatus;
let valueInEnum = false;
for (const value in type) {
if (type[value] === status) {
@@ -566,7 +555,7 @@
}
if (!valueInEnum) {
- throw new window.cvat.exceptions.ArgumentError(
+ throw new ArgumentError(
'Value must be a value from the enumeration cvat.enums.TaskStatus',
);
}
@@ -647,128 +636,24 @@
}
}
- // Fill up the prototype by properties. Class syntax doesn't allow do it
- // So, we do it seperately
- buildDublicatedAPI(Job.prototype);
-
- Job.prototype.save.implementation = async function () {
- // TODO: Add ability to change an assignee
- if (this.id) {
- const jobData = {
- status: this.status,
- };
-
- await serverProxy.jobs.saveJob(this.id, jobData);
- return this;
- }
-
- throw new window.cvat.exceptions.ArgumentError(
- 'Can not save job without and id',
- );
- };
-
- Job.prototype.frames.get.implementation = async function (frame) {
- if (!Number.isInteger(frame) || frame < 0) {
- throw new window.cvat.exceptions.ArgumentError(
- `Frame must be a positive integer. Got: "${frame}"`,
- );
- }
-
- if (frame < this.startFrame || frame > this.stopFrame) {
- throw new window.cvat.exceptions.ArgumentError(
- `The frame with number ${frame} is out of the job`,
- );
- }
-
- const frameData = await getFrame(this.task.id, this.task.mode, frame);
- return frameData;
- };
-
- // TODO: Check filter for annotations
- Job.prototype.annotations.get.implementation = async function (frame, filter) {
- if (frame < this.startFrame || frame > this.stopFrame) {
- throw new window.cvat.exceptions.ArgumentError(
- `Frame ${frame} does not exist in the job`,
- );
- }
-
- const annotationsData = await getAnnotations(this, frame, filter);
- return annotationsData;
- };
-
- Job.prototype.annotations.save.implementation = async function (onUpdate) {
- const result = await saveAnnotations(this, onUpdate);
- return result;
- };
-
- Job.prototype.annotations.merge.implementation = async function (objectStates) {
- const result = await mergeAnnotations(this, objectStates);
- return result;
- };
-
- Job.prototype.annotations.split.implementation = async function (objectState, frame) {
- const result = await splitAnnotations(this, objectState, frame);
- return result;
- };
-
- Job.prototype.annotations.group.implementation = async function (objectStates, reset) {
- const result = await groupAnnotations(this, objectStates, reset);
- return result;
- };
-
- Job.prototype.annotations.hasUnsavedChanges.implementation = function () {
- const result = hasUnsavedChanges(this);
- return result;
- };
-
- Job.prototype.annotations.clear.implementation = async function (reload) {
- const result = await clearAnnotations(this, reload);
- return result;
- };
-
- Job.prototype.annotations.select.implementation = function (frame, x, y) {
- const result = selectObject(this, frame, x, y);
- return result;
- };
-
- Job.prototype.annotations.statistics.implementation = function () {
- const result = annotationsStatistics(this);
- return result;
- };
-
- Job.prototype.annotations.put.implementation = function (objectStates) {
- const result = putAnnotations(this, objectStates);
- return result;
- };
-
- Job.prototype.annotations.upload.implementation = async function (file, format) {
- const result = await uploadAnnotations(this, file, format);
- return result;
- };
-
- Job.prototype.annotations.dump.implementation = async function (name, format) {
- const result = await dumpAnnotations(this, name, format);
- return result;
- };
-
/**
* Class representing a task
* @memberof module:API.cvat.classes
* @extends Session
*/
class Task extends Session {
- /**
- * In a fact you need use the constructor only if you want to create a task
- * @param {object} initialData - Object which is used for initalization
- *
It can contain keys:
- *