changeset 1886:49d06c3dc44e

Merge
author Nicholas Jillings <nickjillings@users.noreply.github.com>
date Wed, 09 Mar 2016 14:12:22 +0000
parents 34c168035394 (current diff) c6c40d4ac530 (diff)
children 9b8daa76d737
files .hgignore CITING.txt README.txt analyse.html analysis/analysis.js analysis/index.html core.css core.js docs/DMRN+10/sections/header.tex docs/WAC2016/WAC2016.bib docs/WAC2016/WAC2016.pdf docs/WAC2016/WAC2016.tex docs/WAC2016/sig-alternate.cls interfaces/AB.css interfaces/AB.js interfaces/ape.js interfaces/blank.js interfaces/discrete.js interfaces/horizontal-sliders.js interfaces/mushra.js loudness.js save.php scripts/evaluation_stats.py scripts/generate_report.py scripts/score_parser.php scripts/timeline_view_movement.py test-schema.xsd test_create/style.css test_create/test_core.js test_create/test_create.html
diffstat 4 files changed, 233 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/core.js	Wed Mar 09 14:04:31 2016 +0000
+++ b/core.js	Wed Mar 09 14:12:22 2016 +0000
@@ -166,38 +166,10 @@
 	//var decode = $.parseXML(response);
 	//projectXML = $(decode);
 	
-	// First perform XML schema validation
-	var Module = {
-		xml: response,
-		schema: schemaXSD,
-		arguments:["--noout", "--schema", 'test-schema.xsd','document.xml']
-	};
-	
-	var xmllint = validateXML(Module);
-	console.log(xmllint);
-	if(xmllint != 'document.xml validates\n')
-	{
-		document.getElementsByTagName('body')[0].innerHTML = null;
-		var msg = document.createElement("h3");
-		msg.textContent = "FATAL ERROR";
-		var span = document.createElement("h4");
-		span.textContent = "The XML validator returned the following errors when decoding your XML file";
-		document.getElementsByTagName('body')[0].appendChild(msg);
-		document.getElementsByTagName('body')[0].appendChild(span);
-		xmllint = xmllint.split('\n');
-		for (var i in xmllint)
-		{
-			document.getElementsByTagName('body')[0].appendChild(document.createElement('br'));
-			var span = document.createElement("span");
-			span.textContent = xmllint[i];
-			document.getElementsByTagName('body')[0].appendChild(span);
-		}
-		return;
-	}
-	
-	var parse = new DOMParser();
-	projectXML = parse.parseFromString(response,'text/xml');
-	var errorNode = projectXML.getElementsByTagName('parsererror');
+    // Check if XML is new or a resumption
+    var parse = new DOMParser();
+	var responseDocument = parse.parseFromString(response,'text/xml');
+    var errorNode = responseDocument.getElementsByTagName('parsererror');
 	if (errorNode.length >= 1)
 	{
 		var msg = document.createElement("h3");
@@ -210,10 +182,51 @@
 		document.getElementsByTagName('body')[0].appendChild(errorNode[0]);
 		return;
 	}
