From 23d354c15996caef3434ab1d68d1afe42459d8e6 Mon Sep 17 00:00:00 2001 From: Paul Beuchat <beuchatp@control.ee.ethz.ch> Date: Wed, 6 May 2020 00:47:57 +0200 Subject: [PATCH] Attempt to get an asynchronous file upload working --- web_interface/html/agent_tab_code.html | 58 ++++++++- web_interface/html/css/fileinput.css | 62 +++++++++ web_interface/html/js/fileinput.js | 150 ++++++++++++++++++++++ web_interface/html/upload_async.php | 41 ++++++ web_interface/install_dfall_server_WIP.sh | 16 ++- 5 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 web_interface/html/css/fileinput.css create mode 100644 web_interface/html/js/fileinput.js create mode 100644 web_interface/html/upload_async.php diff --git a/web_interface/html/agent_tab_code.html b/web_interface/html/agent_tab_code.html index 38bf15e7..b93f163e 100644 --- a/web_interface/html/agent_tab_code.html +++ b/web_interface/html/agent_tab_code.html @@ -8,13 +8,69 @@ Upload your code below. <br> <br> - <input class="fileupload" type="file" id="myToUpload" name="fileToUpload"> + <input class="file" type="file" id="myToUpload" name="fileToUpload"> <br> <input type="submit" value="Upload Code" name="submit"> </form> <br><br><br> + + <input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="1000000" /> + + + <hr class="hr-basic navy"> + + <label for="cppfileinput" class="file-input-label"> + Select your StudentControllerService.<b>cpp</b> file + </label> + <br> + <form id="cppuploadform" action="upload_async.php" method="POST" enctype="multipart/form-data"> + <input type="file" id="cppfileinput" name="cppfile" class="file-input" /> + </form> + + <br> + + <div id="cppfileuploadstatus" class="file-upload-status-div"> +   + </div> + + <br> + + <div id="cppfiledetails" class="file-input-details-div"> +   + </div> + + <br> + + <hr class="hr-basic navy"> + + <label for="yamlfileinput" class="file-input-label"> + Select your StudentControllerService.<b>yaml</b> file + </label> + <br> + <form id="yamluploadform" action="upload_async.php" method="POST" enctype="multipart/form-data"> + <input type="file" id="yamlfileinput" name="yamlfile" class="file-input" /> + </form> + + <br> + + <div id="yamlfileuploadstatus" class="file-upload-status-div"> +   + </div> + + <br> + + <div id="yamlfiledetails" class="file-input-details-div"> +   + </div> + + <br> + + <hr class="hr-basic navy"> + + <br><br><br> + <div id="agentStatusDebuggingDiv"></div> <br><br> diff --git a/web_interface/html/css/fileinput.css b/web_interface/html/css/fileinput.css new file mode 100644 index 00000000..43927246 --- /dev/null +++ b/web_interface/html/css/fileinput.css @@ -0,0 +1,62 @@ +.file-input-label +{ + margin: 0px; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: left; + text-decoration: none; + display: inline-block; + font-size: 1.4em; +} + +.file-input +{ + margin: 0px; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: left; + text-decoration: none; + display: inline-block; + font-size: 1.0em; +} + +.file-upload-status-div +{ + margin: 0px; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: left; + text-decoration: none; + display: inline-block; + font-size: 1.0em; +} + +.file-input-details-div +{ + margin: 0px; + padding-left: 0px; + padding-right: 0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: left; + text-decoration: none; + display: inline-block; + font-size: 1.0em; +} + + + + + + +/* SETTINGS FOR WHEN THE SCREEN IS SMALL */ +@media screen and (max-width: 420px) +{ + +} diff --git a/web_interface/html/js/fileinput.js b/web_interface/html/js/fileinput.js new file mode 100644 index 00000000..82f5db06 --- /dev/null +++ b/web_interface/html/js/fileinput.js @@ -0,0 +1,150 @@ +function initializeFileInputs() +{ + // Get the input fields into variables + var cppfileinput = document.getElementById("cppfileinput"); + var yamlfileinput = document.getElementById("yamlfileinput"); + + // Add an event listener to each + cppfileinput.addEventListener( "change", cppFileInputChangedEvent, false); + yamlfileinput.addEventListener("change", yamlFileInputChangedEvent, false); +} + + + +function cppFileInputChangedEvent(event) +{ + // Get the file list object + // > There should only be one file + var files = event.target.files; + + // Parse the file + parseFileDetails( files[0] , "cppfiledetails" ); + + // Upload the file + uploadFile( files[0] , "text/x-c++src" , "cppfileuploadstatus" , "cppuploadform" ); +} + + + +function yamlFileInputChangedEvent(event) +{ + // Get the file list object + // > There should only be one file + var files = event.target.files; + + // Parse the file + parseFileDetails( files[0] , "yamlfiledetails" ); + + // Upload the file + uploadFile( files[0] , "application/x-yaml" , "yamlfileuploadstatus" , "yamluploadform" ); +} + + + +function parseFileDetails(file,detailsID) +{ + document.getElementById(detailsID).innerHTML = + "<p>File information: <br>" + + "name: <strong>" + file.name + "</strong><br>" + + "type: <strong>" + file.type + "</strong><br>" + + "size: <strong>" + file.size + "</strong> bytes" + + "</p>"; + + // // display an image + // if (file.type.indexOf("image") == 0) { + // var reader = new FileReader(); + // reader.onload = function(e) { + // Output( + // "<p><strong>" + file.name + ":</strong><br />" + + // '<img src="' + e.target.result + '" /></p>' + // ); + // } + // reader.readAsDataURL(file); + // } + + // // display text + // if (file.type.indexOf("text") == 0) { + // var reader = new FileReader(); + // reader.onload = function(e) { + // Output( + // "<p><strong>" + file.name + ":</strong></p><pre>" + + // e.target.result.replace(/</g, "<").replace(/>/g, ">") + + // "</pre>" + // ); + // } + // reader.readAsText(file); + // } + +} + + +function uploadFile(file,expectedFileType,statusID,formID) +{ + // Create a variable for sending an AJAX request + var xmlhttp = new XMLHttpRequest(); + + if ( + xmlhttp.upload + && + file.type == expectedFileType + && + file.size <= document.getElementById("MAX_FILE_SIZE").value + ) + { + + document.getElementById(statusID).innerHTML = "Upload progress 0%"; + + // create progress bar + //var o = $id("progress"); + //var progress = o.appendChild(document.createElement("p")); + //progress.appendChild(document.createTextNode("upload " + file.name)); + + + // progress bar + xmlhttp.upload.addEventListener("progress", function(event) + { + var percent_complete = parseInt( event.loaded / event.total * 100 ); + //progress.style.backgroundPosition = pc + "% 0"; + document.getElementById(statusID).innerHTML = "Upload progress " + percent_complete + "%"; + }, false); + + // file received/failed + xmlhttp.onreadystatechange = function(event) + { + //if (xmlhttp.readyState == 4) { + // progress.className = (xmlhttp.status == 200 ? "success" : "failure"); + //} + if (this.readyState == 4 && this.status == 200) + { + document.getElementById(statusID).innerHTML = "Upload complete." + this.responseText; + } + }; + + // start upload + xmlhttp.open("POST", "upload_async.php", true); + xmlhttp.setRequestHeader("X_FILENAME", file.name); + xmlhttp.send(file); + + } + else + { + // Display an "ERROR" status + document.getElementById(statusID).innerHTML = "<strong>ERROR:</strong>"; + // Check if upload was the cause of the error: + if (!(xmlhttp.upload)) + { + document.getElementById(statusID).innerHTML += "<br>" + "XMLHttpRequest() does not support upload."; + } + // Check if file type is the cause of the error + if (!(file.type == expectedFileType)) + { + document.getElementById(statusID).innerHTML += "<br>" + "file type = " + file.type + ", but it is required to be = " + expectedFileType; + } + // Check if file size is the cause of the error + if (!(file.size <= document.getElementById("MAX_FILE_SIZE").value)) + { + document.getElementById(statusID).innerHTML += "<br>" + "file size = " + file.size + ", is greater than the max allowed of " + document.getElementById("MAX_FILE_SIZE").value + " bytes."; + } + } + +} \ No newline at end of file diff --git a/web_interface/html/upload_async.php b/web_interface/html/upload_async.php new file mode 100644 index 00000000..324e92e6 --- /dev/null +++ b/web_interface/html/upload_async.php @@ -0,0 +1,41 @@ +<?php + + echo "DEBUG1"; + + $fn = (isset($_SERVER['HTTP_X_FILENAME']) ? $_SERVER['HTTP_X_FILENAME'] : false); + + echo "DEBUG2"; + + echo "$fn"; + + if ($fn) + { + echo "DEBUG3"; + + // AJAX call + file_put_contents( + 'uploads/' . $fn, + file_get_contents('php://input') + ); + echo "$fn uploaded"; + exit(); + + } + else + { + echo "DEBUG4"; + // // form submit + // $files = $_FILES['fileselect']; + + // foreach ($files['error'] as $id => $err) { + // if ($err == UPLOAD_ERR_OK) { + // $fn = $files['name'][$id]; + // move_uploaded_file( + // $files['tmp_name'][$id], + // 'uploads/' . $fn + // ); + // echo "<p>File $fn uploaded.</p>"; + // } + // } + } +?> \ No newline at end of file diff --git a/web_interface/install_dfall_server_WIP.sh b/web_interface/install_dfall_server_WIP.sh index 3c3420ad..a0aea03a 100644 --- a/web_interface/install_dfall_server_WIP.sh +++ b/web_interface/install_dfall_server_WIP.sh @@ -4,10 +4,24 @@ sudo apt install apache2 # Install php sudo apt install php +# DISABLE iPv6 + +# CRTICAL TO GET THE gateway4 and nameserver correct +# for example 192.168.0.1 + +# Create a shared folder +cd /home +sudo mkdir www-share +sudo chmod 777 www-share +cd www-share +sudo -u www-data mkdir dfall +sudo -u www-data chmod 775 dfall + # Clone the repository # NOTE: very important here is that the repository # is cloned as the www-data user -sudo -u www-data git clone https://... +cd /home/www-share/dfall +sudo -u www-data git clone https://gitlab.ethz.ch/dfall/dfall-system # Add the necessary line to the "/etc/sudoers" file # that allows the "www-data" user to execute -- GitLab