diff --git a/connectcore-demo-example/demoserver.py b/connectcore-demo-example/demoserver.py index 699ae98..42c4e30 100755 --- a/connectcore-demo-example/demoserver.py +++ b/connectcore-demo-example/demoserver.py @@ -15,6 +15,7 @@ # PERFORMANCE OF THIS SOFTWARE. import argparse +import cgi import http.server import json import logging @@ -139,6 +140,153 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler): # Send the JSON value. self.wfile.write(json.dumps(status).encode(encoding="utf_8")) + elif re.search("/ajax/fs_list_directory", self.path) is not None: + # Set the response headers. + self._set_headers(200) + + # Get the JSON data. + data = self.rfile.read(int(self.headers["Content-Length"])) + path = json.loads(data.decode("utf-8")).get("directory", None) + + log.debug("List directory: %s", path) + + if not path or not os.path.exists(path): + error = "Invalid path" if not path else "No such file or directory" + log.error("Error listing directory '%s': %s", path, error) + self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8")) + return + + work_path = os.path.realpath(path) + content = [] + + dir_list = { + "current_dir": path, + "files": content, + } + + # Add item '..' + if os.path.dirname(work_path) != work_path: + content.append({ + "type": "dir", + "name": os.path.join(path, ".."), + "last_modified": os.stat(os.path.join(path, "..")), + }) + + dir_contents = os.listdir(work_path) + dir_contents.sort() + for item in dir_contents: + item_path = os.path.join(path, item) + item_work_path = os.path.realpath(item_path) + st = os.stat(item_work_path) + item = { + "type": "dir" if os.path.isdir(item_work_path) else "file", + "name": os.path.join(path, item), + "last_modified": st[stat.ST_MTIME], + } + if os.path.isfile(item_work_path): + item["size"] = st[stat.ST_SIZE] + content.append(item) + + # Send the JSON value. + self.wfile.write(json.dumps(dir_list).encode(encoding="utf_8")) + elif re.search("/ajax/fs_remove_file", self.path) is not None: + # Set the response headers. + self._set_headers(200) + # Get the JSON data. + data = self.rfile.read(int(self.headers["Content-Length"])) + path = json.loads(data.decode("utf-8")).get("path", None) + + log.debug("Remove file: %s", path) + + if not path or not os.path.exists(path): + error = "Invalid path" if not path else "No such file or directory" + log.error("Error removing file '%s': %s", path, error) + self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8")) + return + + try: + os.remove(path) + self.wfile.write("{}".encode(encoding="utf_8")) + except OSError as e: + self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8")) + log.error("Error removing file '%s': %s", e.filename, e.strerror) + return + + elif re.search("/ajax/fs_create_dir", self.path) is not None: + # Set the response headers. + self._set_headers(200) + # Get the JSON data. + data = self.rfile.read(int(self.headers["Content-Length"])) + path = json.loads(data.decode("utf-8")).get("directory", None) + + log.debug("Create directory: %s", path) + + if not path: + log.error("Error creating directory '%s': Invalid directory", path) + self.wfile.write(json.dumps({"error": "Invalid directory"}).encode(encoding="utf_8")) + return + + try: + os.makedirs(path, exist_ok=True) + except OSError as e: + self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8")) + log.error("Error creating directory '%s': %s", path, e.strerror) + return + + self.wfile.write("{}".encode(encoding="utf_8")) + elif re.search("/ajax/fs_download_file", self.path) is not None: + # Get the JSON data. + data = self.rfile.read(int(self.headers["Content-Length"])) + path = json.loads(data.decode("utf-8")).get("path", None) + + log.debug("Download file: %s", path) + + if not path: + self._set_headers(200) + log.error("Error downloading file '%s': Invalid path", path) + self.wfile.write(json.dumps({"error": "Invalid path"}).encode(encoding="utf_8")) + return + + work_path = os.path.realpath(path) + try: + with open(work_path, "rb") as f: + contents = f.read() + except OSError as e: + self._set_headers(200) + log.error("Error downloading file '%s': %s", path, e.strerror) + self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8")) + return + + self.send_response(200) + self.send_header("Content-type", "application/octet-stream") + self.end_headers() + self.wfile.write(contents) + elif re.search("/ajax/fs_upload_file", self.path) is not None: + # Set the response headers. + self._set_headers(200) + # Get the data. + ctype, pdict = cgi.parse_header(self.headers['content-type']) + if "boundary" in pdict: + pdict["boundary"] = pdict["boundary"].encode() + data = cgi.parse_multipart(self.rfile, pdict) + path = data.get("path", [None])[0] + f_data = data.get("file", [bytes()])[0] + + log.debug("Upload file: %s", path) + if not path or os.path.exists(path): + error = "Invalid path" if not path else "File already exists" + log.error("Error uploading file '%s': %s", path, error) + self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8")) + return + + work_path = os.path.realpath(path) + try: + with open(work_path, "xb") as f: + f.write(f_data) + self.wfile.write("{}".encode(encoding="utf_8")) + except OSError as e: + log.error("Error uploading file '%s': %s", path, e.strerror) + self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8")) else: # Forbidden. self._set_headers(403) diff --git a/connectcore-demo-example/index.html b/connectcore-demo-example/index.html index dba65c5..96fe841 100644 --- a/connectcore-demo-example/index.html +++ b/connectcore-demo-example/index.html @@ -425,7 +425,7 @@ Digi Demo - Dashboard
Current dir:
-
+
diff --git a/connectcore-demo-example/static/js/common.js b/connectcore-demo-example/static/js/common.js index b394a4f..c869783 100644 --- a/connectcore-demo-example/static/js/common.js +++ b/connectcore-demo-example/static/js/common.js @@ -136,6 +136,8 @@ const ERROR_UNKNOWN_ERROR = "Unknown error"; const PATH_IMAGES = "../static/images/"; +const PORT = "9090"; + String.prototype.format = function() { var formatted = this; for (var arg in arguments) @@ -143,6 +145,20 @@ String.prototype.format = function() { return formatted; }; +// Returns the server address. +function getServerAddress() { + var host = window.location.hostname; + if (!Boolean(host)) + host = "127.0.0.1"; + + return host + ":" + PORT; +} + +function is_local_access() { + var host = window.location.hostname; + return !Boolean(host) || host == "127.0.0.1" || host == "localhost"; +} + // Shows/hides a front popup over the given background element. function showPopup(backElementID, frontElementID, visible) { // Initialize variables. diff --git a/connectcore-demo-example/static/js/dashboard.js b/connectcore-demo-example/static/js/dashboard.js index cf609ec..f1e9c47 100644 --- a/connectcore-demo-example/static/js/dashboard.js +++ b/connectcore-demo-example/static/js/dashboard.js @@ -60,8 +60,6 @@ const ID_WIFI_BT_PANEL_AREA = "wifi_bt_panel_area"; const ID_WIFI_BT_PANEL_ARROW = "wifi_bt_panel_arrow"; const ID_WIFI_BT_PANEL_ICON = "wifi_bt_panel_icon"; -const PORT = "9090"; - const IFACE_BT = "hci0/"; const IFACE_ETHERNET = "eth0/"; const IFACE_WIFI = "wlan0/"; @@ -1006,12 +1004,3 @@ function changeSampleRate() { // Navigate to management page. window.open("../management/?device_id=" + getDeviceID() + "&device_name=" + getDeviceName(), "_self"); } - -// Returns the server address. -function getServerAddress() { - var host = window.location.hostname; - if (!Boolean(host)) - host = "127.0.0.1"; - - return host + ":" + PORT; -} diff --git a/connectcore-demo-example/static/js/file-system.js b/connectcore-demo-example/static/js/file-system.js index f6d034a..b3d83d9 100644 --- a/connectcore-demo-example/static/js/file-system.js +++ b/connectcore-demo-example/static/js/file-system.js @@ -29,7 +29,9 @@ const ID_FILE_SYSTEM_ITEMS_HEADER = "filesystem_items_header"; const ID_FILE_SYSTEM_LOADING = "filesystem_loading"; const ID_FILE_SYSTEM_PANEL = "filesystem_panel"; const ID_FILE_SYSTEM_REMOVE_FILE_BUTTON = "filesystem_remove_file_button"; +const ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON = "filesystem_upload_file_button"; const ID_FILE_SYSTEM_TOOLBAR = "filesystem_toolbar"; +const ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER = "filesystem_toolbar_buttons_container"; const ID_FILE_TO_UPLOAD = "file_to_upload"; const CLASS_FA_FILE = "fa-file"; @@ -98,6 +100,11 @@ function openFileSystem() { // Show the file system. var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL); fileSystemContainer.style.visibility = "visible"; + if (is_local_access()) { + document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON).style.display = "none"; + document.getElementById(ID_FILE_SYSTEM_UPLOAD_FILE_BUTTON).style.display = "none"; + document.getElementById(ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER).style.width = "90px"; + } // List root directory. listDirectory(ROOT_DIRECTORY); } @@ -244,7 +251,7 @@ function listDirectory(directory) { showFileSystemLoading(true); // Send request. $.post( - "../ajax/fs_list_directory", + "http://" + getServerAddress() + "/ajax/fs_list_directory", JSON.stringify({ "directory": path }), @@ -333,7 +340,7 @@ function downloadFile(fileName) { // Send request $.ajax({ type: 'POST', - url: "../ajax/fs_download_file", + url: "http://" + getServerAddress() + "/ajax/fs_download_file", data: data, cache: false, async: true, @@ -436,7 +443,7 @@ function removeFile(fileName, isFile) { showFileSystemLoading(true); // Send request. $.post( - "../ajax/fs_remove_file", + "http://" + getServerAddress() + "/ajax/fs_remove_file", JSON.stringify({ "path": path, "is_file": isFile @@ -489,7 +496,7 @@ function uploadFile(file) { // Send request. $.ajax({ type: 'POST', - url: "../ajax/fs_upload_file", + url: "http://" + getServerAddress() + "/ajax/fs_upload_file", data: formData, cache: false, async: true, @@ -613,7 +620,7 @@ function createDirectory(directoryName) { showFileSystemLoading(true); // Send request. $.post( - "../ajax/fs_create_dir", + "http://" + getServerAddress() + "/ajax/fs_create_dir", JSON.stringify({ "path": path }),