Skip to content

Commit

Permalink
Merge pull request #2 from ezequielramos/main
Browse files Browse the repository at this point in the history
adding events routes
  • Loading branch information
ezequielramos authored Oct 24, 2023
2 parents e59411f + 4dccacc commit 0a1c28e
Show file tree
Hide file tree
Showing 10 changed files with 500 additions and 63 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
coverage.cobertura.xml

# nyc test coverage
.nyc_output
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"eslint": "eslint ./src",
"eslint_fix": "eslint ./src --fix",
"test": "env TS_NODE_TRANSPILE_ONLY=true mocha -r ts-node/register 'tests/**/**.test.ts' --timeout 180000 --exit",
"coverage": "env TS_NODE_TRANSPILE_ONLY=true nyc --reporter=html --reporter=text -- mocha -r ts-node/register 'tests/**/**.test.ts' --timeout 180000 --exit",
"coverage": "env TS_NODE_TRANSPILE_ONLY=true nyc --reporter=html --reporter=text -- mocha -r ts-node/register 'tests/**/**.test.ts' --timeout 180000 --exit && nyc report --reporter=cobertura && mv ./coverage/cobertura-coverage.xml ./coverage.cobertura.xml",
"devops_coverage": "env TS_NODE_TRANSPILE_ONLY=true nyc -- mocha -r ts-node/register 'tests/**/**.test.ts' --reporter ./tests/assets/multiple_reporters.js --timeout 180000 --exit",
"generate_cobertura": "nyc report --reporter=cobertura"
},
Expand Down
167 changes: 167 additions & 0 deletions src/controllers/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { WatchList, watchLists } from "./watch-lists";

function randomCharacters(length: number) {
let result = '';
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
}

interface FeatureConfidence {
name: string | number;
confidence: number;
}

interface EventFace {
episode: number;
matched_object: string,
matched_cluster: null,
matched_card: null,
temperature: null,
created_date: string,
camera: number,
camera_group: number,
case: null,
thumbnail: string,
fullframe: string,
bs_type: "overall",
frame_coords_left: number,
frame_coords_top: number,
frame_coords_right: number,
frame_coords_bottom: number,
matched: boolean,
confidence: number,
cluster_confidence: number;
quality: number,
acknowledged_date: string,
acknowledged_by: number,
acknowledged_reaction: string,
acknowledged: boolean,
video_archive: null,
external_detector: boolean,
meta: object,
id: string,
looks_like_confidence: null,
matched_lists: number[],
detector_params: {
quality: number,
track: {
id: null;
};
},
features: {
headpose_yaw: FeatureConfidence,
headpose_pitch: FeatureConfidence,
beard: FeatureConfidence,
glasses: FeatureConfidence,
age: FeatureConfidence,
gender: FeatureConfidence,
medmask: FeatureConfidence,
emotions: FeatureConfidence;
},
verbose_matched_lists: WatchList[];
// TODO: once camera is implemented, bring it here
verbose_camera: object;
// TODO: once camera group is implemented, bring it here
verbose_camera_group: object;
}

let eventId = 0;
const events: { [eventId: number]: EventFace | undefined; } = {};

function createEvent({ created_date, camera }: { created_date?: string; camera: number; }) {
eventId++;

if (!created_date) {
created_date = new Date().toISOString();
}

const date = new Date(created_date);

const eventFace: EventFace = {
id: String(eventId),
episode: eventId,
created_date: created_date,
acknowledged_date: created_date,
camera: camera,
camera_group: 1,
thumbnail: `http://localhost:5000/uploads/${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}/face_event/${eventId}_face_thumbnail_${randomCharacters(6)}.jpg`,
fullframe: `http://localhost:5000/uploads/${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}/face_event/${eventId}_face_full_frame_${randomCharacters(6)}.jpg`,
matched_object: "",
matched_cluster: null,
matched_card: null,
temperature: null,
case: null,
bs_type: "overall",
frame_coords_left: 11,
frame_coords_top: 21,
frame_coords_right: 62,
frame_coords_bottom: 83,
matched: false,
acknowledged: true,
acknowledged_by: 0,
acknowledged_reaction: "",
cluster_confidence: 0.0,
confidence: 0.0,
external_detector: true,
looks_like_confidence: null,
matched_lists: [watchLists[0].id],
meta: {},
quality: 0.79995,
video_archive: null,
features: {
headpose_yaw: {
name: 22.01571,
confidence: 1
},
headpose_pitch: {
name: -15.91327,
confidence: 1
},
beard: {
name: "beard",
confidence: 0.894003
},
glasses: {
name: "none",
confidence: 0.988431
},
age: {
name: 33.0,
confidence: 1
},
gender: {
name: "male",
confidence: 0.999998
},
medmask: {
name: "none",
confidence: 0.999999
},
emotions: {
name: "neutral",
confidence: 0.97469
}
},
detector_params: {
quality: 0.79995084,
track: {
id: null
}
},
verbose_matched_lists: [watchLists[0]],
// TODO: once camera is implemented, bring it here
verbose_camera: {},
// TODO: once camera group is implemented, bring it here
verbose_camera_group: {}
};
events[eventId] = eventFace;
return eventFace;
}

