From 6de48c3d5701cc08f42f7b1d379f96ca8ec7fedc Mon Sep 17 00:00:00 2001
From: Benjamin Renard <benjamin.renard@akka.eu>
Date: Wed, 7 Feb 2018 14:38:38 +0100
Subject: [PATCH] Implement data upload from a SAMP notification of a local application

---
 js/app/controllers/InteropModule.js |  6 ++++++
 js/app/controllers/SampModule.js    | 44 ++++++++++++++++++++++++++++++++++++++++++--
 js/app/views/UploadPanelUI.js       | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++----------------
 php/classes/VOTableMgr.php          |  3 ++-
 php/uploadFile.php                  | 31 +++++++++++++++++++++++++++++--
 5 files changed, 130 insertions(+), 21 deletions(-)

diff --git a/js/app/controllers/InteropModule.js b/js/app/controllers/InteropModule.js
index b748677..1e3ba72 100644
--- a/js/app/controllers/InteropModule.js
+++ b/js/app/controllers/InteropModule.js
@@ -230,6 +230,12 @@ Ext.define('amdaDesktop.InteropModule', {
 		this.samp.sendFITS(url,name);
 	},
 
+	loadFile: function(url,onLoad,onError) {
+		if (!this.samp)
+			return null;
+		this.samp.loadFile(url,onLoad,onError);
+	},
+
 	loadEpnTap: function(filter) {
 		if(!this.epntap) {
 			this.epntap = Ext.create('amdaDesktop.EpnTapModule');
diff --git a/js/app/controllers/SampModule.js b/js/app/controllers/SampModule.js
index 28fd9d3..5191df4 100644
--- a/js/app/controllers/SampModule.js
+++ b/js/app/controllers/SampModule.js
@@ -278,5 +278,45 @@ Ext.define('amdaDesktop.SampModule', {
 	receiveFile : function(clientName, url, format)
 	{
 		this.fireEvent('uploadfile',this,clientName, url, format);
-	}
-});
\ No newline at end of file
+	},
+
+	loadFile : function(url, onLoad, onError)
+ 	{
+		if (!this.connector || !this.ready) {
+			if (onError)
+				onError("Not connected to a SAMP hub");
+			return;
+		}
+		var proxifiedUrl = this.connector.connection.translateUrl(url);
+		var xobj = null;
+		if ((typeof XMLHttpRequest != "undefined") && (typeof FileReader != "undefined")) {
+			xobj = new XMLHttpRequest();
+		}
+		else {
+			if (onError)
+				onError("Not supported by your browser");
+			return;
+		}
+		xobj.open('GET', proxifiedUrl, true);
+		xobj.responseType = "blob";
+		xobj.onload = function() {
+			var blob = xobj.response;
+			var reader  = new FileReader();
+			reader.addEventListener("load", function () {
+				if (onLoad)
+					onLoad(reader.result);
+			}, false);
+			reader.addEventListener("error", function () {
+				if (onError)
+					onError("Cannot load data received from SAMP");
+			}, false);
+			reader.readAsText(blob,"UTF-8");
+		};
+		xobj.onerror = function () {
+			if (onError)
+				onError("An error occurred during the SAMP request");
+		};
+		xobj.send(null);
+		return true;
+	},
+});
diff --git a/js/app/views/UploadPanelUI.js b/js/app/views/UploadPanelUI.js
index dade01c..5cfa4ed 100644
--- a/js/app/views/UploadPanelUI.js
+++ b/js/app/views/UploadPanelUI.js
@@ -178,30 +178,55 @@ Ext.define('amdaUI.UploadPanelUI', {
 	*/
 	forceUpload : function (url,format,onFinish)
 	{
+		var me = this;
 		var re = /http:\/\/127.0.0.1:/;
 		var isRemoteUrl = !re.test(url);
 
+		switch (format)
+		{
+			case 'votable' :
+				this.getForm().findField('filefrmt').setValue('VOT');
+				break;
+			case 'cdf' :
+				this.getForm().findField('filefrmt').setValue('CDF');
+				break;
+			default :
+				myDesktopApp.errorMsg('Not supported data receive from SAMP');
+				return;
+		}
+
 		if (!isRemoteUrl) {
-			myDesktopApp.warningMsg("Cannot load data from a local application.");
-			if (onFinish)
-				onFinish();
+			myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.interop.id, true, function (module) {
+				var onError = function(error) {
+					if (error)
+						myDesktopApp.errorMsg(error);
+					else
+						myDesktopApp.errorMsg("Cannot load data from this SAMP notification");
+					if (onFinish)
+						onFinish();
+				};
+				var onLoad = function(data) {
+					//Fake value for validation
+					Ext.form.field.File.superclass.setValue.call(me.getForm().findField('localFileName'), 'samp.vot');
+					me.getForm().findField('filesrc').setValue('LOCAL');
+					//Add data related to the samp notification
+					me.getForm().findField('sampFileName').setValue('samp.vot');
+					me.getForm().findField('sampData').setValue(data);
+					var onFinishAll = function() {
+						me.getForm().findField('sampFileName').reset();
+						me.getForm().findField('sampData').reset();
+						if (onFinish)
+							onFinish();
+					}
+					me.postUpload(onFinishAll);
+				};
+				module.loadFile(url,onLoad,onError);
+			});
 			return;
 		}
 		
 		this.getForm().findField('filesrc').setValue('URL');
 		this.getForm().findField('remoteFile').setValue(url);
-		switch (format)
-		{
-			case 'votable' :
-						this.getForm().findField('filefrmt').setValue('VOT');
-						break;
-			case 'cdf' :
-						this.getForm().findField('filefrmt').setValue('CDF');
-						break;
-			default :
-						//ToDo Error - unknown format
-						return;
-		}                
 		this.postUpload(onFinish);
 	},
         
@@ -565,7 +590,17 @@ Ext.define('amdaUI.UploadPanelUI', {
 					localFile, 
 					remoteFile, 			     
 					fileFormat,
-					timeFormat	
+					timeFormat,
+					{
+						xtype: 'hidden',
+						name: 'sampData',
+						value: null
+					},
+					{
+						xtype: 'hidden',
+						name: 'sampFileName',
+						value: null,
+					}
 			],
 			buttons: [
 			{
diff --git a/php/classes/VOTableMgr.php b/php/classes/VOTableMgr.php
index 452679d..5d128a7 100644
--- a/php/classes/VOTableMgr.php
+++ b/php/classes/VOTableMgr.php
@@ -289,7 +289,8 @@ class VOTableMgr {
     if (!$this->xp)
   	   return FALSE;
 
-  	 return (($field->getAttribute("ucd") == "time.epoch") && ($field->getAttribute("xtype") == "dateTime"));
+  	 return (($field->getAttribute("ucd") == "time.epoch") && ($field->getAttribute("xtype") == "dateTime") ||
+		 ($field->getAttribute("ucd") == "TIME") && ($field->getAttribute("unit") == "iso-8601"));
   }
 
   public function getTimeFieldIndex()
diff --git a/php/uploadFile.php b/php/uploadFile.php
index 22c7f58..219632a 100644
--- a/php/uploadFile.php
+++ b/php/uploadFile.php
@@ -117,6 +117,8 @@
 	$nonStd = $_POST['nonstd'] ?  $_POST['nonstd'] : null;
 	$timeLength = $_POST['timelength'] ?  $_POST['timelength'] : null;
 	$doy = isset($_POST['doy']) ?  $_POST['doy'] : null;
+	$sampData = isset($_POST['sampData']) ? $_POST['sampData'] : null;
+	$sampFileName = isset($_POST['sampFileName']) ? $_POST['sampFileName'] : null;
 
 	$allFormats = array('fileFormat' => $fileFrmt, 'timeFormat' => $timeFrmt, 'doy' => $doy,
 								'timeSampling' => $timeSmplg, 'nonStandard' => $nonStd, 'timeLength' => $timeLength);
@@ -127,8 +129,33 @@
 	// to check ws sizw
 	$wsMgr = new UserMgr();
 	$wsMgr->setSpecialSettings();
-  
-	if ($fromURL) 
+
+ 	if (isset($sampData) && !empty($sampData)) {
+		$fileMgr = new FilesMgr();
+		$fileName = date("Y-m-d\TH:i:s").'_samp.vot';
+		$tmpFilePath = USERTEMPDIR.$fileName;
+		file_put_contents($tmpFilePath, $sampData);
+		$fileSize = filesize($tmpFilePath);
+
+		if ($wsMgr->getWsSize() + $fileSize > DISK_QUOTA)
+                {
+			$response = array( 'success' => false, 'error' => 'Please clean up you workspace. You are about to exceed available disk space');
+			unlink($tmpFilePath);
+			die(json_encode($response));
+		}
+
+		if ($fileSize > maxSize)
+		{
+			$maxMB = maxSize/1000000;
+			$response = array( 'success' => false, 'error' => 'The uploaded file exceeds '.$maxMB.'MB');
+			unlink($tmpFilePath);
+			die(json_encode($response));
+		}
+
+		$dataFilePath = USERDATADIR.$fileName;
+		rename($tmpFilePath,$dataFilePath);
+	}
+	else if ($fromURL) 
 	{
 	// url files check
 		if ($_POST['remoteFile']) 
--
libgit2 0.21.2