From 3c5c41d1fca66cf1c1241374ac20100d1ff92578 Mon Sep 17 00:00:00 2001
From: Yves Noirjean <yves.noirjean@id.ethz.ch>
Date: Fri, 9 Feb 2018 11:43:38 +0100
Subject: [PATCH] SSDM-6073: added dialog for disk space usage to settings form

---
 .../webapps/eln-lims/html/js/util/FormUtil.js | 112 +++++++++++++++++-
 .../js/views/SettingsForm/SettingsFormView.js |   9 +-
 .../reporting-plugins/eln-lims-api/script.py  |  43 ++++++-
 3 files changed, 160 insertions(+), 4 deletions(-)

diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
index b01023d0775..f02a7b4b26e 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
@@ -1141,4 +1141,114 @@ var FormUtil = new function() {
 				.css("margin-right", "3px"))
 			.append($("<span>").text(infoText));
 	}
-}
\ No newline at end of file
+
+    //
+    // Dropbox folder name dialog
+    //
+
+	this.showDiskSpaceDialog = function() {
+		let _this = this;
+
+		// TODO move to monitoring section
+		// TODO test in all browsers
+		// TODO add animation
+
+		mainController.serverFacade.customELNApi({
+			"method" : "getDiskSpace",
+			"diskMountPoints" : _this.profile.diskMountPoints,
+		}, function(error, result){
+			if (error) {
+				Util.showError("Could not get disk space information.");
+			} else {
+
+				let $dialog = $("<div>");
+				$dialog
+					.append($("<div>")
+						.append($("<legend>").text("Available storage space:")));
+
+				let $formFieldContainer = $("<div>");
+				$dialog.append($formFieldContainer);
+
+				// close button
+				let $closeButton = $("<a>", {
+					class : "btn btn-default",
+					id : "dropboxFolderNameClose"
+				}).text("Close").css("margin-top", "15px");
+				$dialog.append($closeButton);
+
+				// add disk space
+				let rowHeight = "50px";
+				let barHeight = "30px";
+
+				let $table  = $("<table>");
+				$table
+					.append($("<thead>")
+						.append($("<tr>").css("height", rowHeight)
+							.append($("<th>").text("Mount point").css("width", "30%"))
+							.append($("<th>").text("Size").css("width", "10%"))
+							.append($("<th>").text("Used").css("width", "10%"))
+							.append($("<th>").text("Available").css("width", "10%"))
+							.append($("<th>").text("Percentage").css("width", "40%"))
+					));
+				$table.css({
+					width : "90%",
+					"margin-top" : "25px",
+					"margin-bottom" : "25px",
+					"margin-left" : "auto",
+					"margin-right" : "auto",
+				});
+				$tbody = $("<tbody>");
+				$table.append($tbody);
+				$formFieldContainer.append($table);
+
+				let diskSpaceValues = result.data;
+				for (let i=0; i<diskSpaceValues.length; i++) {
+					let filesystem = diskSpaceValues[i]["Mounted_on"]
+					let size = diskSpaceValues[i]["Size"]
+					let used = diskSpaceValues[i]["Used"]
+					let avail = diskSpaceValues[i]["Avail"]
+					let usedPercentage = diskSpaceValues[i]["UsedPercentage"]
+
+					let $diskSpaceSection = $("<div>");
+					let $total = $("<div>").css({
+						height : barHeight,
+						width : "100%",
+						"background-color" : "lightgray",
+						"border-radius" : "7px",
+						"text-align" : "center",
+						"vertical-align" : "middle",
+						"line-height" : barHeight,
+					});
+					$total.text(usedPercentage);
+					let $used = $("<div>").css({
+						height: barHeight,
+						width : usedPercentage,
+						"background-color" : "lightblue",
+						"border-radius" : "7px",
+						"margin-top" : "-" + barHeight
+					});
+					$diskSpaceSection.append($total).append($used);
+
+					$tbody
+						.append($("<tr>").css("height", rowHeight)
+							.append($("<td>").text(filesystem))
+							.append($("<td>").text(size))
+							.append($("<td>").text(used))
+							.append($("<td>").text(avail))
+							.append($("<td>").append($diskSpaceSection))
+					);
+				}
+
+				Util.blockUI($dialog.html(), _this.getDialogCss());
+
+				// events
+				$("#dropboxFolderNameClose").on("click", function(event) {
+					console.log('close');
+					Util.unblockUI();
+				});
+
+			}
+		});
+	}
+
+}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SettingsForm/SettingsFormView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SettingsForm/SettingsFormView.js
index c944a6411d3..07cacc74623 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SettingsForm/SettingsFormView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SettingsForm/SettingsFormView.js
@@ -65,7 +65,12 @@ function SettingsFormView(settingsFormController, settingsFormModel) {
 				$saveBtn.addClass("btn-primary");
 				toolbarModel.push({ component : $saveBtn, tooltip: "Save" });
 			}
