Switched back to port 80 (http) instead of https in the container

Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
James Ketr 2023-01-23 07:54:15 -08:00
parent 83e006b43c
commit 3e9438bb27
10 changed files with 177 additions and 88 deletions

View File

@ -17,7 +17,7 @@ services:
# - db # - db
restart: always restart: always
ports: ports:
- ${PORT}:443 # nginx -> server/app.js express app - ${PORT}:80 # nginx -> server/app.js express app
# - 127.0.0.1:${SHELL_PORT}:4200 # shellinabox # - 127.0.0.1:${SHELL_PORT}:4200 # shellinabox
volumes: volumes:
- /etc/letsencrypt:/etc/letsencrypt:ro # Use host web keys - /etc/letsencrypt:/etc/letsencrypt:ro # Use host web keys

View File

@ -30,6 +30,9 @@ if [[ -z "${DEVELOPMENT}" ]]; then
{ while true; do npm start ; sleep 3 ; done ; } { while true; do npm start ; sleep 3 ; done ; }
else else
echo "Running in DEVELOPMENT mode." echo "Running in DEVELOPMENT mode."
if [[ ! -d /website/frontend ]]; then
fail "/website/frontend not found. Is the volume mounted? Did you run via './launch.sh'?"
fi
if [[ ! -d /website/frontend/bower_components ]]; then if [[ ! -d /website/frontend/bower_components ]]; then
echo "...installing bower_components for frontend" echo "...installing bower_components for frontend"
cd /website/frontend cd /website/frontend

View File

@ -226,5 +226,7 @@ with conn:
for identity in reduced: for identity in reduced:
print(f'Writing identity {identity["id"]} to DB') print(f'Writing identity {identity["id"]} to DB')
id = create_identity(conn, identity) id = create_identity(conn, identity)
first = True
for face in identity['faces']: for face in identity['faces']:
update_face_identity(conn, face['id'], id) update_face_identity(conn, face['id'], id, first)
first = False

View File

@ -142,7 +142,7 @@ def create_identity(conn, identity):
conn.commit() conn.commit()
return cur.lastrowid return cur.lastrowid
def update_face_identity(conn, faceId, identityId = None): def update_face_identity(conn, faceId, identityId = None, first = False):
""" """
Update the identity associated with this face Update the identity associated with this face
:param conn: :param conn:
@ -152,8 +152,13 @@ def update_face_identity(conn, faceId, identityId = None):
""" """
sql = ''' sql = '''
UPDATE faces SET identityId=? WHERE id=? UPDATE faces SET identityId=? WHERE id=?
''' '''
cur = conn.cursor() cur = conn.cursor()
cur.execute(sql, (identityId, faceId)) cur.execute(sql, (identityId, faceId))
if first:
sql = '''
UPDATE identities SET faceId=? WHERE id=?
'''
cur.execute(sql, (faceId, identityId))
conn.commit() conn.commit()
return None return None

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
pid=$(ps aux | pid=$(ps aux |
grep -E '[0-9] (/usr/bin/)?node .*client.*react-scripts/scripts/start.js' | grep -E '[0-9] (/usr/bin/)?node .*client.*craco.*scripts/start.js' |
while read user pid rest; do while read user pid rest; do
echo $pid; echo $pid;
done) done)

View File

