connectcore-demo-example: management: implement management section
Reboot and firmware update operations. https://onedigi.atlassian.net/browse/DEL-7742 Signed-off-by: Tatiana Leon <Tatiana.Leon@digi.com>
This commit is contained in:
parent
2bfc4d728d
commit
f9853cf8e1
|
|
@ -22,6 +22,7 @@ import logging
|
|||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import signal
|
||||
import socketserver
|
||||
import stat
|
||||
|
|
@ -53,6 +54,7 @@ stop_event = Event()
|
|||
last_cpu_work = 0
|
||||
last_cpu_total = 0
|
||||
led_status = {}
|
||||
fw_process = None
|
||||
|
||||
|
||||
class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
||||
|
|
@ -71,8 +73,14 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
"""
|
||||
Override.
|
||||
"""
|
||||
# Forbidden.
|
||||
self._set_headers(403)
|
||||
if re.search("/ping", self.path) is not None:
|
||||
# Set the response headers.
|
||||
self._set_headers(200)
|
||||
# Send the JSON value.
|
||||
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||
else:
|
||||
# Forbidden.
|
||||
self._set_headers(403)
|
||||
|
||||
def do_POST(self):
|
||||
"""
|
||||
|
|
@ -101,6 +109,7 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
"memory_total": mem_info.get("MemTotal", NOT_AVAILABLE) if mem_info else NOT_AVAILABLE,
|
||||
"flash_size": get_storage_size(),
|
||||
"video_resolution": get_video_resolution(),
|
||||
"fw_store_path": get_fw_store_path(),
|
||||
"bluetooth_mac": get_bt_mac("hci0"),
|
||||
"wifi_mac": read_file("/sys/class/net/wlan0/address").strip().upper() if "wlan0" in list_net_ifaces() else ZERO_MAC,
|
||||
"wifi_ip": get_iface_ip("wlan0") if "wlan0" in list_net_ifaces() else ZERO_IP,
|
||||
|
|
@ -202,8 +211,9 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
# Get the JSON data.
|
||||
data = self.rfile.read(int(self.headers["Content-Length"]))
|
||||
path = json.loads(data.decode("utf-8")).get("directory", None)
|
||||
filters = json.loads(data.decode("utf-8")).get("filters", None)
|
||||
|
||||
log.debug("List directory: %s", path)
|
||||
log.debug("List directory: %s (filters %s)", path, filters)
|
||||
|
||||
if not path or not os.path.exists(path):
|
||||
error = "Invalid path" if not path else "No such file or directory"
|
||||
|
|
@ -212,27 +222,15 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
return
|
||||
|
||||
work_path = os.path.realpath(path)
|
||||
content = []
|
||||
tmp_list = []
|
||||
|
||||
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:
|
||||
for item in os.listdir(work_path):
|
||||
item_path = os.path.join(path, item)
|
||||
item_work_path = os.path.realpath(item_path)
|
||||
st = os.stat(item_work_path)
|
||||
if not os.path.isdir(item_work_path):
|
||||
if not filter_by_extension(item_path, filters):
|
||||
continue
|
||||
item = {
|
||||
"type": "dir" if os.path.isdir(item_work_path) else "file",
|
||||
"name": os.path.join(path, item),
|
||||
|
|
@ -240,10 +238,20 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
}
|
||||
if os.path.isfile(item_work_path):
|
||||
item["size"] = st[stat.ST_SIZE]
|
||||
content.append(item)
|
||||
tmp_list.append(item)
|
||||
|
||||
f_list = sorted(tmp_list, key=lambda item: (item["type"], os.path.basename(item["name"])))
|
||||
|
||||
# Add item '..'
|
||||
if os.path.dirname(work_path) != work_path:
|
||||
f_list.insert(0, {
|
||||
"type": "dir",
|
||||
"name": os.path.join(path, ".."),
|
||||
"last_modified": os.stat(os.path.join(path, "..")),
|
||||
})
|
||||
|
||||
# Send the JSON value.
|
||||
self.wfile.write(json.dumps(dir_list).encode(encoding="utf_8"))
|
||||
self.wfile.write(json.dumps({"current_dir": path, "files": f_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)
|
||||
|
|
@ -326,10 +334,23 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
data = cgi.parse_multipart(self.rfile, pdict)
|
||||
path = data.get("path", [None])[0]
|
||||
f_data = data.get("file", [bytes()])[0]
|
||||
overwrite = data.get("overwrite", [False])[0]
|
||||
error = None
|
||||
|
||||
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.debug("Upload file: %s (overwrite %s)", path, overwrite)
|
||||
|
||||
if not path:
|
||||
error = "Invalid path"
|
||||
elif os.path.exists(path):
|
||||
if not overwrite:
|
||||
error = "File already exists"
|
||||
else:
|
||||
try:
|
||||
os.remove(path)
|
||||
except OSError as e:
|
||||
error = e.strerror
|
||||
|
||||
if error:
|
||||
log.error("Error uploading file '%s': %s", path, error)
|
||||
self.wfile.write(json.dumps({"error": error}).encode(encoding="utf_8"))
|
||||
return
|
||||
|
|
@ -342,6 +363,88 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
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"))
|
||||
elif re.search("/ajax/reboot_device", self.path) is not None:
|
||||
# Set the response headers.
|
||||
self._set_headers(200)
|
||||
|
||||
log.debug("Reboot device")
|
||||
|
||||
# Send the JSON value.
|
||||
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||
|
||||
exec_cmd("reboot")
|
||||
elif re.search("/ajax/update_firmware", self.path) is not None:
|
||||
global fw_process
|
||||
|
||||
# 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("file", None)
|
||||
|
||||
log.debug("Update firmware with file %s", path)
|
||||
|
||||
if is_dual_system():
|
||||
cmd = "firmware-update-dual.sh %s" % path
|
||||
else:
|
||||
if not path.startswith(get_fw_store_path()):
|
||||
# Move the package to /mnt/update
|
||||
update_path = os.path.join(get_fw_store_path(), os.path.basename(path))
|
||||
if os.path.exists(update_path):
|
||||
os.remove(update_path)
|
||||
shutil.move(path, update_path)
|
||||
path = update_path
|
||||
cmd = "update-firmware --reboot-timeout=1 %s" % path
|
||||
|
||||
log.debug("Update cmd: %s", cmd)
|
||||
|
||||
try:
|
||||
fw_process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
shell=True, text=True)
|
||||
self.wfile.write("{}".encode(encoding="utf_8"))
|
||||
except OSError as e:
|
||||
log.error("Error updating firmware '%s': %s", path, e.strerror)
|
||||
self.wfile.write(json.dumps({"error": e.strerror}).encode(encoding="utf_8"))
|
||||
fw_process = None
|
||||
except subprocess.SubprocessError as e:
|
||||
log.error("Error updating firmware '%s': %s", path, e.stdout)
|
||||
self.wfile.write(json.dumps({"error": e.stdout}).encode(encoding="utf_8"))
|
||||
fw_process = None
|
||||
|
||||
if is_dual_system() and os.path.exists(path):
|
||||
os.remove(path)
|
||||
elif re.search("/ajax/check_firmware_update_running", self.path) is not None:
|
||||
# Set the response headers.
|
||||
self._set_headers(200)
|
||||
|
||||
is_running = (fw_process.poll() is not None) if fw_process else False
|
||||
|
||||
log.debug("Update firmware is running %s", is_running)
|
||||
|
||||
self.wfile.write(json.dumps({"update-running": is_running}).encode(encoding="utf_8"))
|
||||
elif re.search("/ajax/check_firmware_update_status", self.path) is not None:
|
||||
# Set the response headers.
|
||||
self._set_headers(200)
|
||||
|
||||
status = "successful"
|
||||
if fw_process:
|
||||
ret = fw_process.poll()
|
||||
if ret is None:
|
||||
status = "active"
|
||||
elif ret != 0:
|
||||
status = "failed"
|
||||
|
||||
log.debug("Update firmware status %s", status)
|
||||
|
||||
self.wfile.write(json.dumps({"status": status}).encode(encoding="utf_8"))
|
||||
elif re.search("/ajax/check_firmware_update_progress", self.path) is not None:
|
||||
# Set the response headers.
|
||||
self._set_headers(200)
|
||||
progress = 100
|
||||
if fw_process and fw_process.poll() is None:
|
||||
progress = "?"
|
||||
self.wfile.write(json.dumps({"progress": progress, "message": "Updating firmare"}).encode(encoding="utf_8"))
|
||||
else:
|
||||
# Forbidden.
|
||||
self._set_headers(403)
|
||||
|
|
@ -368,6 +471,27 @@ class RequestHandler(http.server.SimpleHTTPRequestHandler):
|
|||
self.end_headers()
|
||||
|
||||
|
||||
def filter_by_extension(name, filters):
|
||||
"""
|
||||
Returns whether the provided name ends with one of the provided filters.
|
||||
|
||||
Args:
|
||||
name (String): Name of the file to check.
|
||||
filters (String): Comma-separated extensions.
|
||||
|
||||
Returns:
|
||||
Boolean: True if the file ends with one of the filters, False otherwise.
|
||||
"""
|
||||
if not filters:
|
||||
return True
|
||||
|
||||
for ext in filters.split(","):
|
||||
if name.endswith(ext):
|
||||
return True
|
||||
|
||||
return False;
|
||||
|
||||
|
||||
def get_uptime():
|
||||
"""
|
||||
Gets the system uptime in seconds.
|
||||
|
|
@ -473,6 +597,30 @@ def get_video_resolution():
|
|||
return res.split(":")[1].strip()
|
||||
|
||||
|
||||
def is_dual_system():
|
||||
"""
|
||||
Returns wherther is a dual system.
|
||||
|
||||
Returns:
|
||||
Boolean: True for dual systems, False otherwise.
|
||||
"""
|
||||
res = exec_cmd("fdisk -l | grep recovery")
|
||||
return res[0] != 0
|
||||
|
||||
|
||||
def get_fw_store_path():
|
||||
"""
|
||||
Returns the path to store an image before an update.
|
||||
|
||||
Returns:
|
||||
String: Absolute path to store a firmware image.
|
||||
"""
|
||||
if is_dual_system():
|
||||
return "/home/root/"
|
||||
|
||||
return "/mnt/update/"
|
||||
|
||||
|
||||
def get_mem_info():
|
||||
"""
|
||||
Gets a dictionary with memory info.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ Digi Demo - Management
|
|||
|
||||
<link rel="stylesheet" href="./static/css/general.css">
|
||||
<link rel="stylesheet" href="./static/css/toastr.css">
|
||||
<link rel="stylesheet" href="./static/css/xterm.css">
|
||||
|
||||
<!-- JS, Popper.js, and jQuery -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
|
||||
|
|
@ -41,7 +40,7 @@ Digi Demo - Management
|
|||
<div>
|
||||
<img src="./static/images/board.png" class="device-title-img" title="Device">
|
||||
</div>
|
||||
<div id="device-name"></div>
|
||||
<div id="device-name">DEY DEVICE</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
@ -55,7 +54,7 @@ Digi Demo - Management
|
|||
|
||||
<ul id="sections" data-pjax class="list-group">
|
||||
<li>
|
||||
<a data-pjax href="/dashboard/" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<a data-pjax href="index.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-tachometer-alt fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Dashboard</span>
|
||||
|
|
@ -63,15 +62,15 @@ Digi Demo - Management
|
|||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="/history/" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<a data-pjax href="multimedia.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-chart-area fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Historical data</span>
|
||||
<span class="digi-menu-icon fas fa-film fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Multimedia</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a data-pjax href="/management/" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<a data-pjax href="management.html" class="list-group-item list-group-item-action d-flex align-items-center">
|
||||
<div class="d-flex w-100 justify-content-start align-items-center">
|
||||
<span class="digi-menu-icon fas fa-cog fa-fw fa-lg mr-3"></span>
|
||||
<span class="menu-collapsed">Management</span>
|
||||
|
|
@ -99,7 +98,7 @@ Digi Demo - Management
|
|||
<div id="pjax-container">
|
||||
|
||||
<!-- <input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu,.json,.txt"/>-->
|
||||
<input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()"/>
|
||||
<input type="file" id="firmware_file" style="display:none" onchange="firmwareFileChanged()" accept=".swu"/>
|
||||
<div class="row justify-content-lg-center">
|
||||
<div class="col-lg-12 col-xl-12">
|
||||
<div id="loading_popup" class="popup popup-loading shadow">
|
||||
|
|
@ -122,6 +121,13 @@ Digi Demo - Management
|
|||
<div id="confirm_dialog_yes_button" class="device-card-button confirm-dialog-button">Yes</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rebooted_dialog" class="popup popup-info shadow d-none">
|
||||
<div class="popup-title"><p><i class="fa fa-check success-message fa-lg"></i> Device rebooted</p></div>
|
||||
<div class="popup-text">Reload the page to continue.</div>
|
||||
<div class="confirm-dialog-buttons-container" style="padding-top: 30px;">
|
||||
<div id="reload_button" class="device-card-button confirm-dialog-button" onclick="document.location.replace('index.html')">Reload</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loading_wrapper" class="loading-wrapper element-grayed">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
|
|
@ -164,10 +170,6 @@ Digi Demo - Management
|
|||
<span class="fas fa-upload fa-lg"></span>
|
||||
<span class="firmware-tab-text">Upload file</span>
|
||||
</div>
|
||||
<div id="firmware_tab_fileset_header" class="firmware-tab-header" onclick="showFirmwareTab(ID_FIRMWARE_TAB_FILESET)">
|
||||
<span class="fas fa-database fa-lg"></span>
|
||||
<span class="firmware-tab-text">Download from storage</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="firmware-tab-container">
|
||||
<div id="firmware_tab_upload" class="firmware-tab firmware-tab-upload">
|
||||
|
|
@ -177,18 +179,6 @@ Digi Demo - Management
|
|||
<div id="firmware_file_label" class="firmware-file-label">No file chosen</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="firmware_tab_fileset" class="firmware-tab firmware-tab-fileset">
|
||||
<div>Download and install firmware from Digi Remote Manager storage.</div>
|
||||
<div class="fileset-items-header">
|
||||
<div class="fileset-entry-icon"></div>
|
||||
<div class="fileset-entry-name">Name</div>
|
||||
<div class="fileset-entry-path">Path</div>
|
||||
<div class="fileset-entry-size">Size</div>
|
||||
<div class="fileset-entry-last-modified">Last modified</div>
|
||||
</div>
|
||||
<div id="fileset_items_container" class="fileset-items-container"></div>
|
||||
<div id="refresh_fileset_button" class="device-card-button refresh-fileset-button" onclick="refreshFilesetFiles()">Refresh</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="update_firmware_progress" class="update-firmware-progress">
|
||||
<div id="update_firmware_progress_title" class="update-firmware-progress-title">Firmware update in progress...</div>
|
||||
|
|
@ -199,13 +189,61 @@ Digi Demo - Management
|
|||
</div>
|
||||
<div>
|
||||
<div id="update_firmware_button" class="device-card-button update-firmware-button management-button-disabled" onclick="askUpdateFirmware()">Update Firmware</div>
|
||||
<div id="cancel_update_firmware_button" class="device-card-button cancel-firmware-update-button management-button-disabled" onclick="askCancelFirmwareUpdate()">Cancel update</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- card body -->
|
||||
</div> <!-- card shadow -->
|
||||
<div id="filesystem_panel" class="filesystem-panel">
|
||||
<div class="filesystem-background"></div>
|
||||
<div id="filesystem_container" class="filesystem-container">
|
||||
<div id="filesystem_header" class="device-card-header">
|
||||
<span class="fas fa-folder-open fa-lg mr-2"></span>
|
||||
<span>Device's file system</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeFileSystem()"></div>
|
||||
</div>
|
||||
<div id="filesystem_hover_background" class="filesystem-hover-background"></div>
|
||||
<div id="filesystem_dir_name_panel" class="filesystem-dir-name-panel">
|
||||
<div class="filesystem-dir-name-background"></div>
|
||||
<div class="filesystem-dir-name-container">
|
||||
<div class="device-card-header">
|
||||
<span class="fas fa-folder-plus fa-lg mr-2"></span>
|
||||
<span>Create new directory</span>
|
||||
<div class="fas fa-window-close fa-lg device-card-header-button" onclick="closeDirectoryNamePanel()"></div>
|
||||
</div>
|
||||
<div class="filesystem-dir-name-label">Enter the new directory name</div>
|
||||
<input id="filesystem_directory_name" class="filesystem-dir-name-input" type="text"/>
|
||||
<div id="filesystem_directory_name_error" class="filesystem-dir-name-error"></div>
|
||||
<div id="filesystem_directory_name_button" class="device-card-button filesystem-dir-name-button filesystem-dir-name-button-disabled" onclick="onCreateDirectory()">Create directory</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar" class="filesystem-toolbar">
|
||||
<div class="filesystem-current-directory-container">
|
||||
<div class="filesystem-current-directory-label">Current dir:</div>
|
||||
<div id="current_directory" class="filesystem-current-directory"></div>
|
||||
</div>
|
||||
<div id="filesystem_toolbar_buttons_container" class="filesystem-toolbar-buttons-container">
|
||||
<div id="filesystem_select_file_button" class="filesystem-button fas fa-bolt fa-2x" onclick="selectFirmwareFile()" title="Select firmware file"></div>
|
||||
<div id="filesystem_create_directory_button" class="filesystem-button fas fa-folder-plus fa-2x" onclick="openDirectoryNamePanel()" title="Create directory"></div>
|
||||
<div id="filesystem_upload_file_button" class="filesystem-button fas fa-upload fa-2x" onclick="openFileBrowser()" title="Upload file"></div>
|
||||
<div id="filesystem_download_file_button" class="filesystem-button fas fa-file-download fa-2x" onclick="downloadSelectedFile()" title="Download file"></div>
|
||||
<div id="filesystem_remove_file_button" class="filesystem-button fas fa-trash fa-2x" onclick="askRemoveFile()" title="Remove file"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="filesystem_items_header" class="filesystem-items-header">
|
||||
<div class="filesystem-entry-icon"></div>
|
||||
<div class="filesystem-entry-name">Name</div>
|
||||
<div class="filesystem-entry-size">Size</div>
|
||||
<div class="filesystem-entry-last-modified">Last modified</div>
|
||||
</div>
|
||||
<div id="filesystem_items_container" class="filesystem-items-container"></div>
|
||||
<div id="filesystem_loading" class="popup shadow" style="top: 33%">
|
||||
<img class="popup-item" src="./static/images/loading.gif" alt="Loading..." />
|
||||
<div class="popup-text">Loading...</div>
|
||||
</div>
|
||||
</div> <!-- filesystem_container -->
|
||||
</div> <!-- filesystem_panel -->
|
||||
</div> <!-- loading wrapper -->
|
||||
</div> <!-- col -->
|
||||
</div> <!-- row justify -->
|
||||
|
||||
|
||||
<script>
|
||||
|
|
@ -223,10 +261,10 @@ Digi Demo - Management
|
|||
});
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div> <!-- pjax-container -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- container fluid -->
|
||||
</div> <!--bg light -->
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
|
@ -252,11 +290,8 @@ Digi Demo - Management
|
|||
<script type="text/javascript" src="./static/js/ccimx8m-nano.js"></script>
|
||||
<script type="text/javascript" src="./static/js/ccimx8x-sbc-pro.js"></script>
|
||||
<script type="text/javascript" src="./static/js/dashboard.js"></script>
|
||||
<script type="text/javascript" src="./static/js/multimedia.js"></script>
|
||||
<script type="text/javascript" src="./static/js/management.js"></script>
|
||||
<script type="text/javascript" src="./static/js/history.js"></script>
|
||||
<script type="text/javascript" src="./static/js/xterm.js"></script>
|
||||
<script type="text/javascript" src="./static/js/xterm-addon-fit.js"></script>
|
||||
<script type="text/javascript" src="./static/js/console.js"></script>
|
||||
<script type="text/javascript" src="./static/js/file-system.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
|
@ -298,10 +333,6 @@ Digi Demo - Management
|
|||
|
||||
// Set the selected section.
|
||||
setSelectedSection();
|
||||
|
||||
// Set the name of the selected device.
|
||||
$("#device-name").html("DEY device".toUpperCase());
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -382,6 +382,7 @@ body {
|
|||
left: 50%;
|
||||
text-align: center;
|
||||
max-width: 800px;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
.popup i {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ const ID_ETHERNET_STATE = "ethernet_state";
|
|||
const ID_FILES = "files";
|
||||
const ID_FLASH_MEMORY = "flash_memory";
|
||||
const ID_FLASH_SIZE = "flash_size";
|
||||
const ID_FW_STORE_PATH = "fw_store_path";
|
||||
const ID_HAS_ARROW = "has-arrow";
|
||||
const ID_HAS_PANEL = "has-panel";
|
||||
const ID_ICON = "icon";
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
// Constants.
|
||||
const ID_CURRENT_DIRECTORY = "current_directory";
|
||||
const ID_FILE_SYSTEM_CONTAINER = "filesystem_container";
|
||||
const ID_FILE_SYSTEM_CREATE_DIR_BUTTON = "filesystem_create_directory_button";
|
||||
const ID_FILE_SYSTEM_DIR_NAME = "filesystem_directory_name";
|
||||
const ID_FILE_SYSTEM_DIR_NAME_BUTTON = "filesystem_directory_name_button";
|
||||
const ID_FILE_SYSTEM_DIR_NAME_ERROR = "filesystem_directory_name_error";
|
||||
|
|
@ -29,6 +30,7 @@ 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_SELECT_FILE_BUTTON = "filesystem_select_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";
|
||||
|
|
@ -52,18 +54,18 @@ const PREFIX_FS = "fs_";
|
|||
const REGEX_DIRECTORY_NAME = '^[^\\s^\x00-\x1f\\?*:"";<>|\\/.][^\x00-\x1f\\?*:"";<>|\\/]*[^\\s^\x00-\x1f\\?*:"";<>|\\/.]+$';
|
||||
|
||||
const TEMPLATE_DIRECTORY = "" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='listDirectory(\"{2}\")'>" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='listDirectory(\"{2}\", filters=\"{3}\")'>" +
|
||||
" <div class='fas fa-folder fa-lg filesystem-entry-icon'></div>" +
|
||||
" <div class='filesystem-entry-name'>{3}</div>" +
|
||||
" <div class='filesystem-entry-name'>{4}</div>" +
|
||||
" <div class='filesystem-entry-size'></div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{4}</div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{5}</div>" +
|
||||
"</div>";
|
||||
const TEMPLATE_FILE = "" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='selectFileSystemEntry(\"fs_{2}\")' ondblclick='downloadFile(\"{3}\")'>" +
|
||||
"<div id='fs_{0}' class='filesystem-entry' title='{1}' onclick='selectFileSystemEntry(\"fs_{2}\", filters=\"{3}\")' ondblclick='downloadFile(\"{4}\")'>" +
|
||||
" <div class='fas fa-file fa-lg filesystem-entry-icon'></div>" +
|
||||
" <div class='filesystem-entry-name'>{4}</div>" +
|
||||
" <div class='filesystem-entry-size'>{5}</div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{6}</div>" +
|
||||
" <div class='filesystem-entry-name'>{5}</div>" +
|
||||
" <div class='filesystem-entry-size'>{6}</div>" +
|
||||
" <div class='filesystem-entry-last-modified'>{7}</div>" +
|
||||
"</div>";
|
||||
|
||||
const ERROR_DIR_NAME_EMPTY = "Directory name cannot be empty.";
|
||||
|
|
@ -77,7 +79,7 @@ var selectedFileSystemEntry = null;
|
|||
var filesystemResizeObserver = null;
|
||||
|
||||
// Opens the file system panel.
|
||||
function openFileSystem() {
|
||||
function openFileSystem(showButtons=true, filters="") {
|
||||
// Check if the file system is showing.
|
||||
if (isFileSystemShowing())
|
||||
return;
|
||||
|
|
@ -100,19 +102,23 @@ function openFileSystem() {
|
|||
// Show the file system.
|
||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||
fileSystemContainer.style.visibility = "visible";
|
||||
if (is_local_access()) {
|
||||
if (!showButtons || 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";
|
||||
document.getElementById(ID_FILE_SYSTEM_TOOLBAR_BUTTONS_CONTAINER).style.width = "auto";
|
||||
}
|
||||
if (!showButtons) {
|
||||
document.getElementById(ID_FILE_SYSTEM_CREATE_DIR_BUTTON).style.display = "none";
|
||||
document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON).style.display = "none";
|
||||
}
|
||||
// List root directory.
|
||||
listDirectory(ROOT_DIRECTORY);
|
||||
listDirectory(ROOT_DIRECTORY, filters=filters);
|
||||
}
|
||||
|
||||
// Returns whether the file system window is open or not.
|
||||
function isFileSystemShowing() {
|
||||
// Sanity checks.
|
||||
if (!isDashboardShowing())
|
||||
if (!isDashboardShowing() && !isManagementShowing())
|
||||
return false;
|
||||
// Initialize variables.
|
||||
var fileSystemContainer = document.getElementById(ID_FILE_SYSTEM_PANEL);
|
||||
|
|
@ -178,26 +184,63 @@ function clearFileSystemEntries() {
|
|||
}
|
||||
|
||||
// Enables/disabled the file system buttons.
|
||||
function enableFileSystemButtons(enable) {
|
||||
function enableFileSystemButtons(enable, filters="") {
|
||||
// Initialize variables.
|
||||
var downloadButton = document.getElementById(ID_FILE_SYSTEM_DOWNLOAD_FILE_BUTTON);
|
||||
var removeButton = document.getElementById(ID_FILE_SYSTEM_REMOVE_FILE_BUTTON);
|
||||
var selectFwButton = document.getElementById(ID_FILE_SYSTEM_SELECT_FILE_BUTTON);
|
||||
// Apply enable state.
|
||||
if (!enable) {
|
||||
downloadButton.disabled = true;
|
||||
removeButton.disabled = true;
|
||||
downloadButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
||||
removeButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
||||
if (removeButton) {
|
||||
removeButton.disabled = true;
|
||||
removeButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (downloadButton) {
|
||||
downloadButton.disabled = true;
|
||||
downloadButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (selectFwButton) {
|
||||
selectFwButton.disabled = true;
|
||||
selectFwButton.classList.add(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
} else {
|
||||
downloadButton.disabled = false;
|
||||
removeButton.disabled = false;
|
||||
downloadButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
||||
removeButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED)
|
||||
if (removeButton) {
|
||||
removeButton.disabled = false;
|
||||
removeButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (downloadButton) {
|
||||
downloadButton.disabled = false;
|
||||
downloadButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
if (selectFwButton) {
|
||||
enable = false;
|
||||
if (filters) {
|
||||
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||
var filter_list = filters.split(",");
|
||||
for (var i = 0; i < filter_list.length; i++) {
|
||||
if (filePath.endsWith(filter_list[i])) {
|
||||
enable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!filters || enable) {
|
||||
selectFwButton.disabled = false;
|
||||
selectFwButton.classList.remove(CLASS_FILE_SYSTEM_BUTTON_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Downloads the selected file.
|
||||
function selectFirmwareFile() {
|
||||
// Build file path.
|
||||
var filePath = selectedFileSystemEntry.substring(PREFIX_FS.length);
|
||||
firmwareFileChanged(filePath);
|
||||
}
|
||||
|
||||
// Selects the given file system entry.
|
||||
function selectFileSystemEntry(entryID) {
|
||||
function selectFileSystemEntry(entryID, filters="") {
|
||||
// Unselect all entries.
|
||||
unselectFileSystemEntries();
|
||||
// Set selected style to the selected device div.
|
||||
|
|
@ -207,7 +250,7 @@ function selectFileSystemEntry(entryID) {
|
|||
// Save selected entry.
|
||||
selectedFileSystemEntry = entryID;
|
||||
// Enable buttons.
|
||||
enableFileSystemButtons(true);
|
||||
enableFileSystemButtons(true, filters=filters);
|
||||
}
|
||||
|
||||
// Unselects all the file system entries.
|
||||
|
|
@ -227,7 +270,7 @@ function unselectFileSystemEntries() {
|
|||
}
|
||||
|
||||
// Lists the contents of the given directory.
|
||||
function listDirectory(directory) {
|
||||
function listDirectory(directory, filters="") {
|
||||
// Build path.
|
||||
var path = currentDirectory;
|
||||
if (path == null || currentDirectory == directory)
|
||||
|
|
@ -253,14 +296,15 @@ function listDirectory(directory) {
|
|||
$.post(
|
||||
"http://" + getServerAddress() + "/ajax/fs_list_directory",
|
||||
JSON.stringify({
|
||||
"directory": path
|
||||
"directory": path,
|
||||
"filters": filters,
|
||||
}),
|
||||
function(data) {
|
||||
// Process only if the file system window is showing.
|
||||
if (!isFileSystemShowing())
|
||||
return;
|
||||
// Process answer.
|
||||
processListDirectoryResponse(data);
|
||||
processListDirectoryResponse(data, filters=filters);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only if the file system window is showing.
|
||||
|
|
@ -274,7 +318,7 @@ function listDirectory(directory) {
|
|||
}
|
||||
|
||||
// Processes the list directory response.
|
||||
function processListDirectoryResponse(response) {
|
||||
function processListDirectoryResponse(response, filters="") {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Hide the loading status.
|
||||
|
|
@ -307,10 +351,10 @@ function processListDirectoryResponse(response) {
|
|||
}
|
||||
var entryDiv = document.createElement("div");
|
||||
if (entry[ID_TYPE] == FS_TYPE_FILE)
|
||||
entryDiv.innerHTML = TEMPLATE_FILE.format(name, name, name, name, name,
|
||||
entryDiv.innerHTML = TEMPLATE_FILE.format(name, name, name, filters, name, name,
|
||||
sizeToHumanRead(entry[ID_SIZE]), lastModified);
|
||||
else if (entry[ID_TYPE] == FS_TYPE_DIRECTORY)
|
||||
entryDiv.innerHTML = TEMPLATE_DIRECTORY.format(name, name, name, name, lastModified);
|
||||
entryDiv.innerHTML = TEMPLATE_DIRECTORY.format(name, name, name, filters, name, lastModified);
|
||||
if (entryDiv.innerHTML != null && entryDiv.innerHTML != "")
|
||||
fileSystemEntriesDiv.appendChild(entryDiv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,6 @@
|
|||
|
||||
// Constants.
|
||||
const ID_REBOOT_BUTTON = "reboot_button";
|
||||
const ID_CANCEL_FIRMWARE_UPDATE_BUTTON = "cancel_update_firmware_button";
|
||||
const ID_FILESET_ITEMS_CONTAINER = "fileset_items_container";
|
||||
const ID_FIRMWARE_TAB_FILESET = "firmware_tab_fileset";
|
||||
const ID_FIRMWARE_TAB_FILESET_HEADER = "firmware_tab_fileset_header";
|
||||
const ID_FIRMWARE_TAB_UPLOAD = "firmware_tab_upload";
|
||||
const ID_FIRMWARE_TAB_UPLOAD_HEADER = "firmware_tab_upload_header";
|
||||
const ID_SELECT_FIRMWARE_BUTTON = "select_firmware_button";
|
||||
|
|
@ -35,16 +31,11 @@ const ID_UPDATE_RUNNING = "update_running";
|
|||
const CLASS_FIRMWARE_TAB = "firmware-tab";
|
||||
const CLASS_FIRMWARE_TAB_HEADER = "firmware-tab-header";
|
||||
const CLASS_FIRMWARE_TAB_HEADER_ACTIVE = "firmware-tab-header-active";
|
||||
const CLASS_FILESET_ENTRY_NAME = "fileset-entry-name";
|
||||
const CLASS_FILESET_ENTRY_PATH = "fileset-entry-path";
|
||||
const CLASS_FILESET_ENTRY_SELECTED = "fileset-entry-selected";
|
||||
const CLASS_MANAGEMENT_BUTTON_DISABLED = "management-button-disabled";
|
||||
const CLASS_PROGRESS_BAR_ERROR = "update-firmware-progress-bar-error";
|
||||
const CLASS_PROGRESS_BAR_INFO = "update-firmware-progress-bar-info";
|
||||
const CLASS_PROGRESS_BAR_SUCCESS = "update-firmware-progress-bar-success";
|
||||
const CLASS_SAVE_BUTTON_DISABLED = "system-monitor-save-disabled";
|
||||
|
||||
const TITLE_CONFIRM_CANCEL_UPDATE = "Cancel firmware update";
|
||||
const TITLE_CONFIRM_FIRMWARE_UPDATE = "Confirm firmware update";
|
||||
const TITLE_CONFIRM_REBOOT = "Confirm reboot";
|
||||
const TITLE_DEVICE_REBOOTING = "Device Rebooting";
|
||||
|
|
@ -52,9 +43,7 @@ const TITLE_FIRMWARE_UPDATE_ERROR = "Firmware update failed!";
|
|||
const TITLE_FIRMWARE_UPDATE_IN_PROGRESS = "Firmware update in progress...";
|
||||
const TITLE_FIRMWARE_UPDATE_SUCCESS = "Firmware update succeeded!";
|
||||
|
||||
const MESSAGE_CANCELING_FIRMWARE_UPDATE = "Canceling firmware update...";
|
||||
const MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS = "Checking firmware update...";
|
||||
const MESSAGE_CONFIRM_CANCEL_UPDATE = "This action will cancel the ongoing firmware update process. Do you want to continue?";
|
||||
const MESSAGE_CONFIRM_FIRMWARE_UPDATE = "This action will update the device firmware. Do you want to continue?";
|
||||
const MESSAGE_CONFIRM_REBOOT = "This action will reboot the device and connection will be lost. Do you want to continue?";
|
||||
const MESSAGE_DEVICE_REBOOTING = "The device is rebooting. Please wait...";
|
||||
|
|
@ -68,23 +57,10 @@ const MESSAGE_UPLOAD_COMPLETE = "Firmware file upload complete";
|
|||
const MESSAGE_UPDATING_FIRMWARE = "Updating firmware...";
|
||||
const MESSAGE_UPLOADING_FIRMWARE = "Uploading firmware file...";
|
||||
|
||||
const REGEX_INTEGER = '^[0-9]+$';
|
||||
|
||||
const UPDATE_ERROR = "error";
|
||||
const UPDATE_INFO = "info";
|
||||
const UPDATE_SUCCESS = "success";
|
||||
|
||||
const DEMO_FILE_SET = "ConnectCoreDemo";
|
||||
|
||||
const TEMPLATE_FILESET_FILE = "" +
|
||||
"<div id='file_{0}' class='fileset-entry' title='{1}' onclick='selectFilesetEntry(\"file_{2}\")'>" +
|
||||
" <div class='fas fa-file fa-lg fileset-entry-icon'></div>" +
|
||||
" <div class='fileset-entry-name'>{3}</div>" +
|
||||
" <div class='fileset-entry-path'>{4}</div>" +
|
||||
" <div class='fileset-entry-size'>{5}</div>" +
|
||||
" <div class='fileset-entry-last-modified'>{6}</div>" +
|
||||
"</div>";
|
||||
|
||||
const FIRMWARE_UPDATE_CHECK_INTERVAL = 10000;
|
||||
|
||||
// Variables.
|
||||
|
|
@ -93,10 +69,8 @@ var managementInfoRead = false;
|
|||
var deviceRebooting = false;
|
||||
var updatingFirmware = false;
|
||||
var firmwareUpdateTimer = null;
|
||||
var uploadProgressSocket = null;
|
||||
var uploadFirmwareAjaxRequest = null;
|
||||
var filesLoaded = false;
|
||||
var selectedFilesetEntry = null;
|
||||
var fwStorageDir = "/home/root/";
|
||||
|
||||
// Initializes the management page.
|
||||
function initializeManagementPage() {
|
||||
|
|
@ -124,10 +98,14 @@ function readDeviceInfoManagement() {
|
|||
showLoadingPopup(true, MESSAGE_LOADING_INFORMATION);
|
||||
// Send request to retrieve device information.
|
||||
$.post(
|
||||
"../ajax/get_device_info",
|
||||
"http://" + getServerAddress() + "/ajax/get_device_info",
|
||||
function(data) {
|
||||
readingManagementInfo = false;
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
// Process device information answer.
|
||||
processDeviceInfoManagementResponse(data);
|
||||
}
|
||||
|
|
@ -150,15 +128,18 @@ function processDeviceInfoManagementResponse(response) {
|
|||
if (!checkErrorResponse(response, false)) {
|
||||
// Fill device info.
|
||||
fillDeviceInfo(response);
|
||||
} else {
|
||||
readingManagementInfo = false;
|
||||
// Hide the loading panel.
|
||||
showLoadingPopup(false);
|
||||
fwStorageDir = response[ID_FW_STORE_PATH];
|
||||
// Flag device info read.
|
||||
managementInfoRead = true;
|
||||
// Check if there is a firmware update running.
|
||||
checkFirmwareUpdateRunning();
|
||||
}
|
||||
}
|
||||
|
||||
// Fills device information.
|
||||
function fillDeviceInfo(deviceData) {
|
||||
// Set the device type.
|
||||
updateFieldValue(ID_DEVICE_NAME, deviceData[ID_DEVICE_TYPE].toUpperCase());
|
||||
// Set DEY version.
|
||||
updateFieldValue(ID_DEY_VERSION, deviceData[ID_DEY_VERSION]);
|
||||
// Set Kernel version.
|
||||
|
|
@ -188,7 +169,7 @@ function rebootDevice() {
|
|||
showLoadingPopup(true, MESSAGE_SENDING_REBOOT);
|
||||
// Send request to reboot the device.
|
||||
$.post(
|
||||
"../ajax/reboot_device",
|
||||
"http://" + getServerAddress() + "/ajax/reboot_device",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
|
|
@ -209,43 +190,78 @@ function rebootDevice() {
|
|||
});
|
||||
}
|
||||
|
||||
function onConnectivity(cb) {
|
||||
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||
cb();
|
||||
}).fail(function() {
|
||||
onConnectivity(cb);
|
||||
});
|
||||
}
|
||||
|
||||
function showRebootInfo() {
|
||||
// Show info dialog.
|
||||
showInfoPopup(true, TITLE_DEVICE_REBOOTING, "Waiting for connectivity after reboot <span class=\"dots\"></span>");
|
||||
deviceRebooting = true;
|
||||
managementInfoRead = false;
|
||||
prevDeviceConnectionStatus = false;
|
||||
|
||||
var dotsInterval = setInterval(function() {
|
||||
var dots = $("#info_popup .dots");
|
||||
dots.text(dots.text() === "..." ? "" : dots.text() + ".");
|
||||
}, 2000);
|
||||
|
||||
setTimeout(function() {
|
||||
onConnectivity(function() {
|
||||
clearInterval(dotsInterval);
|
||||
showInfoPopup(false);
|
||||
showPopup(ID_LOADING_WRAPPER, "rebooted_dialog", true);
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// Processes the response of the reboot device request.
|
||||
function processRebootDeviceResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Show info dialog.
|
||||
showInfoPopup(true, TITLE_DEVICE_REBOOTING, MESSAGE_DEVICE_REBOOTING);
|
||||
deviceRebooting = true;
|
||||
managementInfoRead = false;
|
||||
// TODO: This should not be necessary when implementing device connection monitor.
|
||||
prevDeviceConnectionStatus = false;
|
||||
}
|
||||
if (!checkErrorResponse(response, false))
|
||||
showRebootInfo();
|
||||
}
|
||||
|
||||
// Opens the firmware file browser.
|
||||
function openFirmwareBrowser() {
|
||||
document.getElementById(ID_UPDATE_FIRMWARE_FILE).click();
|
||||
if (is_local_access())
|
||||
openFileSystem(showButtons=false, filters=".swu");
|
||||
else
|
||||
document.getElementById(ID_UPDATE_FIRMWARE_FILE).click();
|
||||
}
|
||||
|
||||
// Reads the device status.
|
||||
function firmwareFileChanged() {
|
||||
function firmwareFileChanged(fileName="") {
|
||||
// Execute only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
closeFileSystem();
|
||||
// Initialize variables.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
var firmwareFileLabelElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL);
|
||||
// Hide progress bar.
|
||||
showFirmwareUpdateProgress(false);
|
||||
if (firmwareFileElement.files.length == 0) {
|
||||
if (fileName == "" && firmwareFileElement.files.length == 0) {
|
||||
// No file selected.
|
||||
firmwareFileLabelElement.innerHTML = MESSAGE_NO_FILE_SELECTED;
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
return;
|
||||
}
|
||||
var firmwareFile = firmwareFileElement.files[0];
|
||||
var firmwareFile = "";
|
||||
// Build file path.
|
||||
if (is_local_access()) {
|
||||
firmwareFile = currentDirectory + fileName;
|
||||
// Hide the loading status.
|
||||
showFileSystemLoading(false);
|
||||
} else {
|
||||
firmwareFile = firmwareFileElement.files[0].name;
|
||||
}
|
||||
// Update firmware file name.
|
||||
firmwareFileLabelElement.innerHTML = firmwareFile.name;
|
||||
firmwareFileLabelElement.innerHTML = firmwareFile;
|
||||
// Enable button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||
}
|
||||
|
|
@ -270,19 +286,13 @@ function askUpdateFirmware() {
|
|||
showFirmwareUpdateProgress(true);
|
||||
// Disable management page controls.
|
||||
enableManagementPageControls(false);
|
||||
// Enable cancel button.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
||||
// Check active tab.
|
||||
if (activeTab == ID_FIRMWARE_TAB_UPLOAD) {
|
||||
// Upload firmware.
|
||||
uploadFirmwareFile();
|
||||
} else if (activeTab == ID_FIRMWARE_TAB_FILESET) {
|
||||
// Build file path.
|
||||
var filesetEntryElement = document.getElementById(selectedFilesetEntry);
|
||||
var fileName = filesetEntryElement.getElementsByClassName(CLASS_FILESET_ENTRY_NAME)[0].innerHTML;
|
||||
var filePath = filesetEntryElement.getElementsByClassName(CLASS_FILESET_ENTRY_PATH)[0].innerHTML;
|
||||
// Update firmware.
|
||||
updateFirmware(DEMO_FILE_SET + "/" + filePath + "/" + fileName);
|
||||
if (!is_local_access())
|
||||
// Upload firmware.
|
||||
uploadFirmwareFile();
|
||||
else
|
||||
updateFirmware(document.getElementById(ID_UPDATE_FIRMWARE_FILE_LABEL).innerHTML);
|
||||
}
|
||||
},
|
||||
function() {
|
||||
|
|
@ -300,15 +310,13 @@ function uploadFirmwareFile() {
|
|||
setFirmwareUpdateProgressInfo(0, MESSAGE_UPLOADING_FIRMWARE);
|
||||
// Prepare data.
|
||||
var formData = new FormData();
|
||||
formData.append("file_set", DEMO_FILE_SET);
|
||||
formData.append("file_name", firmwareFile.name);
|
||||
formData.append("path", fwStorageDir + firmwareFile.name);
|
||||
formData.append("file", firmwareFile);
|
||||
// Register websocket to receive upload progress.
|
||||
subscribeUploadFileProgress(firmwareFile.name);
|
||||
// Send request
|
||||
uploadFirmwareAjaxRequest = $.ajax({
|
||||
formData.append("overwrite", true);
|
||||
// Send request.
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "../ajax/upload_firmware",
|
||||
url: "http://" + getServerAddress() + "/ajax/fs_upload_file",
|
||||
data: formData,
|
||||
cache: false,
|
||||
async: true,
|
||||
|
|
@ -318,9 +326,6 @@ function uploadFirmwareFile() {
|
|||
success: function(response) {
|
||||
// Reset request variable.
|
||||
uploadFirmwareAjaxRequest = null;
|
||||
// Close progress socket.
|
||||
if (uploadProgressSocket != null && uploadProgressSocket != "undefined")
|
||||
uploadProgressSocket.close();
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
|
|
@ -330,9 +335,6 @@ function uploadFirmwareFile() {
|
|||
error: function(response) {
|
||||
// Reset request variable.
|
||||
uploadFirmwareAjaxRequest = null;
|
||||
// Close progress socket.
|
||||
if (uploadProgressSocket != null && uploadProgressSocket != "undefined")
|
||||
uploadProgressSocket.close();
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
|
|
@ -366,26 +368,7 @@ function processUploadFirmwareFileResponse(response) {
|
|||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
var firmwareFile = firmwareFileElement.files[0];
|
||||
// Send the update request.
|
||||
//updateFirmware(DEMO_FILE_SET + "/" + getDeviceID() + "/" + firmwareFile.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribes to firmware update progress.
|
||||
function subscribeUploadFileProgress(fileName) {
|
||||
// Create the web socket.
|
||||
var socketPrefix = window.location.protocol == "https:" ? "wss" : "ws";
|
||||
uploadProgressSocket = new WebSocket(socketPrefix + "://" + window.location.host + "/ws/file_upload_progress/" + fileName);
|
||||
// Define the callback to be notified when firmware update progress is received.
|
||||
uploadProgressSocket.onmessage = function(e) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing()) {
|
||||
// Close the socket.
|
||||
uploadProgressSocket.close();
|
||||
return;
|
||||
}
|
||||
// Update progress.
|
||||
var data = JSON.parse(e.data);
|
||||
setFirmwareUpdateProgressInfo(data[ID_PROGRESS], MESSAGE_UPLOADING_FIRMWARE);
|
||||
updateFirmware(fwStorageDir + firmwareFile.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -393,11 +376,9 @@ function subscribeUploadFileProgress(fileName) {
|
|||
function updateFirmware(filePath) {
|
||||
// Update status.
|
||||
setFirmwareUpdateProgressInfo(0, MESSAGE_SENDING_UPLOAD_REQUEST);
|
||||
// Disable the cancel button.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
||||
// Send request to update the firmware.
|
||||
$.post(
|
||||
"../ajax/update_firmware",
|
||||
"http://" + getServerAddress() + "/ajax/update_firmware",
|
||||
JSON.stringify({
|
||||
"file": filePath
|
||||
}),
|
||||
|
|
@ -435,8 +416,6 @@ function processUpdateFirmwareResponse(response) {
|
|||
// Enable the page controls.
|
||||
enableManagementPageControls(true);
|
||||
} else {
|
||||
// Enable the cancel button.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
||||
// Update progress status.
|
||||
setFirmwareUpdateProgressInfo(100, MESSAGE_SENDING_FIRMWARE_UPDATE_REQUEST);
|
||||
// Start timer to check firmware update status periodically.
|
||||
|
|
@ -476,7 +455,7 @@ function checkFirmwareUpdateStatus() {
|
|||
}
|
||||
// Send request to check firmware update status.
|
||||
$.post(
|
||||
"../ajax/check_firmware_update_status",
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_status",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
|
|
@ -488,8 +467,13 @@ function checkFirmwareUpdateStatus() {
|
|||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
$.get("http://" + getServerAddress() + "/ping", function() {
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
}).fail(function() {
|
||||
if (!deviceRebooting)
|
||||
showRebootInfo();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -516,6 +500,7 @@ function processCheckFirmwareUpdateStatusResponse(response) {
|
|||
managementInfoRead = false;
|
||||
// Set update as successful.
|
||||
setFirmwareUpdateProgressSuccess(response[ID_MESSAGE]);
|
||||
showRebootInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -532,7 +517,7 @@ function checkFirmwareUpdateRunning() {
|
|||
showLoadingPopup(true, MESSAGE_CHECKING_FIRMWARE_UPDATE_STATUS);
|
||||
// Send request to check firmware update running.
|
||||
$.post(
|
||||
"../ajax/check_firmware_update_running",
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_running",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
|
|
@ -561,8 +546,6 @@ function processCheckFirmwareUpdateRunningResponse(response) {
|
|||
updatingFirmware = true;
|
||||
// Disable page controls.
|
||||
enableManagementPageControls(false);
|
||||
// Enable cancel button.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
||||
// Show firmware update progress.
|
||||
showFirmwareUpdateProgress(true);
|
||||
// Update the firmware update progress.
|
||||
|
|
@ -585,7 +568,7 @@ function checkFirmwareUpdateProgress() {
|
|||
showLoadingPopup(false);
|
||||
// Send request to check firmware update progress.
|
||||
$.post(
|
||||
"../ajax/check_firmware_update_progress",
|
||||
"http://" + getServerAddress() + "/ajax/check_firmware_update_progress",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
|
|
@ -611,212 +594,6 @@ function processCheckFirmwareUpdateProgressResponse(response) {
|
|||
}
|
||||
}
|
||||
|
||||
// Asks user to cancel the firmware update process
|
||||
function askCancelFirmwareUpdate() {
|
||||
showConfirmDialog(TITLE_CONFIRM_CANCEL_UPDATE, MESSAGE_CONFIRM_CANCEL_UPDATE,
|
||||
function() {
|
||||
cancelFirmwareUpdate();
|
||||
},
|
||||
function() {
|
||||
// Do nothing.
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Cancels an ongoing firmware update.
|
||||
function cancelFirmwareUpdate() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing() || !updatingFirmware)
|
||||
return;
|
||||
// Check the type of the firmware update.
|
||||
if (uploadFirmwareAjaxRequest != null)
|
||||
cancelFirmwareUploadProcess();
|
||||
else
|
||||
cancelFirmwareUpdateProcess();
|
||||
}
|
||||
|
||||
// Cancels the firmware upload process.
|
||||
function cancelFirmwareUploadProcess() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Send request to cancel firmware upload.
|
||||
uploadProgressSocket.send("cancel");
|
||||
// Abort AJAX request.
|
||||
uploadFirmwareAjaxRequest.abort();
|
||||
uploadFirmwareAjaxRequest = null;
|
||||
// Flag the update variable.
|
||||
updatingFirmware = false;
|
||||
// Enable page controls.
|
||||
enableManagementPageControls(true);
|
||||
// Hide he firmware update progress.
|
||||
showFirmwareUpdateProgress(false);
|
||||
}
|
||||
|
||||
// Cancels the remote firmware update process.
|
||||
function cancelFirmwareUpdateProcess() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Disable cancel button.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
||||
// Show loading popup.
|
||||
showLoadingPopup(true, MESSAGE_CANCELING_FIRMWARE_UPDATE);
|
||||
// Send request to cancel firmware update.
|
||||
$.post(
|
||||
"../ajax/cancel_firmware_update",
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process cancel firmware update answer.
|
||||
processCancelFirmwareUpdateResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
// Enable cancel button again.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the cancel firmware update request.
|
||||
function processCancelFirmwareUpdateResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (checkErrorResponse(response, false)) {
|
||||
// Enable cancel button again.
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, true);
|
||||
} else {
|
||||
// Flag the update variable.
|
||||
updatingFirmware = false;
|
||||
// Enable page controls.
|
||||
enableManagementPageControls(true);
|
||||
// Hide firmware update progress.
|
||||
showFirmwareUpdateProgress(false);
|
||||
// Stop the firmware update timer.
|
||||
stopFirmwareUpdateTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// Clears the fileset file list.
|
||||
function clearFilesetList() {
|
||||
// Initialize variables.
|
||||
var filesetEntriesContainerElement = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
||||
// Clear the fileset file list.
|
||||
if (filesetEntriesContainerElement != null && filesetEntriesContainerElement != "undefined") {
|
||||
while (filesetEntriesContainerElement.firstChild)
|
||||
filesetEntriesContainerElement.removeChild(filesetEntriesContainerElement.lastChild);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh the fileset list of files.
|
||||
function refreshFilesetFiles() {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Flag files loaded.
|
||||
filesLoaded = false;
|
||||
// Reset fileset files.
|
||||
listFilesetFiles(DEMO_FILE_SET);
|
||||
}
|
||||
|
||||
// Lists all the files of a fileset.
|
||||
function listFilesetFiles(fileSet) {
|
||||
// Sanity checks
|
||||
if (!isManagementShowing() || filesLoaded)
|
||||
return;
|
||||
// Unselect all fileset entries.
|
||||
unselectFilesetEntries();
|
||||
// Clear the fileset list.
|
||||
clearFilesetList();
|
||||
// Show loading popup.
|
||||
showLoadingPopup(true, MESSAGE_LOADING_FILES);
|
||||
// Send request to list files.
|
||||
$.post(
|
||||
"../ajax/list_fileset_files",
|
||||
JSON.stringify({
|
||||
"file_set": fileSet
|
||||
}),
|
||||
function(data) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process answer.
|
||||
processListFilesetFilesResponse(data);
|
||||
}
|
||||
).fail(function(response) {
|
||||
// Process only in the management page.
|
||||
if (!isManagementShowing())
|
||||
return;
|
||||
// Hide loading popup.
|
||||
showLoadingPopup(false);
|
||||
// Process error.
|
||||
processAjaxErrorResponse(response);
|
||||
});
|
||||
}
|
||||
|
||||
// Processes the response of the list fileset files request.
|
||||
function processListFilesetFilesResponse(response) {
|
||||
// Check if there was any error in the request.
|
||||
if (!checkErrorResponse(response, false)) {
|
||||
// Parse the files contained in the fileset.
|
||||
var files = response[ID_FILES];
|
||||
// Add the files to the list.
|
||||
if (files != null && files != "undefined") {
|
||||
var filesetEntriesContainerElement = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
||||
for (var entry of response[ID_FILES]) {
|
||||
var name = entry[ID_NAME];
|
||||
var entryDiv = document.createElement("div");
|
||||
entryDiv.innerHTML = TEMPLATE_FILESET_FILE.format(name, name, name, name, entry[ID_PATH],
|
||||
sizeToHumanRead(entry[ID_SIZE]), transformDate(entry[ID_LAST_MODIFIED]));
|
||||
filesetEntriesContainerElement.appendChild(entryDiv);
|
||||
}
|
||||
}
|
||||
// Flag fileset list variable.
|
||||
filesLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Selects a file from the fileset list
|
||||
function selectFilesetEntry(entryID) {
|
||||
// Unselect all entries.
|
||||
unselectFilesetEntries();
|
||||
// Set selected style to the selected div.
|
||||
var entryElement = document.getElementById(entryID)
|
||||
if (entryElement != null) {
|
||||
entryElement.classList.add(CLASS_FILESET_ENTRY_SELECTED);
|
||||
selectedFilesetEntry = entryID;
|
||||
// Enable update firmware button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||
// Hide firmware update progress.
|
||||
showFirmwareUpdateProgress(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Unselects all the fileset entries.
|
||||
function unselectFilesetEntries() {
|
||||
// Initialize variables.
|
||||
var fileSystemEntriesDiv = document.getElementById(ID_FILESET_ITEMS_CONTAINER);
|
||||
var children = fileSystemEntriesDiv.children;
|
||||
// Remove selected class from all entries.
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var entry = children[i].children[0];
|
||||
entry.classList.remove(CLASS_FILESET_ENTRY_SELECTED);
|
||||
}
|
||||
selectedFilesetEntry = null;
|
||||
// Disable firmware update button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
}
|
||||
|
||||
// Enables/disables the management page controls.
|
||||
function enableManagementPageControls(enable) {
|
||||
// Reboot button.
|
||||
|
|
@ -829,32 +606,16 @@ function enableManagementPageControls(enable) {
|
|||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
else
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
||||
} else if (activeTab == ID_FIRMWARE_TAB_FILESET) {
|
||||
if (!filesLoaded || selectedFilesetEntry == null)
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, false);
|
||||
else
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, enable);
|
||||
}
|
||||
// Cancel update button.
|
||||
if (isFirmwareUpdateRunning() && enable)
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, enable);
|
||||
else
|
||||
enableManagementButton(ID_CANCEL_FIRMWARE_UPDATE_BUTTON, false);
|
||||
// Tabs.
|
||||
var tabUploadElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD);
|
||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||
var tabFilesetElement = document.getElementById(ID_FIRMWARE_TAB_FILESET);
|
||||
var tabFilesetHeaderElement = document.getElementById(ID_FIRMWARE_TAB_FILESET_HEADER);
|
||||
if (enable) {
|
||||
tabUploadElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
tabUploadHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
tabFilesetElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
tabFilesetHeaderElement.classList.remove((CLASS_DISABLED_DIV));
|
||||
} else {
|
||||
tabUploadElement.classList.add((CLASS_DISABLED_DIV));
|
||||
tabUploadHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
||||
tabFilesetElement.classList.add((CLASS_DISABLED_DIV));
|
||||
tabFilesetHeaderElement.classList.add((CLASS_DISABLED_DIV));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -875,12 +636,9 @@ function enableManagementButton(buttonID, enable) {
|
|||
function getActiveFirmwareUpdateTab() {
|
||||
// Initialize variables.
|
||||
var tabUploadHeaderElement = document.getElementById(ID_FIRMWARE_TAB_UPLOAD_HEADER);
|
||||
var tabFilesetHeaderElement = document.getElementById(ID_FIRMWARE_TAB_FILESET_HEADER);
|
||||
// Check the active tab.
|
||||
if (tabUploadHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
||||
return ID_FIRMWARE_TAB_UPLOAD;
|
||||
else if (tabFilesetHeaderElement.classList.contains(CLASS_FIRMWARE_TAB_HEADER_ACTIVE))
|
||||
return ID_FIRMWARE_TAB_FILESET;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
|
@ -923,15 +681,6 @@ function showFirmwareTab(tabID) {
|
|||
showFirmwareUpdateProgress(false);
|
||||
// Perform additional actions on each tab.
|
||||
switch(tabID) {
|
||||
case ID_FIRMWARE_TAB_FILESET:
|
||||
if (filesLoaded && selectedFilesetEntry != null) {
|
||||
// Enable firmware update button.
|
||||
enableManagementButton(ID_UPDATE_FIRMWARE_BUTTON, true);
|
||||
} else if (!filesLoaded) {
|
||||
// Refresh fileset entries.
|
||||
listFilesetFiles(DEMO_FILE_SET);
|
||||
}
|
||||
break;
|
||||
case ID_FIRMWARE_TAB_UPLOAD:
|
||||
// Check if there is a file in the file input.
|
||||
var firmwareFileElement = document.getElementById(ID_UPDATE_FIRMWARE_FILE);
|
||||
|
|
@ -998,8 +747,16 @@ function updateFirmwareUpdateProgress(status, progress, title=null, message=null
|
|||
break;
|
||||
}
|
||||
// Update the progress bar percent.
|
||||
progressBarElement.style.width = progress + "%";
|
||||
progressBarElement.innerHTML = progress + "%";
|
||||
if (progress != "?") {
|
||||
progressBarElement.style.width = progress + "%";
|
||||
progressBarElement.innerHTML = progress + "%";
|
||||
} else {
|
||||
let html = progressBarElement.innerHTML;
|
||||
if (html.startsWith("."))
|
||||
progressBarElement.innerHTML = html + ".";
|
||||
else
|
||||
progressBarElement.innerHTML = ".";
|
||||
}
|
||||
}
|
||||
// Update the progress title.
|
||||
var progressTitleElement = document.getElementById(ID_UPDATE_FIRMWARE_PROGRESS_TITLE);
|
||||
|
|
|
|||
Loading…
Reference in New Issue