diff --git a/pytron_run/ai_manager/__init__.py b/pytron_run/ai_manager/__init__.py deleted file mode 100644 index d2dd5e3..0000000 --- a/pytron_run/ai_manager/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from os.path import dirname, basename, isfile -import glob -modules = glob.glob(dirname(__file__)+"/*/ai.py") -__all__ = ['.'.join(f.split('.')[:-1]) for f in modules if isfile(f)] diff --git a/pytron_run/ai_manager/dummy/ai.py b/pytron_run/ai_manager/dummy/ai.py deleted file mode 100644 index 9cdba62..0000000 --- a/pytron_run/ai_manager/dummy/ai.py +++ /dev/null @@ -1,11 +0,0 @@ -"""An AI to try things""" - -from tron.player import Player, Direction - -class Ai(Player): - """" A basic AI""" - def __init__(self): - super(Ai, self).__init__() - - def action(self, map, id): - return Direction.RIGHT diff --git a/server.js b/server.js index 51b4b45..0ea9bb3 100644 --- a/server.js +++ b/server.js @@ -127,6 +127,21 @@ function startServer() { }); app.post('/upload-target', (req, res) => { + + if (!req.body.name) { + res.render('error', {message: "You have to enter a name in the form"}); + return; + } + + if (req.body.name.indexOf('.') !== -1) { + res.render('error', {message: "The name of your AI can't contain dots"}); + } + + if (!req.files.archive) { + res.render('error', {message: "You have to send a ZIP archive"}); + return; + } + let path = pathtools.join(aisPath, req.body.name) try { @@ -158,6 +173,8 @@ function startServer() { 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})) @@ -170,7 +187,7 @@ function startServer() { }); }) .on('error', () => { - res.send('an error occured while extracting the archive') + res.render('error', {message: 'Failed to unzip the archive'}); }); }); }); diff --git a/views/error.pug b/views/error.pug new file mode 100644 index 0000000..0eaf81d --- /dev/null +++ b/views/error.pug @@ -0,0 +1,8 @@ +extends base + +block content + section.section + .container + .message.is-danger + .message-header An error occured + .message-body= message diff --git a/views/upload.pug b/views/upload.pug index 3ba5ba1..9a2a90d 100644 --- a/views/upload.pug +++ b/views/upload.pug @@ -1,14 +1,42 @@ extends base + block content section.section .container .columns.is-centered - .column.is-narrow.is-desktop + .column.is-6.is-desktop form(action="upload-target", method="POST", encType="multipart/form-data") .field label.label Name + p.content.has-text-justified + | This name will be the name you will see on + | the leaderboard. It also corresponds to the + | name of the module your AI will be on the + | server. + p.content.has-text-justified + | You can use an already exisiting name to + | 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") .field + label.label Archive + p.content.has-text-justified + | The archive to upload needs to contain a file + | named ai.py which must contain a + | class named Ai which must contain + | a constructor that takes no arguments (other + | than self or optional arguments). + p.content.has-text-justified + | It may also contain more files, such as + | binary files with neural network weights, or + | such as other python modules. + p.content.has-text-justified + | Please note that this archive must not + | contain a directory, it must only contain the + | files. .file.has-name label.file-label input.file-input(type="file", name="archive") @@ -17,6 +45,6 @@ block content i.fas.fa-upload span.file-label Choose a file… span.file-name - .control - button.button.is-link Submit + .field + input.button.is-link(type="submit", value="Submit")