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:
Tatiana Leon 2022-05-16 13:57:02 +02:00
parent 2bfc4d728d
commit f9853cf8e1
6 changed files with 415 additions and 433 deletions

View File

@ -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.

View File

@ -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>

View File

@ -382,6 +382,7 @@ body {
left: 50%;
text-align: center;
max-width: 800px;
min-width: 300px;
}
.popup i {

View File

@ -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";

View File

@ -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);
}

View File

@ -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);