Updates
This commit is contained in:
parent
bdae28a825
commit
639f493972
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ucaptcha",
|
||||
"version": "0.0.0-pre2",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
15
src/R.js
15
src/R.js
|
@ -1,9 +1,13 @@
|
|||
import path from 'path';
|
||||
import {fileURLToPath} from 'url';
|
||||
const __dirname = fileURLToPath(import.meta.url);
|
||||
|
||||
export const __dirname = fileURLToPath(import.meta.url);
|
||||
export const dirname = meta => fileURLToPath(import.meta.url);
|
||||
export const PROJECT_ROOT = process.cwd();
|
||||
|
||||
export const TAGS = [
|
||||
null,
|
||||
'vehicle',
|
||||
'house',
|
||||
]
|
||||
/**
|
||||
* A path string relative to the project folder.
|
||||
* @typedef {String} IMAGES_FOLDER
|
||||
|
@ -12,8 +16,3 @@ export const IMAGES_FOLDER = path.join(PROJECT_ROOT, 'public', 'images');
|
|||
|
||||
export const MAX_SESSION_TIME = 60 * 30;
|
||||
|
||||
export const TAGS = [
|
||||
null,
|
||||
'vehicle',
|
||||
'house',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Reduces errors till express is fixed
|
||||
import express from 'express';
|
||||
/**
|
||||
* @type {express.Router}
|
||||
* @property {function} get
|
||||
*/
|
||||
export class Router {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor() {
|
||||
return express.Router();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import fs from 'fs';
|
||||
import {IMAGES_FOLDER} from '../../R.js';
|
||||
import {IMAGES_FOLDER} from '../R.js';
|
||||
|
||||
/**
|
||||
* @return {Promise<string>} Image file without extension
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* TODO: this code should maybe be the constructor of a session model
|
||||
*/
|
||||
import pickRandomFile from './pickRandomFile.js';
|
||||
import {randomBytes} from './utils.js';
|
||||
import {client} from '../idb.js';
|
||||
import {MAX_SESSION_TIME, TAGS} from '../R.js';
|
||||
import {Session} from '../models/Session.js';
|
||||
|
||||
/**
|
||||
* @param {string} websiteKey
|
||||
* @param {Object} cookies
|
||||
* @return {Promise<Session>}
|
||||
*/
|
||||
export default async function initializeSession(websiteKey, cookies) {
|
||||
const image = await pickRandomFile();
|
||||
|
||||
const imageTagId = 1; // TODO: Change later to be dynamic based on `image`
|
||||
const sessionId = cookies[websiteKey] ? cookies[websiteKey] : randomBytes(8);
|
||||
|
||||
client.setex(sessionId, MAX_SESSION_TIME, JSON.stringify({
|
||||
sessionId,
|
||||
websiteKey,
|
||||
image,
|
||||
obj: imageTagId,
|
||||
score: 0.5,
|
||||
}));
|
||||
|
||||
|
||||
const session = new Session({
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTagId: TAGS[imageTagId],
|
||||
});
|
||||
|
||||
return session;
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
console.log(import.meta.url, ' is deprecated please use res.json() directly')
|
||||
/**
|
||||
* @param {Response} res
|
||||
* @param {object} json
|
||||
* @param {import('express').Response} res
|
||||
* @param {JSON} json
|
||||
*/
|
||||
export default (res, json) => {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
/**
|
||||
* Session storage in IDB
|
||||
* @typedef {Object} IDBSession
|
||||
* @property {string} sessionId User session ID
|
||||
* @property {string} websiteKey Website ID
|
||||
* @property {string} image Image URL for challenge
|
||||
* @property {number} obj Image object ID
|
||||
* @property {number} score How likely is the user to be a human?
|
||||
*/
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Session storage in IDB
|
||||
* @type {Session} Session
|
||||
* @property {string} [sessionId] User session ID
|
||||
* @property {string} [websiteKey] Website ID
|
||||
* @property {string} [image] Image URL for challenge
|
||||
* @property {number} [obj] Image object ID
|
||||
* @property {number} [score] How likely is the user to be a human?
|
||||
*/
|
||||
export class Session {
|
||||
/**
|
||||
*
|
||||
* @param {*} obj
|
||||
*/
|
||||
constructor(obj={}) {
|
||||
Object.assign(this,obj)
|
||||
}
|
||||
}
|
||||
export default Session
|
|
@ -1,95 +0,0 @@
|
|||
/**
|
||||
* User session
|
||||
*/
|
||||
export default function UserSession() {
|
||||
/** @private @type {string | undefined} */
|
||||
this._sessionId = undefined;
|
||||
|
||||
/** @private @type {string | undefined} */
|
||||
this._websiteKey = undefined;
|
||||
|
||||
/** @private @type {string | undefined} */
|
||||
this._imageTag = undefined;
|
||||
|
||||
|
||||
/**
|
||||
* Get session identifier
|
||||
* @return {string}
|
||||
*/
|
||||
this.getSessionId = function() {
|
||||
return this._sessionId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set session identifier
|
||||
* @param {string} sessionId
|
||||
*/
|
||||
this.setSessionId = function(sessionId) {
|
||||
this._sessionId = sessionId;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get website key
|
||||
* @return {string}
|
||||
*/
|
||||
this.getWebsiteKey = function() {
|
||||
return this._websiteKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set website key
|
||||
* @param {string} websiteKey
|
||||
*/
|
||||
this.setWebsiteKey = function(websiteKey) {
|
||||
this._websiteKey = websiteKey;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get image tag as text
|
||||
* @return {string}
|
||||
*/
|
||||
this.getImageTag = function() {
|
||||
return this._imageTag;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set image tag as text
|
||||
* @param {string} imageObject
|
||||
*/
|
||||
this.setImageTag = function(imageObject) {
|
||||
this._imageTag = imageObject;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serialize the session into a JSON object
|
||||
* @return {Array<any>}
|
||||
*/
|
||||
this.serialize = function() {
|
||||
const sessionId = this.getSessionId();
|
||||
const websiteKey = this.getWebsiteKey();
|
||||
const imageTag = this.getImageTag();
|
||||
|
||||
return [
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize session data from JSON object
|
||||
* @param {Array<any>} payload
|
||||
*/
|
||||
this.deserialize = function([
|
||||
sessionId,
|
||||
websiteKey,
|
||||
imageTag,
|
||||
]) {
|
||||
this.setSessionId(sessionId);
|
||||
this.setWebsiteKey(websiteKey);
|
||||
this.setImageTag(imageTag);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import {Router} from '../../helpers/express-router.js';
|
||||
import {serveImage} from './verify.js';
|
||||
import path from 'path';
|
||||
import {IMAGES_FOLDER} from '../../R.js';
|
||||
const router = new Router();
|
||||
export default router.get('/image', async (req, res) => {
|
||||
const sessionId = req.query.s;
|
||||
if (!sessionId) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const [suspicious, filename] = await serveImage(sessionId);
|
||||
if (suspicious) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
res.sendFile(path.join(IMAGES_FOLDER, filename));
|
||||
});
|
|
@ -1,56 +0,0 @@
|
|||
import express from 'express';
|
||||
import path from 'path';
|
||||
|
||||
import reloadSession from './reloadSession.js';
|
||||
import serveImage from './serveImage.js';
|
||||
import verifyImage from './verifyImage.js';
|
||||
|
||||
import sendJson from '../../helpers/sendJson.js';
|
||||
import {IMAGES_FOLDER, MAX_SESSION_TIME} from '../../R.js';
|
||||
|
||||
const router = new express.Router();
|
||||
|
||||
router.get('/reload', async (req, res)=>{
|
||||
try {
|
||||
const websiteKey = req.query.k;
|
||||
if (!websiteKey) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const session = await reloadSession(websiteKey, req.cookies);
|
||||
res.cookie(websiteKey, session.getSessionId(),
|
||||
{httpOnly: true, maxAge: MAX_SESSION_TIME * 1000});
|
||||
sendJson(res, session.serialize());
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/image', async (req, res)=>{
|
||||
const sessionId = req.query.s;
|
||||
if (!sessionId) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const [suspicious, filename] = await serveImage(sessionId);
|
||||
if (suspicious) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
res.sendFile(path.join(IMAGES_FOLDER, filename));
|
||||
});
|
||||
|
||||
router.post('/verify', async (req, res)=>{
|
||||
const sessionId = req.body.s;
|
||||
const mat = req.body.mat;
|
||||
console.log(req.body);
|
||||
|
||||
const session = await verifyImage(sessionId, mat);
|
||||
sendJson(res, session.serialize());
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -0,0 +1,34 @@
|
|||
import express from 'express';
|
||||
import sendJson from '../../helpers/sendJson.js';
|
||||
import {MAX_SESSION_TIME} from '../../R.js';
|
||||
import reloadSession from '../../helpers/reloadSession.js';
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {express.Request} req
|
||||
* @param {express.Response} res
|
||||
*/
|
||||
const reloadHandler = async (req, res) => {
|
||||
try {
|
||||
const websiteKey = req.query.k;
|
||||
if (!websiteKey) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const session = await reloadSession(websiteKey, req.cookies);
|
||||
const {sessionId} = session;
|
||||
res.cookie(
|
||||
websiteKey, sessionId,
|
||||
{httpOnly: true, maxAge: MAX_SESSION_TIME * 1000},
|
||||
);
|
||||
res.json(session);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
res.end();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default router.get('/reload', reloadHandler);
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* TODO: this code should maybe be the constructor of a session model
|
||||
*/
|
||||
import pickRandomFile from './pickRandomFile.js';
|
||||
import UserSession from '../../models/UserSession.js';
|
||||
import {randomBytes} from '../../helpers/utils.js';
|
||||
import {client} from '../../helpers/idb.js';
|
||||
import {MAX_SESSION_TIME, TAGS} from '../../R.js';
|
||||
|
||||
// /**
|
||||
// * @typedef {import('../../models/IDBSession.js')} IDBSession
|
||||
// */
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} websiteKey
|
||||
* @param {Object} cookies
|
||||
* @return {Promise<UserSession>}
|
||||
*/
|
||||
export default async function initializeSession(websiteKey, cookies) {
|
||||
let randomSessionId;
|
||||
|
||||
if (cookies[websiteKey]) {
|
||||
randomSessionId = cookies[websiteKey];
|
||||
} else {
|
||||
randomSessionId = randomBytes(8);
|
||||
}
|
||||
|
||||
const image = await pickRandomFile();
|
||||
|
||||
const imageTagId = 1; // TODO: Change later to be dynamic based on `image`
|
||||
const session = new UserSession();
|
||||
|
||||
session.setSessionId(randomSessionId);
|
||||
session.setWebsiteKey(websiteKey);
|
||||
session.setImageTag(TAGS[imageTagId]);
|
||||
|
||||
/** @type {import('../../models/IDBSession.js')} */
|
||||
const idbPayload = {
|
||||
sessionId: session.getSessionId(),
|
||||
websiteKey: session.getWebsiteKey(),
|
||||
image,
|
||||
obj: imageTagId,
|
||||
score: 0.5,
|
||||
};
|
||||
|
||||
client.setex(
|
||||
session.getSessionId(), MAX_SESSION_TIME, JSON.stringify(idbPayload));
|
||||
|
||||
return session;
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
import {client} from '../../helpers/idb.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../models/IDBSession.js').IDBSession} IDBSession
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} sessionId
|
||||
* @return {Promise}
|
||||
*/
|
||||
export default function(sessionId) {
|
||||
return new Promise((resolve, reject)=>{
|
||||
client.get(sessionId, (err, result)=>{
|
||||
if (err) return reject(err);
|
||||
if (!result) return reject(new Error('Session expired'));
|
||||
|
||||
/** @type {IDBSession} */
|
||||
const sessionData = JSON.parse(result);
|
||||
|
||||
console.log(sessionData);
|
||||
|
||||
const {
|
||||
// sessionId,
|
||||
image,
|
||||
// score,
|
||||
} = sessionData;
|
||||
|
||||
// if (score < 0.1) {
|
||||
// client.del(sessionId, (err)=>{
|
||||
// if (err) return reject(err);
|
||||
|
||||
// return resolve([
|
||||
// true,
|
||||
// null,
|
||||
// ]);
|
||||
// });
|
||||
// }
|
||||
|
||||
return resolve([
|
||||
null,
|
||||
image + '.jpg',
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
import {promisify} from 'util';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {client} from '../../idb.js';
|
||||
import {PROJECT_ROOT, MAX_SESSION_TIME, TAGS} from '../../R.js';
|
||||
import {argmaxThresh} from '../../helpers/utils.js';
|
||||
import pickRandomFile from '../../helpers/pickRandomFile.js';
|
||||
import Session from '../../models/Session.js';
|
||||
import express from 'express';
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileMat
|
||||
* @property {Array<number>} mat Matrix of floats
|
||||
* @property {number} nums Number of users that have seen this challenge
|
||||
* @property {number} obj The object in the image
|
||||
*/
|
||||
|
||||
/** @type {FileMat} */
|
||||
const defaultMat = {
|
||||
mat: Array(16).fill(0.5),
|
||||
nums: 0,
|
||||
obj: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get file matrix
|
||||
* @param {string} image
|
||||
* @return {FileMat}
|
||||
*/
|
||||
function getMat(image) {
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
|
||||
return mats[image] || defaultMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the image mat
|
||||
* @param {FileMat} imageMat
|
||||
* @param {Array<number>} userMat
|
||||
* @param {string} image
|
||||
*/
|
||||
function updateMat(imageMat, userMat, image) {
|
||||
const updatedMat = [...imageMat.mat];
|
||||
for (let i = 0; i < imageMat.mat.length; i++) {
|
||||
const delta = 0.1;
|
||||
if (userMat[i] === 1) {
|
||||
if (updatedMat[i] + delta > 1) {
|
||||
updatedMat[i] = 1.0;
|
||||
} else {
|
||||
updatedMat[i] += delta;
|
||||
}
|
||||
} else {
|
||||
if (updatedMat[i] < delta) {
|
||||
updatedMat[i] = 0.0;
|
||||
} else {
|
||||
updatedMat[i] -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('OLD MAT: ', imageMat.mat);
|
||||
console.log('NEW MAT: ', updatedMat);
|
||||
|
||||
imageMat.nums += 1;
|
||||
imageMat.mat = updatedMat;
|
||||
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
mats[image] = imageMat;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'),
|
||||
JSON.stringify(mats, null, 2), {encoding: 'utf8'});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sessionId
|
||||
* @param {Array<number>} userMat
|
||||
* @return {Promise}
|
||||
*/
|
||||
async function verify(sessionId, userMat) {
|
||||
const redisGet = promisify(client.get);
|
||||
const session = await redisGet(sessionId)
|
||||
.then((resp) => {
|
||||
if (!resp) {
|
||||
throw new Error('Session expired');
|
||||
}
|
||||
/** @type {Session} */
|
||||
const result = JSON.parse(resp);
|
||||
let {image, score, websiteKey} = result;
|
||||
const imageMat = getMat(image);
|
||||
const trueArgmax = argmaxThresh(imageMat.mat, 0.6).join(',');
|
||||
const userArgmax = argmaxThresh(userMat, 1).join(',');
|
||||
|
||||
updateMat(imageMat, userMat, image);
|
||||
|
||||
console.log('trueArgmax', trueArgmax);
|
||||
console.log('userArgmax', userArgmax);
|
||||
|
||||
const delta = imageMat.nums * 0.05;
|
||||
|
||||
if (userArgmax !== trueArgmax) {
|
||||
// TODO: Decrease the score based on mat dispersion
|
||||
// High variance = small reduction
|
||||
// Low variance = high reduction
|
||||
score -= delta;
|
||||
} else {
|
||||
score += delta;
|
||||
}
|
||||
|
||||
|
||||
return pickRandomFile().then((image)=>{
|
||||
// TODO: Make me dynamic
|
||||
const newImageTag = 1;
|
||||
const update = JSON.stringify(
|
||||
Object.assign(result, {
|
||||
image: image,
|
||||
obj: newImageTag,
|
||||
}));
|
||||
|
||||
return promisify(client.setex)(sessionId, MAX_SESSION_TIME, update).then(()=>new Session({
|
||||
sessionId, websiteKey, imageTag: TAGS[newImageTag],
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {import('../../models/Session.js').Session} IDBSession
|
||||
*/
|
||||
|
||||
/**
|
||||
* serveImage
|
||||
* @param {string} sessionId
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function serveImage(sessionId) {
|
||||
const redisGet = promisify(client.get);
|
||||
return redisGet(sessionId)
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
throw new Error('Session expired');
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.then((result) => {
|
||||
/** @type {Session} */
|
||||
const sessionData = JSON.parse(result);
|
||||
|
||||
console.log(sessionData);
|
||||
|
||||
const {
|
||||
// sessionId,
|
||||
image,
|
||||
// score,
|
||||
} = sessionData;
|
||||
|
||||
// if (score < 0.1) {
|
||||
// client.del(sessionId, (err)=>{
|
||||
// if (err) return reject(err);
|
||||
|
||||
// return resolve([
|
||||
// true,
|
||||
// null,
|
||||
// ]);
|
||||
// });
|
||||
// }
|
||||
|
||||
return [
|
||||
null,
|
||||
image + '.jpg',
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
export default router.post('/verify', async (req, res)=>{
|
||||
const sessionId = req.body.s;
|
||||
const mat = req.body.mat;
|
||||
console.log(req.body);
|
||||
|
||||
const session = await verify(sessionId, mat);
|
||||
res.json(session);
|
||||
});
|
|
@ -1,136 +0,0 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {client} from '../../helpers/idb.js';
|
||||
import {PROJECT_ROOT, MAX_SESSION_TIME, TAGS} from '../../R.js';
|
||||
import {argmaxThresh} from '../../helpers/utils.js';
|
||||
import pickRandomFile from './pickRandomFile.js';
|
||||
import UserSession from '../../models/UserSession.js';
|
||||
|
||||
|
||||
/** @typedef {import('../../models/IDBSession.js')} IDBSession */
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileMat
|
||||
* @property {Array<number>} mat Matrix of floats
|
||||
* @property {number} nums Number of users that have seen this challenge
|
||||
* @property {number} obj The object in the image
|
||||
*/
|
||||
|
||||
/** @type {FileMat} */
|
||||
const defaultMat = {
|
||||
mat: Array(16).fill(0.5),
|
||||
nums: 0,
|
||||
obj: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get file matrix
|
||||
* @param {string} image
|
||||
* @return {FileMat}
|
||||
*/
|
||||
function getMat(image) {
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
|
||||
return mats[image] || defaultMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the image mat
|
||||
* @param {FileMat} imageMat
|
||||
* @param {Array<number>} userMat
|
||||
* @param {string} image
|
||||
*/
|
||||
function updateMat(imageMat, userMat, image) {
|
||||
const updatedMat = Object.assign([], imageMat.mat);
|
||||
for (let i = 0; i < imageMat.mat.length; i++) {
|
||||
const delta = 0.1;
|
||||
if (userMat[i] === 1) {
|
||||
if (updatedMat[i] + delta > 1) {
|
||||
updatedMat[i] = 1.0;
|
||||
} else {
|
||||
updatedMat[i] += delta;
|
||||
}
|
||||
} else {
|
||||
if (updatedMat[i] < delta) {
|
||||
updatedMat[i] = 0.0;
|
||||
} else {
|
||||
updatedMat[i] -= delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('OLD MAT: ', imageMat.mat);
|
||||
console.log('NEW MAT: ', updatedMat);
|
||||
|
||||
imageMat.nums += 1;
|
||||
imageMat.mat = updatedMat;
|
||||
|
||||
const mats = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'), {encoding: 'utf8'}));
|
||||
mats[image] = imageMat;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(PROJECT_ROOT, 'dev', 'mat.json'),
|
||||
JSON.stringify(mats, null, 2), {encoding: 'utf8'});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} sessionId
|
||||
* @param {Array<number>} userMat
|
||||
* @return {Promise}
|
||||
*/
|
||||
export default function(sessionId, userMat) {
|
||||
return new Promise((resolve, reject)=>{
|
||||
client.get(sessionId, (err, resp)=>{
|
||||
if (err) return reject(err);
|
||||
if (!resp) return reject(new Error('Session expired'));
|
||||
|
||||
/** @type {IDBSession} */
|
||||
const result = JSON.parse(resp);
|
||||
|
||||
const imageMat = getMat(result.image);
|
||||
const trueArgmax = argmaxThresh(imageMat.mat, 0.6).join(',');
|
||||
const userArgmax = argmaxThresh(userMat, 1).join(',');
|
||||
|
||||
updateMat(imageMat, userMat, result.image);
|
||||
|
||||
console.log('trueArgmax', trueArgmax);
|
||||
console.log('userArgmax', userArgmax);
|
||||
|
||||
const delta = imageMat.nums * 0.05;
|
||||
|
||||
if (userArgmax !== trueArgmax) {
|
||||
// TODO: Decrease the score based on mat dispersion
|
||||
// High variance = small reduction
|
||||
// Low variance = high reduction
|
||||
result.score -= delta;
|
||||
} else {
|
||||
result.score += delta;
|
||||
}
|
||||
|
||||
pickRandomFile().then((image)=>{
|
||||
// TODO: Make me dynamic
|
||||
const newImageTag = 1;
|
||||
const update = JSON.stringify(
|
||||
Object.assign(result, {
|
||||
image: image,
|
||||
obj: newImageTag,
|
||||
}));
|
||||
|
||||
client.setex(sessionId, MAX_SESSION_TIME,
|
||||
update, (err)=>{
|
||||
if (err) return reject(err);
|
||||
const session = new UserSession();
|
||||
session.setSessionId(sessionId);
|
||||
session.setWebsiteKey(result.websiteKey);
|
||||
session.setImageTag(TAGS[newImageTag]);
|
||||
|
||||
resolve(session);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -20,7 +20,10 @@ if (process.env.NODE_ENV === 'development') {
|
|||
});
|
||||
}
|
||||
|
||||
import apis from './routes/api/index.js';
|
||||
app.use('/api', apis);
|
||||
//import apis from './routes/api/index.js';
|
||||
import apiImage from './routes/api/image.js';
|
||||
import apiVerify from './routes/api/verify.js';
|
||||
import apiReload from './routes/api/reload.js';
|
||||
app.use('/api', [apiImage,apiVerify,apiReload]);
|
||||
|
||||
export {app};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {connect as connectToIdb} from './helpers/idb.js';
|
||||
import {connect as connectToIdb} from './idb.js';
|
||||
import {app} from './server.js';
|
||||
|
||||
import {fetchImagesJob} from './helpers/fetchImagesJob.js';
|
||||
|
|
Loading…
Reference in New Issue