-	
-	// Build the specification
-	specification.decode(projectXML);
-	storage.initialise();
+    if (responseDocument.children[0].nodeName == "waet") {
+        // document is a specification
+        
+        // Perform XML schema validation
+        var Module = {
+            xml: response,
+            schema: schemaXSD,
+            arguments:["--noout", "--schema", 'test-schema.xsd','document.xml']
+        };
+            projectXML = responseDocument;
+        var xmllint = validateXML(Module);
+        console.log(xmllint);
+        if(xmllint != 'document.xml validates\n')
+        {
+            document.getElementsByTagName('body')[0].innerHTML = null;
+            var msg = document.createElement("h3");
+            msg.textContent = "FATAL ERROR";
+            var span = document.createElement("h4");
+            span.textContent = "The XML validator returned the following errors when decoding your XML file";
+            document.getElementsByTagName('body')[0].appendChild(msg);
+            document.getElementsByTagName('body')[0].appendChild(span);
+            xmllint = xmllint.split('\n');
+            for (var i in xmllint)
+            {
+                document.getElementsByTagName('body')[0].appendChild(document.createElement('br'));
+                var span = document.createElement("span");
+                span.textContent = xmllint[i];
+                document.getElementsByTagName('body')[0].appendChild(span);
+            }
+            return;
+        }
+        // Build the specification
+	   specification.decode(projectXML);
+        // Generate the session-key
+        storage.initialise();
+        
+    } else if (responseDocument.children[0].nodeName == "waetresult") {
+        // document is a result
+        projectXML = responseDocument.getElementsByTagName('waet')[0];
+        // Build the specification
+	    specification.decode(projectXML);
+        // Use the session-key
+        var sessionKey = responseDocument.children[0].getAttribute(key);
+        storage.initialise(sessionKey);
+    }
 	/// CHECK FOR SAMPLE RATE COMPATIBILITY
 	if (specification.sampleRate != undefined) {
 		if (Number(specification.sampleRate) != audioContext.sampleRate) {
@@ -297,27 +310,6 @@
 	
 	// Create the audio engine object
 	audioEngineContext = new AudioEngine(specification);
-	
-	$(specification.pages).each(function(index,elem){
-		$(elem.audioElements).each(function(i,audioElem){
-			var URL = elem.hostURL + audioElem.url;
-			var buffer = null;
-			for (var i=0; i<audioEngineContext.buffers.length; i++)
-			{
-				if (URL == audioEngineContext.buffers[i].url)
-				{
-					buffer = audioEngineContext.buffers[i];
-					break;
-				}
-			}
-			if (buffer == null)
-			{
-				buffer = new audioEngineContext.bufferObj();
-				buffer.getMedia(URL);
-				audioEngineContext.buffers.push(buffer);
-			}
-		});
-	});
 }
 
 function createProjectSave(destURL) {
@@ -328,7 +320,7 @@
 	var parent = document.createElement("div");
 	parent.appendChild(xmlDoc);
 	var file = [parent.innerHTML];
-	if (destURL == "null" || destURL == undefined) {
+	if (destURL == "local") {
 		var bb = new Blob(file,{type : 'application/xml'});
 		var dnlk = window.URL.createObjectURL(bb);
 		var a = document.createElement("a");
@@ -348,32 +340,24 @@
 			console.log('Error saving file to server! Presenting download locally');
 			createProjectSave(null);
 		};
-		xmlhttp.onreadystatechange  = function() {
-			console.log(xmlhttp.status);
-			if (xmlhttp.status != 200 && xmlhttp.readyState == 4) {
-				createProjectSave(null);
-			} else {
-				var parser = new DOMParser();
-				var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
-				if (xmlDoc == null)
-				{
-					createProjectSave('null');
-				}
-				var response = xmlDoc.childNodes[0];
-				if (response.getAttribute('state') == "OK")
-				{
-					var file = response.getElementsByTagName('file')[0];
-					console.log('Save OK: Filename '+file.textContent+','+file.getAttribute('bytes')+'B');
-					popup.showPopup();
-					popup.popupContent.innerHTML = null;
-					popup.popupContent.textContent = "Thank you!";
-					window.onbeforeunload=null;
-				} else {
-					var message = response.getElementsByTagName('message')[0];
-					errorSessionDump(message.textContent);
-				}
-			}
-		};
+		xmlhttp.onload = function() {
+            console.log(xmlhttp);
+            if (this.status >= 300) {
+                console.log("WARNING - Could not update at this time");
+            } else {
+                var parser = new DOMParser();
+                var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
+                var response = xmlDoc.getElementsByTagName('response')[0];
+                if (response.getAttribute("state") == "OK") {
+                    var file = response.getElementsByTagName("file")[0];
+                    console.log("Save: OK, written "+file.getAttribute("bytes")+"B");
+                } else {
+                    var message = response.getElementsByTagName("message");
+                    console.log("Save: Error! "+message.textContent);
+                    createProjectSave("local");
+                }
+            }
+        };
 		xmlhttp.send(file);
 		popup.showPopup();
 		popup.popupContent.innerHTML = null;
@@ -432,6 +416,10 @@
 	return Math.pow(10,gain/20.0);
 }
 
+function randomString(length) {
+    return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
+}
+
 function interfacePopup() {
 	// Creates an object to manage the popup
 	this.popup = null;
@@ -805,6 +793,22 @@
 		{
 			if (specification.testPages <= i && specification.testPages != 0) {break;}
 			this.stateMap.push(pageHolder[i]);
+            storage.createTestPageStore(pageHolder[i]);
+            for (var element of pageHolder[i].audioElements) {
+                var URL = pageHolder[i].hostURL + element.url;
+                var buffer = null;
+                for (var buffObj of audioEngineContext.buffers) {
+                    if (URL == buffObj.url) {
+                        buffer = buffObj;
+                        break;
+                    }
+                }
+                if (buffer == null) {
+                    buffer = new audioEngineContext.bufferObj();
+                    buffer.getMedia(URL);
+                    audioEngineContext.buffers.push(buffer);
+                }
+            }
 		}
         
 		if (specification.preTest != null) {this.preTestSurvey = specification.preTest;}
@@ -823,6 +827,7 @@
 		if (this.stateIndex == null) {
 			this.initialise();
 		}
+        storage.update();
 		if (this.stateIndex == -1) {
 			this.stateIndex++;
 			console.log('Starting test...');
@@ -855,7 +860,7 @@
 				{
 					this.currentStateMap.audioElements = randomiseOrder(this.currentStateMap.audioElements);
 				}
-                this.currentStore = storage.createTestPageStore(this.currentStateMap);
+                this.currentStore = storage.testPages[this.stateIndex];
 				if (this.currentStateMap.preTest != null)
 				{
 					this.currentStatePosition = 'pre';
@@ -3097,11 +3102,74 @@
 	this.root = this.document.childNodes[0];
 	this.state = 0;
 	
-	this.initialise = function()
+	this.initialise = function(sessionKey)
 	{
-		if (specification.preTest != undefined){this.globalPreTest = new this.surveyNode(this,this.root,specification.preTest);}
+        if (sessionKey == undefined) {
+            // We need to get the sessionKey
+            this.SessionKey.generateKey();
+            var projectDocument = specification.projectXML;
+            projectDocument.setAttribute('file-name',url);
+            this.root.appendChild(projectDocument);
+            this.root.appendChild(returnDateNode());
+            this.root.appendChild(interfaceContext.returnNavigator());
+        } else {
+            this.SessionKey.key = sessionKey;
+        }
+        if (specification.preTest != undefined){this.globalPreTest = new this.surveyNode(this,this.root,specification.preTest);}
 		if (specification.postTest != undefined){this.globalPostTest = new this.surveyNode(this,this.root,specification.postTest);}
 	};
+    
+    this.SessionKey = {
+        key: null,
+        request: new XMLHttpRequest(),
+        parent: this,
+        handleEvent: function() {
+            var parse = new DOMParser();
+            var xml = parse.parseFromString(this.request.response,"text/xml");
+            if (xml.getAllElementsByTagName("state")[0].textContent == "OK") {
+                this.key = xml.getAllElementsByTagName("key")[0].textContent;
+                this.parent.root.setAttribute("key",this.key);
+                this.parent.root.setAttribute("state","empty");
+            } else {
+                this.generateKey();
+            }
+        },
+        generateKey: function() {
+            var temp_key = randomString(32);
+            this.request.open("GET","keygen.php?key="+temp_key,true);
+            this.request.addEventListener("load",this);
+            this.request.send();
+        },
+        update: function() {
+            this.parent.root.setAttribute("state","update");
+            var xmlhttp = new XMLHttpRequest();
+            xmlhttp.open("POST",specification.projectReturn+"?key="+this.key);
+            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
+            xmlhttp.onerror = function(){
+                console.log('Error updating file to server!');
+            };
+            var hold = document.createElement("div");
+            var clone = this.parent.root.cloneNode(true);
+            hold.appendChild(clone);
+            xmlhttp.onload = function() {
+                if (this.status >= 300) {
+                    console.log("WARNING - Could not update at this time");
+                } else {
+                    var parser = new DOMParser();
+                    var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
+                    var response = xmlDoc.getElementsByTagName('response')[0];
+                    if (response.getAttribute("state") == "OK") {
+                        var file = response.getElementsByTagName("file")[0];
+                        console.log("Intermediate save: OK, written "+file.getAttribute("bytes")+"B");
+                    } else {
+                        var message = response.getElementsByTagName("message");
+                        console.log("Intermediate save: Error! "+message.textContent);
+                    }
+                }
+            }
+            xmlhttp.send([hold.innerHTML]);
+        }
+    }
 	
 	this.createTestPageStore = function(specification)
 	{
@@ -3198,15 +3266,14 @@
 		
 		this.parent.root.appendChild(this.XMLDOM);
 	};
+    this.update = function() {
+        this.SessionKey.update();
+    }
 	this.finish = function()
 	{
 		if (this.state == 0)
 		{
-			var projectDocument = specification.projectXML;
-			projectDocument.setAttribute('file-name',url);
-			this.root.appendChild(projectDocument);
-			this.root.appendChild(returnDateNode());
-			this.root.appendChild(interfaceContext.returnNavigator());
+            this.update();
 		}
 		this.state = 1;
 		return this.root;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/keygen.php	Wed Mar 09 14:12:22 2016 +0000
@@ -0,0 +1,40 @@
+<?php
+// This checks the key sent by the JavaScript against the current bunch of saves
+// XML Saves location - assumes it will be saves/
+$saves = glob("saves/*.xml");
+
+$key_requested = $_GET['key'];
+
+$xml_good = "<response><state>OK</state><key>".$key_requested."</key></response>";
+$xml_bad = "<response><state>NO</state><key>".$key_requested."</key></response>";
+$xml_error = "<response><state>ERROR</state><key>".$key_requested."</key></response>";
+if (is_array($saves))
+{
+    foreach($saves as $filename) {
+        $xml_string = file_get_contents($filename, FILE_TEXT);
+        $xml_object = simplexml_load_string($xml_string);
+        if ($xml_object != false) {
+            if (isset($value['key']))
+            {
+                if ($value['key'] == $key_requested) {
+                    echo $xml_bad;
+                    return;
+                }
+            }
+        }
+    }
+    echo $xml_good;
+    // TODO:
+    //  Generate the XML Base file and save it
+    $doc_struct = new SimpleXMLElement('<waetresult/>');
+    $doc_struct->addAttribute("key",$key_requested);
+    //  Add start time
+    //  Add IP Address information
+    //  Save the file
+    $doc_struct->asXML("saves/save-".$key_requested.".xml");
+    return;
+} else {
+    echo $xml_error;
+    return;
+}
+?>
\ No newline at end of file
--- a/pythonServer.py	Wed Mar 09 14:04:31 2016 +0000
+++ b/pythonServer.py	Wed Mar 09 14:12:22 2016 +0000
@@ -7,6 +7,7 @@
 import inspect
 import os
 import urllib2
+import urlparse
 import pickle
 import datetime
 
@@ -58,18 +59,40 @@
 	s.end_headers()
 	s.wfile.write(fileDump.read())
 	fileDump.close()
-	
+
+def keygen(s):
+	reply = ""
+	options = s.path.rsplit('?')
+	options = options[1].rsplit('=')
+	key = options[1]
+	print key
+	if os.path.isfile("saves/save-"+key+".xml"):
+		reply = "<response><state>NO</state><key>"+key+"</key></response>"
+	else:
+		reply = "<response><state>OK</state><key>"+key+"</key></response>"
+	s.send_response(200)
+	s.send_header("Content-type", "application/xml")
+	s.end_headers()
+	s.wfile.write(reply)
+	file = open("saves/save-"+key+".xml",'w')
+	file.write("<waetresult key="+key+"/>")
+	file.close();
+
 def saveFile(self):
 	global curFileName
 	global curSaveIndex
+	options = self.path.rsplit('?')
+        options = options[1].rsplit('=')
+        key = options[1]
+        print key
 	varLen = int(self.headers['Content-Length'])
 	postVars = self.rfile.read(varLen)
-	print curFileName
-	file = open('saves/'+curFileName,'w')
+	print "Saving file key "+key
+	file = open('saves/save-'+key+'.xml','w')
 	file.write(postVars)
 	file.close()
 	try:
-		wbytes = os.path.getsize('saves/'+curFileName)
+		wbytes = os.path.getsize('saves/save-'+key+'.xml')
 	except OSError:
 		self.send_response(200)
 		self.send_header("Content-type", "text/xml")
@@ -94,6 +117,8 @@
 		if(request.client_address[0] == "127.0.0.1"):
 			if (request.path == "/favicon.ico"):
 				send404(request)
+			elif (request.path.split('?',1)[0] == "/keygen.php"):
+				keygen(request);
 			else:
 				if (request.path == '/'):
 					request.path = '/index.html'
@@ -108,7 +133,7 @@
 
 	def do_POST(request):
 		if(request.client_address[0] == "127.0.0.1"):
-			if (request.path == "/save" or request.path == "/save.php"):
+			if (request.path.rsplit('?',1)[0] == "/save" or request.path.rsplit('?',1)[0] == "/save.php"):
 				saveFile(request)
 		else:
 			send404(request)
@@ -119,4 +144,4 @@
     httpd = server_class(server_address, handler_class)
     httpd.serve_forever()
 
-run()
\ No newline at end of file
+run()
--- a/save.php	Wed Mar 09 14:04:31 2016 +0000
+++ b/save.php	Wed Mar 09 14:12:22 2016 +0000
@@ -9,10 +9,9 @@
 	header('Access-Control-Allow-Origin: *');
 	header("Content-type: text/xml");
 	$postText = file_get_contents('php://input');
-	$sha1_hash = sha1($postText);
-	$datetime = date('ymdHis');
-	$xmlfile = "save".$datetime."-".$sha1_hash.".xml";
-	$fileHandle = fopen("saves/".$xmlfile, 'w');
+    $file_key = $_GET['key'];
+    $filename = "saves/save-".$file_key.".xml";
+	$fileHandle = fopen($filename, 'w');
 	if ($fileHandle == FALSE)
 	{
 		// Filehandle failed