@ -111,6 +111,14 @@ function init() {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: false allowNull: false
}, },
faceId: {
type: Sequelize.INTEGER,
sallowNull: true,
references: {
model: Photo,
key: 'id',
}
},
descriptors: Sequelize.BLOB /* average of all faces mapped to this */ descriptors: Sequelize.BLOB /* average of all faces mapped to this */
}, { }, {
timestamps: false timestamps: false
@ -180,6 +188,10 @@ function init() {
key: 'id', key: 'id',
} }
}, },
distance: {
type: Sequelize.FLOAT,
defaultValue: -1
},
classifiedBy: { classifiedBy: {
type: Sequelize.DataTypes.ENUM( type: Sequelize.DataTypes.ENUM(
'machine', 'machine',

View File

@ -1,7 +1,7 @@
# DEVELOPMENT -- use npm development server on port 3000 (entrypoint.sh) # DEVELOPMENT -- use npm development server on port 3000 (entrypoint.sh)
location /identities/api/v1/ { location /identities/api/v1/ {
rewrite ^/identities/api/v1/(.*)$ /api/v1/$1 break; rewrite ^/identities/api/v1/(.*)$ /api/v1/$1 break;
proxy_pass https://localhost/; proxy_pass http://localhost/;
proxy_redirect off; proxy_redirect off;
proxy_set_header Host $host; proxy_set_header Host $host;
} }
@ -17,5 +17,5 @@ location /identities {
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade"; proxy_set_header Connection "Upgrade";
proxy_pass https://localhost:3000; proxy_pass http://localhost:3000;
} }

View File

@ -1,17 +1,17 @@
server { server {
listen 80 default_server; listen 80 default_server;
listen [::]:80 default_server; listen [::]:80 default_server;
return 301 https://$host$request_uri; # return 301 https://$host$request_uri;
} #}
server { #server {
listen 443 ssl; # listen 443 ssl;
client_max_body_size 5g; client_max_body_size 5g;
ssl on; # ssl on;
ssl_certificate /etc/letsencrypt/live/ketrenos.com/fullchain.pem; # ssl_certificate /etc/letsencrypt/live/ketrenos.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ketrenos.com/privkey.pem; # ssl_certificate_key /etc/letsencrypt/live/ketrenos.com/privkey.pem;
root /website; root /website;
index index.html; index index.html;

View File

@ -1,10 +1,13 @@
# PRODUCTION -- pre-built source # PRODUCTION -- pre-built source
location /identities/api/v1/ { location /identities/api/v1/ {
rewrite ^/identities/api/v1/(.*)$ https://${host}/api/v1/$1 permanent; rewrite ^/identities/api/v1/(.*)$ /api/v1/$1 break;
proxy_pass http://localhost/;
proxy_redirect off;
proxy_set_header Host $host;
} }
location /identities { location /identities {
try_files $uri $uri/ =404; try_files $uri $uri/ =404;
alias /website/client/build; alias /website/client/build;
index index.html; index index.html;
} }

View File

@ -11,7 +11,7 @@ require("../db/photos").then(function(db) {
const router = express.Router(); const router = express.Router();
const addOrUpdateIdentity = async(id, { const upsertIdentity = async(id, {
displayName, displayName,
firstName, firstName,
lastName, lastName,
@ -106,7 +106,7 @@ router.post('/', async (req, res) => {
return res.status(401).send({ message: "Unauthorized to modify photos." }); return res.status(401).send({ message: "Unauthorized to modify photos." });
} }
const identity = await addOrUpdateIdentity(-1, req.body, res); const identity = await upsertIdentity(-1, req.body, res);
if (!identity) { if (!identity) {
return; return;
} }
@ -126,7 +126,7 @@ router.put('/:id', async (req, res) => {
return res.status(400).send({ message: `Invalid identity id ${id}` }); return res.status(400).send({ message: `Invalid identity id ${id}` });
} }
const identity = await addOrUpdateIdentity(id, req.body, res); const identity = await upsertIdentity(id, req.body, res);
if (!identity) { if (!identity) {
return; return;
} }
@ -331,6 +331,106 @@ const getUnknownIdentity = async (faceCount) => {
return unknownIdentity; return unknownIdentity;
} }
/* Compute the identity's centroid descriptor from all faces
* and determine closest face to that centroid. If either of
* those values have changed, update the identity.
*
* Also updates the 'distance' on each face to the identity
* centroid.
*/
const updateIdentityFaces = async (identity) => {
if (!identity.identityId) {
identity.identityId = identity.id;
}
const faces = await photoDB.sequelize.query(
"SELECT " +
"faces.*,faceDescriptors.* " +
"WHERE " +
"faces.identityId=:identityId " +
"AND faceDescriptors.id=faces.descriptorsId", {
replacements: identity,
type: photoDB.Sequelize.QueryTypes.SELECT,
raw: true
});
let average = undefined,
closestId = -1,
closestDistance = -1,
count = 0;
faces.forEach((face) => {
if (!descriptors[index]) {
return;
}
if (!face.descriptors) {
return;
}
face.distance = euclideanDistance(
face.descriptors,
identity.descriptors
);
face.descriptors = bufferToFloat32Array(face.descriptors).map(x => x * x);
if (closestId === -1) {
closestId = face.id;
closestDistance = face.distance;
average = descriptors;
count = 1;
return;
}
descriptors.forEach((x, i) => {
average[i] += x;
});
count++;
if (face.distance < closestDistance) {
closestDistance = face.distance;
closestId = face.id;
}
});
let same = true;
if (average) {
average = average.map(x => x / count);
same = bufferToFloat32Array(identity.descriptors)
.find((x, i) => average[i] === x) === undefined;
await Promise(faces, async (face) => {
const distance = euclideanDistanceArray(face.descriptors, average);
if (distance !== face.distance) {
await photoDB.sequelize.query(
'UPDATE faces SET distance=:distance WHERE id=:faceId', {
replacements: face
}
);
}
});
}
let sql = '';
if (closestId !== undefined && closestId !== identity.faceId) {
sql = `${sql} faceId=:faceId`;
}
if (!same) {
if (sql !== '') {
sql = `${sql}, `;
}
sql = `${sql} descriptors=:descriptors`;
}
if (sql !== '') {
await photoDB.sequelize.select(
`UPDATE identities SET ${sql} ` +
`WHERE id=:identityId`, {
replacements: {
faceId: closestId,
descriptors: average,
identityId: identity.id
}
}
);
}
};
router.get("/:id?", async (req, res) => { router.get("/:id?", async (req, res) => {
console.log(`GET ${req.url}`); console.log(`GET ${req.url}`);
@ -352,100 +452,64 @@ router.get("/:id?", async (req, res) => {
const filter = id ? "WHERE identities.id=:id " : ""; const filter = id ? "WHERE identities.id=:id " : "";
const identities = await photoDB.sequelize.query("SELECT " + const identities = await photoDB.sequelize.query(
"identities.*," + "SELECT " +
"GROUP_CONCAT(faces.id) AS relatedFaceIds," + "identities.id AS identityId," +
"GROUP_CONCAT(faces.descriptorId) AS relatedFaceDescriptorIds," + "identities.firstName," +
"GROUP_CONCAT(faces.photoId) AS relatedFacePhotoIds " + "identities.lastName," +
"identities.middleName," +
"identities.displayName," +
"identities.faceId " +
"FROM identities " + "FROM identities " +
"LEFT JOIN faces ON identities.id=faces.identityId " + filter, {
filter +
"GROUP BY identities.id", {
replacements: { id }, replacements: { id },
type: photoDB.Sequelize.QueryTypes.SELECT, type: photoDB.Sequelize.QueryTypes.SELECT,
raw: true raw: true
}); });
await Promise.map(identities, async (identity) => { await Promise.map(identities, async (identity) => {
[ 'firstName', 'middleName', 'lastName' ].forEach(key => { let where;
if (!identity[key]) { /* If id was set, only return a single face */
identity[key] = ''; if (id !== undefined) {
if (identity.faceId !== -1) {
where = 'faceId=:faceId';
} else {
where = 'identityId=:identityId LIMIT 1';
} }
});
identity.identityId = identity.id;
if (!identity.relatedFaceIds) {
identity.relatedFaces = [];
} else { } else {
const relatedFaces = identity.relatedFaceIds.split(","), where = 'identityId=:identityId'
relatedFacePhotos = identity.relatedFacePhotoIds.split(","); }
identity.relatedFaces = await photoDB.sequelize.query(
'SELECT id as faceId,photoId,distance FROM faces ' +
`WHERE ${where} ORDER BY distance ASC`, {
replacements: identity,
type: photoDB.Sequelize.QueryTypes.SELECT,
raw: true
}
);
let descriptors = await photoDB.sequelize.query(
`SELECT descriptors FROM facedescriptors WHERE id in (:ids)`, {
replacements: {
ids: identity.relatedFaceDescriptorIds.split(',')
},
type: photoDB.Sequelize.QueryTypes.SELECT,
raw: true
}
);
descriptors = descriptors.map(entry => entry.descriptors);
identity.relatedFaces = relatedFaces.map((faceId, index) => { if (identity.relatedFaces.length !== 0
let distance = 0; && (!identity.faceId || identity.faceId === -1)) {
if (descriptors[index] && identity.descriptors) { await updateIdentityFaces(identity);
distance = euclideanDistance(
descriptors[index],
identity.descriptors
);
} else {
distance = -1;
}
return {
identityId: identity.id,
faceId,
photoId: relatedFacePhotos[index],
distance
};
});
} }
/* If there were no faces, then add a 'Unknown' face */
if (identity.relatedFaces.length === 0) { if (identity.relatedFaces.length === 0) {
identity.relatedFaces.push({ identity.relatedFaces.push({
faceId: -1, faceId: -1,
photoId: -1, photoId: -1,
identityId: identity.id, identityId: identity.identityId,
distance: 0, distance: 0,
faceConfidence: 0 faceConfidence: 0
}); });
} }
identity
.relatedFaces
.sort((A, B) => {
return A.distance - B.distance;
});
/* If no filter was specified, only return the best face for
* the identity */
if (!filter) {
identity.relatedFaces = [ identity.relatedFaces[0] ];
}
delete identity.id;
delete identity.descriptors;
delete identity.relatedFaceIds;
delete identity.relatedFacePhotoIds;
delete identity.relatedFaceDescriptorIds;
delete identity.relatedIdentityDescriptors;
}); });
/* If no ID was provided (so no 'filter') then this call is returning /* If no ID was provided then this call is returning
* a list of all identities -- we create a fake identity for all * a list of all identities -- we create a fake identity for all
* unlabeled faces */ * unlabeled faces */
if (!filter) { if (!id) {
const unknownIdentity = await getUnknownIdentity(1) const unknownIdentity = await getUnknownIdentity(1)
identities.push(unknownIdentity); identities.push(unknownIdentity);
} }