"use strict"; const express = require("express"), config = require("config"), crypto = require("crypto"), Promise = require("bluebird"); let photoDB; require("../db/photos").then(function(db) { photoDB = db; }); const router = express.Router(); const picturesPath = config.get("picturesPath").replace(/\/$/, "") + "/"; router.put("/:id", function(req, res/*, next*/) { if (!req.user.maintainer) { return res.status(401).send("Unauthorized to modify photos."); } return res.status(400).send("Invalid request"); }); router.delete("/:id?", function(req, res/*, next*/) { if (!req.user.maintainer) { return res.status(401).send("Unauthorized to delete photos."); } return res.status(400).send("Invalid request"); }); function getFacesForPhoto(id) { /* Get the set of faces in this photo */ return photoDB.sequelize.query( "SELECT * FROM faces WHERE photoId=:id AND faceConfidence>0.9", { replacements: { id: id, }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }).then((faces) => { /* For each face in the photo, get the related faces */ return photoDB.sequelize.query( "SELECT relatedFaces.photoId AS photoId,fd.face1Id,fd.face2Id,fd.distance,relatedFaces.faceConfidence " + "FROM (SELECT id,photoId,faceConfidence FROM faces WHERE faces.faceConfidence>=0.9 AND faces.id IN (:ids)) AS faces " + "INNER JOIN faces AS relatedFaces ON relatedFaces.faceConfidence>=0.9 AND relatedFaces.id IN (fd.face1Id,fd.face2Id) " + "INNER JOIN facedistances AS fd ON fd.distance<=0.5 " + " AND (fd.face1Id=faces.id OR fd.face2Id=faces.id) " + "WHERE (faces.id=fd.face1Id OR faces.id=fd.face2Id) " + "ORDER BY fd.distance ASC", { replacements: { ids: faces.map(face => face.id), }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }).then((relatedFaces) => { faces.forEach((face) => { face.relatedFaces = relatedFaces.filter((related) => { return (related.photoId != id && (related.face1Id == face.id || related.face2Id == face.id)); }).map((related) => { return { distance: related.distance, faceConfidence: related.faceConfidence, photoId: related.photoId, faceId: related.face1Id != face.id ? related.face1Id : related.face2Id } }); }); return faces; }); }); } router.get("/:id?", (req, res) => { let id; if (req.params.id) { id = parseInt(req.params.id); if (id != req.params.id) { return res.status(400).send({ message: "Usage /[id]"}); } } let promise; if (id) { promise = photoDB.sequelize.query( "SELECT * FROM faces WHERE id=:id", { replacements: { id: id }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }); } else { promise = photoDB.sequelize.query( "SELECT COUNT(id) AS count FROM faces WHERE faceConfidence>=0.9 AND identityId IS NULL", { type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }).then((results) => { const random = Math.floor(Math.random() * results[0].count); return photoDB.sequelize.query( "SELECT * FROM faces WHERE faceConfidence>=0.9 AND identityId IS NULL ORDER BY id LIMIT :index,1", { replacements: { index: random }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }); }); } return promise.then((faces) => { console.log("Looking up " + faces.map(face => face.id).join(",")); return photoDB.sequelize.query( "SELECT relatedFaces.photoId AS photoId,fd.face1Id,fd.face2Id,fd.distance,relatedFaces.faceConfidence " + "FROM (SELECT id,photoId,faceConfidence FROM faces WHERE faces.id IN (:ids)) AS faces " + "INNER JOIN faces AS relatedFaces ON relatedFaces.identityId IS NULL AND relatedFaces.faceConfidence>=0.9 AND relatedFaces.id IN (fd.face1Id,fd.face2Id) " + "INNER JOIN facedistances AS fd ON fd.distance<=0.5 " + " AND (fd.face1Id=faces.id OR fd.face2Id=faces.id) " + "WHERE (faces.id=fd.face1Id OR faces.id=fd.face2Id) " + "ORDER BY fd.distance ASC",{ replacements: { ids: faces.map(face => face.id) }, type: photoDB.Sequelize.QueryTypes.SELECT, raw: true }).then((relatedFaces) => { faces.forEach((face) => { face.relatedFaces = relatedFaces.filter((related) => { return (related.photoId != faces[0].photoId && (related.face1Id == face.id || related.face2Id == face.id)); }).map((related) => { return { distance: related.distance, faceConfidence: related.faceConfidence, photoId: related.photoId, faceId: related.face1Id != face.id ? related.face1Id : related.face2Id } }); }); return faces; }); }).then((results) => { return res.status(200).json(results); }).catch((error) => { console.error(error); return res.status(500).send("Error processing request."); }); }); module.exports = router;