-			
+
+			var $diskSpaceButton = FormUtil.getButtonWithIcon("glyphicon-hdd", function () {
+				FormUtil.showDiskSpaceDialog();
+			});
+			toolbarModel.push({ component : $diskSpaceButton, tooltip: "Show available storage space" });
+
 			var $header = views.header;
 			$header.append($formTitle);
 			$header.append(FormUtil.getToolbar(toolbarModel));
@@ -853,4 +858,4 @@ function SettingsFormView(settingsFormController, settingsFormModel) {
 		return $fieldset;
 	}
 
-}
\ No newline at end of file
+}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/eln-lims-api/script.py b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/eln-lims-api/script.py
index affcfb3763b..792bcf50aa0 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/eln-lims-api/script.py
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/eln-lims-api/script.py
@@ -258,6 +258,10 @@ def process(tr, parameters, tableBuilder):
 		result = getFeaturesFromFeatureVector(tr, parameters, tableBuilder);
 		isOk = True;
 
+	if method == "getDiskSpace":
+		result = getDiskSpace(tr, parameters, tableBuilder)
+		isOk = True
+
 	if isOk:
 		tableBuilder.addHeader("STATUS");
 		tableBuilder.addHeader("MESSAGE");
@@ -356,6 +360,43 @@ def getFeaturesFromFeatureVector(tr, parameters, tableBuilder):
 	featuresFromFeatureVector = screeningServiceDSS.loadFeatures(sessionToken, [featureVectorDataset], featuresCodesFromFeatureVector);
 	return getJsonForData(featuresFromFeatureVector);
 
+def getDiskSpace(tr, parameters, tableBuilder):
+	storerootDir = getConfigParameterAsString("storeroot-dir")
+	df = subprocess.check_output(["df", '-h'])
+	diskSpaceValues = extractDiskSpaceValues(df, [find_mountpoint()])
+	return getJsonForData(diskSpaceValues)
+
+def find_mountpoint():
+	storerootDir = getConfigParameterAsString("storeroot-dir")
+	path = os.path.realpath(storerootDir)
+	while not os.path.ismount(path):
+		path = os.path.dirname(path)
+	return path
+
+def extractDiskSpaceValues(df, diskMountPoints):
+	diskSpaceValues = []
+	dfLines = df.splitlines()
+	columnIdxReversed = {} 	#reverse because the first column (which we don't need) can contain spaces
+	header = dfLines[0].replace("Mounted on", "Mounted_on")
+	columnsReversed = header.split()[::-1]
+	for i, column in enumerate(columnsReversed):
+    		if column in ["Mounted_on", "Size", "Used", "Avail"]:
+			columnIdxReversed[column] = i
+		elif column in ["Capacity", "Use%"]: # Mac OS X or GNU/Linux
+			columnIdxReversed["UsedPercentage"] = i
+	for diskMountPoint in diskMountPoints:
+		diskSpaceValues.append(extractValuesForDiskMountpoint(dfLines, columnIdxReversed, diskMountPoint))
+	return diskSpaceValues
+
+def extractValuesForDiskMountpoint(dfLines, columnIdxReversed, diskMountPoint):
+	values = {}
+	for line in dfLines[1:]:
+		valuesSplitReversed = line.split()[::-1]
+		if valuesSplitReversed[columnIdxReversed["Mounted_on"]] == diskMountPoint:
+			for column, i in columnIdxReversed.iteritems():
+				values[column] = valuesSplitReversed[i]
+			return values
+
 def insertSpaceIfMissing(tr, spaceCode):
 	space = tr.getSpace(spaceCode);
 	if space == None:
@@ -1161,4 +1202,4 @@ def getDescendantsTreePermIdsStringSet(samples):
 				if queueSample.getFetchOptions().hasChildren():
 					for child in queueSample.getChildren():
 						descendantsQueue.append(child);
-	return descendantsPermIds;
\ No newline at end of file
+	return descendantsPermIds;
-- 
GitLab