export { createEvent };
71 changes: 71 additions & 0 deletions src/controllers/watch-lists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
interface WatchList {
id: number,
created_date: string,
modified_date: string,
active: boolean,
name: string,
comment: string,
color: string,
notify: boolean,
acknowledge: boolean,
camera_groups: [],
face_threshold: null,
body_threshold: null,
car_threshold: null,
ignore_events: boolean,
send_events_to_external_vms: boolean,
active_after: null,
active_before: null,
disable_schedule: object,
recount_schedule_on: null,
origin: "ffsecurity";
}

const watchLists: WatchList[] = [
{
"id": -1,
"created_date": "2023-09-02T15:49:23.312899Z",
"modified_date": "2023-09-02T15:49:23.312914Z",
"active": true,
"name": "Unmatched",
"comment": "Default list for unmatched events",
"color": "ffffff",
"notify": false,
"acknowledge": false,
"camera_groups": [],
"face_threshold": null,
"body_threshold": null,
"car_threshold": null,
"ignore_events": false,
"send_events_to_external_vms": false,
"active_after": null,
"active_before": null,
"disable_schedule": {},
"recount_schedule_on": null,
"origin": "ffsecurity"
},
{
"id": 1,
"created_date": "2023-09-02T15:49:23.306322Z",
"modified_date": "2023-09-02T15:49:23.306413Z",
"active": true,
"name": "Default Watch List",
"comment": "",
"color": "123456",
"notify": false,
"acknowledge": false,
"camera_groups": [],
"face_threshold": null,
"body_threshold": null,
"car_threshold": null,
"ignore_events": false,
"send_events_to_external_vms": false,
"active_after": null,
"active_before": null,
"disable_schedule": {},
"recount_schedule_on": null,
"origin": "ffsecurity"
}
];

export { watchLists, WatchList };
9 changes: 2 additions & 7 deletions src/routes/detect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const upload = multer({

function loadDetectRoutes(app: Express) {

app.post('/detect/', validAuthorization, upload.any(), async (req: Request, res: Response) => {
app.post('/detect/', validAuthorization, upload.single('photo'), async (req: Request, res: Response) => {

let photo;
const photo = req.file;

if (!('attributes' in req.body)) {
return res.status(400).json({
Expand All @@ -21,11 +21,6 @@ function loadDetectRoutes(app: Express) {
});
}

if (req.files) {
const files = req.files as Express.Multer.File[];
photo = files.find((file) => file.fieldname == "photo");
}

if (!photo) {
return res.status(400).json({
"traceback": "",
Expand Down
96 changes: 96 additions & 0 deletions src/routes/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Express, Request, Response } from 'express';
import multer from 'multer';
import { validAuthorization } from '../services/route_middlewares';
import { createEvent } from '../controllers/events';

const upload = multer({
storage: multer.memoryStorage()
});

function loadEventsRoutes(app: Express) {

app.post('/events/faces/add/', validAuthorization, upload.single('fullframe'), async (req: Request, res: Response) => {

if (!('token' in req.body)) {
return res.status(400).json({
"traceback": "",
"code": "BAD_PARAM",
"desc": "This field is required.",
"param": "token"
});
}

if (!('camera' in req.body)) {
return res.status(400).json({
"traceback": "",
"code": "BAD_PARAM",
"desc": "This field is required.",
"param": "camera"
});
}

if (!('mf_selector' in req.body)) {
return res.status(400).json({
"traceback": "",
"code": "BAD_PARAM",
"desc": "This field is required.",
"param": "mf_selector"
});
}

const fullframe = req.file;

if (!fullframe) {
return res.status(400).json({
"traceback": "",
"code": "BAD_PARAM",
"desc": "No file was submitted.",
"param": "fullframe"
});
}

// TODO: implement token validation
// return res.status(403).json({
// "traceback": "",
// "code": "PERMISSION_DENIED",
// "desc": "Incorrect events creation API token"
// });

// TODO: implement camera_id validation
// return res.status(400).json({
// "traceback": "",
// "code": "BAD_PARAM",
// "desc": `Invalid pk "${req.body.camera}" - object does not exist.`,
// "param": "camera"
// });

// TODO: implement no face on fullframe
// return res.status(200).json({
// "orientation": 1,
// "objects": {
// }
// });

const eventFace = createEvent({
camera: req.body.camera,
created_date: req.body.timestamp
});

return res.status(200).json({
"events": [
eventFace.id
],
"errors": []
});
});

app.get('/events/faces/', validAuthorization, async (req: Request, res: Response) => {
return res.status(200).json({
"next_page": null,
"count": 0,
"results": []
});
});
}

export { loadEventsRoutes };
Loading

0 comments on commit 0a1c28e

Please sign in to comment.