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">
+			&nbsp
+			</div>
+
+			<br>
+
+			<div id="cppfiledetails" class="file-input-details-div">
+			&nbsp
+			</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">
+			&nbsp
+			</div>
+
+			<br>
+
+			<div id="yamlfiledetails" class="file-input-details-div">
+			&nbsp
+			</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, "&lt;").replace(/>/g, "&gt;") +
+	// 			"</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