Update
This commit is contained in:
parent
f2194b4ebe
commit
ea444b350c
|
@ -101,6 +101,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||||
},
|
},
|
||||||
|
"bcryptjs": {
|
||||||
|
"version": "2.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
||||||
|
"integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
|
||||||
|
},
|
||||||
"binary": {
|
"binary": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"express-fileupload": "^1.1.3-alpha.1",
|
"express-fileupload": "^1.1.3-alpha.1",
|
||||||
"pug": "^2.0.3",
|
"pug": "^2.0.3",
|
||||||
|
|
113
server.js
113
server.js
|
@ -8,12 +8,14 @@ const { spawn } = require('child_process');
|
||||||
const pug = require('pug');
|
const pug = require('pug');
|
||||||
const unzip = require('unzip');
|
const unzip = require('unzip');
|
||||||
const touch = require('touch');
|
const touch = require('touch');
|
||||||
|
const bcrypt = require('bcryptjs');
|
||||||
|
|
||||||
// Consts
|
// Consts
|
||||||
const port = 8000;
|
const port = 8000;
|
||||||
const pythonPath = '/home/pytron/miniconda3/envs/pytron/bin/python'
|
const pythonPath = '/usr/bin/python3'
|
||||||
const aisPath = 'pytron_run/ai_manager/'
|
const aisPath = 'pytron_run/ai_manager/'
|
||||||
const aisPathOld = 'pytron_run/ai_manager_old'
|
const aisPathOld = 'pytron_run/ai_manager_old'
|
||||||
|
const hashPath = "__bcrypt__hash.txt"
|
||||||
|
|
||||||
// Create the directories to store the files
|
// Create the directories to store the files
|
||||||
try { fs.mkdirSync(aisPath); } catch { }
|
try { fs.mkdirSync(aisPath); } catch { }
|
||||||
|
@ -98,13 +100,41 @@ function parse(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed.sortedAis.sort((a, b) => b.score - a.score);
|
parsed.sortedAis.sort((a, b) => b.score - a.score);
|
||||||
parsed.sortedAis[0].rank = 1;
|
if (parsed.sortedAis.length > 0) parsed.sortedAis[0].rank = 1;
|
||||||
parsed.sortedAis[1].rank = 2;
|
if (parsed.sortedAis.length > 1) parsed.sortedAis[1].rank = 2;
|
||||||
parsed.sortedAis[2].rank = 3;
|
if (parsed.sortedAis.length > 2) parsed.sortedAis[2].rank = 3;
|
||||||
|
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveArchiveAndRun(req, res) {
|
||||||
|
|
||||||
|
let path = pathtools.join(aisPath, req.body.name);
|
||||||
|
try { fs.mkdirSync(path); } catch { }
|
||||||
|
|
||||||
|
let zipfile = pathtools.join(path, 'archive.zip');
|
||||||
|
req.files.archive.mv(zipfile, (err) => {
|
||||||
|
if (err != null) {
|
||||||
|
console.log(err);
|
||||||
|
res.render('error', {message: 'Unable to save the ZIP archive to the server'});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs.createReadStream(zipfile)
|
||||||
|
.pipe(unzip.Extract({path}))
|
||||||
|
.on('close', () => {
|
||||||
|
// Touch __init__.py
|
||||||
|
touch(pathtools.join(path, '__init__.py'), () => {
|
||||||
|
// Trigger python_run
|
||||||
|
runPython();
|
||||||
|
res.redirect('/');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.on('error', () => {
|
||||||
|
res.render('error', {message: 'Failed to unzip the archive'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function startServer() {
|
function startServer() {
|
||||||
const app = express();
|
const app = express();
|
||||||
app.set('view engine', 'pug');
|
app.set('view engine', 'pug');
|
||||||
|
@ -134,6 +164,10 @@ function startServer() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!req.body.password) {
|
||||||
|
res.render('error', {message: "You have to enter a password in the form"});
|
||||||
|
}
|
||||||
|
|
||||||
if (req.body.name.indexOf('.') !== -1) {
|
if (req.body.name.indexOf('.') !== -1) {
|
||||||
res.render('error', {message: "The name of your AI can't contain dots"});
|
res.render('error', {message: "The name of your AI can't contain dots"});
|
||||||
}
|
}
|
||||||
|
@ -143,7 +177,37 @@ function startServer() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = pathtools.join(aisPath, req.body.name)
|
let path = pathtools.join(aisPath, req.body.name);
|
||||||
|
let aiExisted;
|
||||||
|
try {
|
||||||
|
fs.statSync(path).isDirectory();
|
||||||
|
aiExisted = true;
|
||||||
|
} catch (e) {
|
||||||
|
aiExisted = false;
|
||||||
|
fs.mkdirSync(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (aiExisted) {
|
||||||
|
fs.readFile(pathtools.join(path, hashPath), 'utf-8', function(err, data) {
|
||||||
|
|
||||||
|
if (err != null) {
|
||||||
|
res.render('error', {message: "Couldn't read hashed password"});
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the AI already existed, verify the password
|
||||||
|
bcrypt.compare(req.body.password, data, function(err, success) {
|
||||||
|
if (err != null) {
|
||||||
|
res.render('error', {message: "Couldn't compare password"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
res.render('error', {message: "Authentication failed"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (fs.statSync(path).isDirectory()) {
|
if (fs.statSync(path).isDirectory()) {
|
||||||
|
@ -168,29 +232,34 @@ function startServer() {
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.mkdirSync(path);
|
// Save archive and run stuff
|
||||||
|
saveArchiveAndRun(req, res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
bcrypt.hash(req.body.password, 10, function(err, hash) {
|
||||||
|
|
||||||
let zipfile = pathtools.join(path, 'archive.zip');
|
|
||||||
req.files.archive.mv(zipfile, (err) => {
|
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
console.log(err);
|
res.render('error', {message: "Couldn't hash password"});
|
||||||
res.render('error', {message: 'Unable to save the ZIP archive to the server'});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fs.createReadStream(zipfile)
|
|
||||||
.pipe(unzip.Extract({path}))
|
// Store hash in your password DB.
|
||||||
.on('close', () => {
|
fs.writeFile(pathtools.join(path, hashPath), hash, (err) => {
|
||||||
// Touch __init__.py
|
|
||||||
touch(pathtools.join(path, '__init__.py'), () => {
|
if (err != null) {
|
||||||
// Trigger python_run
|
res.render('error', {message: "Couldn't save hashed password"});
|
||||||
runPython();
|
return;
|
||||||
res.redirect('/');
|
}
|
||||||
});
|
|
||||||
})
|
// Save archive and run stuff
|
||||||
.on('error', () => {
|
saveArchiveAndRun(req, res);
|
||||||
res.render('error', {message: 'Failed to unzip the archive'});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use('/static', express.static('static'));
|
app.use('/static', express.static('static'));
|
||||||
|
|
|
@ -16,11 +16,18 @@ block content
|
||||||
p.content.has-text-justified
|
p.content.has-text-justified
|
||||||
| You can use an already existing name to
|
| You can use an already existing name to
|
||||||
| replace it with a new version of your AI.
|
| replace it with a new version of your AI.
|
||||||
p.content.has-text-justified
|
|
||||||
| You could also erase other people's AI, but
|
|
||||||
| please, don't do it, because I would be sad
|
|
||||||
| 😢
|
|
||||||
input.input(type="text", name="name", placeholder="Name of your AI")
|
input.input(type="text", name="name", placeholder="Name of your AI")
|
||||||
|
.fielg
|
||||||
|
label.label Password
|
||||||
|
p.content.has-text-justified
|
||||||
|
| This password will allow you to update your
|
||||||
|
| AI. If the name you specify is not used,
|
||||||
|
| this password can be anything you want. If
|
||||||
|
| the name you specify already exists, you need
|
||||||
|
| to enter the password you entered when you
|
||||||
|
| uploaded the AI the first time.
|
||||||
|
input.input(type="password", name="password", placeholder="Password")
|
||||||
|
|
||||||
.field
|
.field
|
||||||
label.label Archive
|
label.label Archive
|
||||||
p.content.has-text-justified
|
p.content.has-text-justified
|
||||||
|
|
Loading…
Reference in New Issue