// MIT License // // Copyright (c) 2016-2018, Alexander I. Chebykin // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. /** * CAI CP v.0.9.1 * * @module : Core * @author : Alexander I. Chebykin * @copyright : Copyright (c) 2016-2018 Alexander I. Chebykin * @version : 0.9.1 * @build date : 2018-06-05 * @license : MIT * @link : https://github.com/CAI79/CAI-CP ******************************************************************/ (function () { "use strict"; /** * Return GET parameter * * @param {string} key Key name * * returns {string} */ function $_GET(key) { var s = window.location.search; s = s.match(new RegExp(key + "=([^&=]+)")); return s ? s[1] : false; } /** * Check value is numeric * * @param {variant} value Value to be checked * * @returns {Boolean} */ function isNumeric(value) { return !isNaN(parseFloat(value)) && isFinite(value); } /** * Return string with formatted numeric value. ex: 12345,6 -> 12'345,6 * * @param {variant} value Source value * @param {separator} separator Character used to separate thousands * * @returns {String} */ function numFormatted(value, separator) { var result = "", splitted = value.toString().split(" "); for (var i = 0; i < splitted.length; i++) { if (isNumeric(splitted[i])) { result += " " + splitted[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, separator); } else { result += " " + splitted[i].toString(); } } return result; } /** * Add message with timestamp to browser's console * * @param {string} log_message Message text * * @returns {undefined} */ function console_log(log_message) { var now = new Date(); console.log(now + ": " + log_message); } /** * Application constructor * * @returns {undefined} */ function Application() { /* Object types */ this.OT_TABLE_H = 1; this.OT_TABLE_V = 2; this.OT_IFRAME = 3; this.OT_CANVAS = 4; // this.OT_DIV = 5; this.timers = []; this.apps_list = {}; this.lang = {}; this.menu = {}; this.settings = {}; this.widgets = {}; this.blocks_rotation = ["system", "system_pulse", "storage", "network", "smb"]; this.cur_block = 0; /* Monitoring variables */ this.mon_users = 0; this.mon_users_info = { "count" : 0, "last_user": "", "last_addr": "" }; /* Ctrl pressed flag */ this.ctrl_on = false; /* Down point for swipe event on header */ this.hdr_x_down = null; this.hdr_y_down = null; this.init(1); } /** * Add events handlers * * @returns {undefined} */ Application.prototype.add_evt_handlers = function () { var app_instance = this; /* Add swipe handler to header */ document.getElementById("app_header").addEventListener("touchstart", function (event) { app_instance.hdr_x_down = event.touches[0].clientX; app_instance.hdr_y_down = event.touches[0].clientY; }, false); document.getElementById("app_header").addEventListener("touchmove", function (event) { if (!app_instance.hdr_x_down || !app_instance.hdr_y_down) { return; } var x_up = event.touches[0].clientX, y_up = event.touches[0].clientY, delta_x = app_instance.hdr_x_down - x_up, delta_y = app_instance.hdr_y_down - y_up; if (Math.abs(delta_x) > Math.abs(delta_y)) { if (delta_x > 0) { /* left swipe */ app_instance.cur_block += 1; if (app_instance.cur_block > app_instance.blocks_rotation.length - 1) { app_instance.cur_block = 0; } } else { /* right swipe */ app_instance.cur_block -= 1; if (app_instance.cur_block < 0) { app_instance.cur_block = app_instance.blocks_rotation.length - 1; } } app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]); if (app_instance.blocks_rotation[app_instance.cur_block] === "system") { app_instance.os_logo_draw(); } // } else { // if (delta_y > 0) { /* up swipe */ // } else { /* down swipe */ // } } /* reset values */ app_instance.hdr_x_down = null; app_instance.hdr_y_down = null; }, false); /* Add ctrl pressed flag switcher */ document.addEventListener("keydown", function (event) { if ((event.which === 17) && !app_instance.ctrl_on) { app_instance.ctrl_on = true; } if (app_instance.ctrl_on) { /* Temporary turn off ctrl flag */ app_instance.ctrl_on = false; switch (event.which) { case 37: // Ctrl + <- app_instance.cur_block -= 1; if (app_instance.cur_block < 0) { app_instance.cur_block = app_instance.blocks_rotation.length - 1; } app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]); if (app_instance.blocks_rotation[app_instance.cur_block] === "system") { app_instance.os_logo_draw(); } event.preventDefault(); break; case 39: // Ctrl + -> app_instance.cur_block += 1; if (app_instance.cur_block > app_instance.blocks_rotation.length - 1) { app_instance.cur_block = 0; } app_instance.widgets_run(app_instance.blocks_rotation[app_instance.cur_block]); if (app_instance.blocks_rotation[app_instance.cur_block] === "system") { app_instance.os_logo_draw(); } event.preventDefault(); break; case 49: // Ctrl + 1 app_instance.widgets_run("system"); app_instance.os_logo_draw(); event.preventDefault(); break; case 50: // Ctrl + 2 app_instance.widgets_run("system_pulse"); event.preventDefault(); break; case 51: // Ctrl + 3 app_instance.widgets_run("storage"); event.preventDefault(); break; case 52: // Ctrl + 4 app_instance.widgets_run("network"); event.preventDefault(); break; case 53: // Ctrl + 5 app_instance.widgets_run("smb"); event.preventDefault(); break; case 112: // Ctrl + F1 app_instance.help_show(false); event.preventDefault(); break; } app_instance.ctrl_on = true; } }); document.addEventListener("keyup", function (event) { if ((event.which === 17) && app_instance.ctrl_on) { app_instance.ctrl_on = false; } }); }; /** * Get data by uri * * @param {string} uri Data uri * * returns {undefined} */ Application.prototype.get_data = function (uri) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onload = function() { resolve(this.responseText); }; xhr.onerror = reject; xhr.open("GET", uri); xhr.send(); }); }; /** * Initialize application * * @param {numeric} init_level Initialization level: * 1 - Load settings, * 2 - Load localization * 3 - Initializa interface * * @returns {Boolean} */ Application.prototype.init = function (init_level) { var app_instance = this, json_file; switch (init_level) { case 1: /* Add events handlers */ this.add_evt_handlers(); /* Load user defined settings */ this.get_data("system/json/settings.json") .then(function(result) { app_instance.settings = JSON.parse(result); app_instance.init(2); }) .catch(function(result) { console_log("init 1 error: " + result); }); break; case 2: /* Load general settings */ this.get_data("system/json/general_settings/") .then(function(result) { var general_settings = JSON.parse(result); app_instance.settings.shutdown_enabled = general_settings.shutdown_enabled; app_instance.settings.reboot_enabled = general_settings.reboot_enabled; app_instance.settings.w_transmission_enabled = general_settings.w_transmission_enabled; app_instance.init(3); }) .catch(function(result) { console_log("init 2 error: " + result); }); break; case 3: /* Load locale */ if ($_GET("lang")) { json_file = "system/json/locale/" + $_GET("lang") + ".json"; } else { json_file = "system/json/locale/" + this.settings.lang + ".json"; window.history.pushState(null, null, "?lang=" + this.settings.lang); } this.get_data(json_file) .then(function(result) { app_instance.lang = JSON.parse(result); app_instance.init(4); }) .catch(function(result) { console_log("init 3 error: " + result); }); break; case 4: /* Files rights check */ if (this.settings.check_files_rights) { this.get_data("system/scripts/check_files.php") .then(function(result) { if (JSON.parse(result).length > 0) { var div_info = document.createElement("div"), text_info = document.createTextNode(app_instance.lang.fs_errors); div_info.style.cursor = "pointer"; div_info.appendChild(text_info); div_info.addEventListener("click", function () { app_instance.page_clear(); app_instance.widget_run(app_instance.w_table_files_check); }); document.getElementById("div_attention_content").appendChild(div_info); document.getElementById("div_attention").classList.remove("hidden"); } app_instance.init(5); }) .catch(function(result) { console_log("init 4 error: " + result); }); } else { this.init(5); return; } break; case 5: /* Interface init */ /* Menu elements */ this.menu = { "div_menu_info": { "id" : "div_menu_info", "caption" : this.lang.information, "visible" : true, "separator" : false, "elements": { "info_system": { "icon" : "gfx/icons/server.png", "caption" : this.lang.system, "callback" : function () { app_instance.widgets_run("system"); app_instance.os_logo_draw(); } }, "info_pulse": { "icon" : "gfx/icons/sysinfo.png", "caption" : this.lang.system_pulse, "callback" : function () { app_instance.widgets_run("system_pulse"); } }, "info_storage": { "icon" : "gfx/icons/storage.png", "caption" : this.lang.storage, "callback" : function () { app_instance.widgets_run("storage"); } }, "info_network": { "icon" : "gfx/icons/network.png", "caption" : this.lang.network, "callback" : function () { app_instance.widgets_run("network"); } }, "info_smb": { "icon" : "gfx/icons/samba.png", "caption" : this.lang.smb, "callback" : function () { app_instance.widgets_run("smb"); } } } }, "div_menu_app": { "id" : "div_menu_app", "caption" : this.lang.applications, "visible" : false, "separator" : true, "elements": {} }, "div_settings": { "id" : "div_menu_settings", "caption" : "", "visible" : true, "separator" : true, "elements" : { "cp_settings": { "icon" : "gfx/icons/settings.png", "caption" : this.lang.settings, "callback" : function () { app_instance.settings_show(); } }, "cp_help_about": { "icon" : "gfx/icons/about.png", "caption" : this.lang.about, "callback" : function () { app_instance.help_show(true); } }, "cp_help": { "icon" : "gfx/icons/help.png", "caption" : this.lang.help, "callback" : function () { app_instance.help_show(false); } } } }, "div_shutdown": { "id" : "div_menu_shutdown", "caption" : "", "visible" : true, "separator" : true, "elements": { "srv_reboot": { "icon" : "gfx/icons/reboot.png", "caption" : this.lang.reboot, "callback" : function () { app_instance.shutdown(true); } }, "srv_shutdown": { "icon" : "gfx/icons/shutdown.png", "caption" : this.lang.shutdown, "callback" : function () { app_instance.shutdown(false); } } } } }; if (!this.settings.shutdown_enabled && !this.settings.reboot_enabled) { delete this.menu.div_shutdown; } else { if (!this.settings.shutdown_enabled) { delete this.menu.div_shutdown.elements.srv_shutdown; } if (!this.settings.reboot_enabled) { delete this.menu.div_shutdown.elements.srv_reboot; } } /* Widgets declarations */ this.w_table_drv_temp = { parent : "page_content", id : "drv_temp_info", type : this.OT_TABLE_H, label : this.lang.drv_temp_info, class_name : "tbl_info", json_uri : "system/scripts/?widget=hdd_temp", raw_num : true, refresh : 60 }; this.w_table_drv_smart = { parent : "page_content", id : "drv_smart_info", type : this.OT_TABLE_H, label : this.lang.drv_smart_info, class_name : "tbl_info", json_uri : "system/json/?widget=hdd_smart", raq_num : true, refresh : 3600 }; this.w_table_fs_info = { parent : "page_content", id : "fs_info", type : this.OT_TABLE_H, label : this.lang.fs_info, class_name : "tbl_info", json_uri : "system/json/?widget=fs", raw_num : true, refresh : 30 }; this.w_table_iostat_info = { parent : "page_content", id : "iostat_info", type : this.OT_TABLE_H, label : this.lang.iostat_info, class_name : "tbl_info", json_uri : "system/json/?widget=io_stat", raw_num : false, refresh : 30 }; this.w_table_general_info = { parent : "page_content", id : "general_info", type : this.OT_TABLE_V, label : this.lang.general_info, class_name : "tbl_info", json_uri : "system/json/?widget=general_info", raw_num : true, refresh : 10 }; this.w_table_cpu_info = { parent : "page_content", id : "cpu_info", type : this.OT_TABLE_V, label : this.lang.cpu_info, class_name : "tbl_info", json_uri : "system/json/?widget=cpu_info", raw_num : false, refresh : 0 }; this.w_table_memory_info = { parent : "page_content", id : "memory_info", type : this.OT_TABLE_V, label : this.lang.memory_info, class_name : "tbl_info", json_uri : "system/json/?widget=mem_info", raw_num : false, refresh : 0 }; this.w_table_processes = { parent : "page_content", id : "proc_info", type : this.OT_TABLE_H, label : this.lang.proc_info, class_name : "tbl_info", json_uri : "system/json/?widget=processes", raw_num : false, refresh : 15 }; this.w_table_arp_cache = { parent : "page_content", id : "net_arp_cache_info", type : this.OT_TABLE_H, label : this.lang.net_arp_cache_info, class_name : "tbl_info", json_uri : "system/json/?widget=arp_cache", raw_num : true, refresh : 0 }; this.w_table_ip_addr = { parent : "page_content", id : "net_ip_addr_info", type : this.OT_TABLE_H, label : this.lang.net_ip_addr_info, class_name : "tbl_info", json_uri : "system/json/?widget=ip_addr", raw_num : true, refresh : 0 }; this.w_table_ip_route = { parent : "page_content", id : "net_ip_route_info", type : this.OT_TABLE_H, label : this.lang.net_ip_route_info, class_name : "tbl_info", json_uri : "system/json/?widget=ip_route", raw_num : true, refresh : 0 }; this.w_table_net_band = { parent : "page_content", id : "net_band_info", type : this.OT_TABLE_H, label : this.lang.net_band_info, class_name : "tbl_info", json_uri : "system/json/?widget=net_band", raw_num : false, refresh : 15 }; this.w_table_net_conn = { parent : "page_content", id : "net_conn_info", type : this.OT_TABLE_H, label : this.lang.net_conn_info, class_name : "tbl_info", json_uri : "system/json/?widget=net_conn", raw_num : true, refresh : 15 }; this.w_table_net_mcast = { parent : "page_content", id : "net_mcast_info", type : this.OT_TABLE_H, label : this.lang.net_mcast_info, class_name : "tbl_info", json_uri : "system/json/?widget=net_multicast", raw_num : true, refresh : 0 }; this.w_table_lstn_socks = { parent : "page_content", id : "net_lstn_socks_info", type : this.OT_TABLE_H, label : this.lang.net_lstn_socks_info, class_name : "tbl_info", json_uri : "system/json/?widget=listen_socks", raw_num : true, refresh : 0 }; this.w_table_unix_socks = { parent : "page_content", id : "net_unix_socks_info", type : this.OT_TABLE_H, label : this.lang.net_unix_socks_info, class_name : "tbl_info", json_uri : "system/json/?widget=active_unix_socks", raw_num : true, refresh : 0 }; this.w_table_transmission = { parent : "page_content", id : "transmission_info", type : this.OT_TABLE_H, label : this.lang.transmission_info, class_name : "tbl_info", json_uri : "system/scripts/json_transmission.php", raw_num : false, refresh : 30 }; this.w_table_users_online = { parent : "page_content", id : "users_online_info", type : this.OT_TABLE_H, label : this.lang.users_online_info, class_name : "tbl_info", json_uri : "system/json/?widget=users_online", raw_num : true, refresh : 30 }; this.w_table_smb_shares = { parent : "page_content", id : "smb_shares_info", type : this.OT_TABLE_H, label : this.lang.smb_shares_info, class_name : "tbl_info", json_uri : "system/json/?widget=smb_shares", raw_num : true, refresh : 30 }; this.w_table_smb_proc = { parent : "page_content", id : "smb_proc_info", type : this.OT_TABLE_H, label : this.lang.smb_proc_info, class_name : "tbl_info", json_uri : "system/json/?widget=smb_proc", raw_num : true, refresh : 30 }; this.w_table_smb_locks = { parent : "page_content", id : "smb_locks_info", type : this.OT_TABLE_H, label : this.lang.smb_locks_info, class_name : "tbl_info", json_uri : "system/json/?widget=smb_locks", raw_num : true, refresh : 30 }; this.w_canvas_cpu_graph = { parent : "page_content", id : "cpu_graph", type : this.OT_CANVAS, label : this.lang.cpu_info, class_name : "canvas_info", json_uri : "system/json/?widget=cpu_load", refresh : 5, min_val : 0, max_val : 100, raw_num : true, measure : "%" }; this.w_canvas_mem_graph = { parent : "page_content", id : "mem_graph", type : this.OT_CANVAS, label : this.lang.memory_info, class_name : "canvas_info", json_uri : "system/json/?widget=mem", refresh : 5, min_val : 0, max_val : "auto", raw_num : true, measure : "MB" }; this.w_canvas_net_down_graph = { parent : "page_content", id : "net_down_graph", type : this.OT_CANVAS, label : this.lang.net_down_info, class_name : "canvas_info", json_uri : "system/json/?widget=net_download_transfer_rate", refresh : 5, min_val : 0, max_val : "auto", raw_num : true, measure : "KB/s" }; this.w_canvas_net_up_graph = { parent : "page_content", id : "net_up_graph", type : this.OT_CANVAS, label : this.lang.net_up_info, class_name : "canvas_info", json_uri : "system/json/?widget=net_upload_transfer_rate", refresh : 5, min_val : 0, max_val : "auto", raw_num : true, measure : "KB/s" }; this.w_canvas_swap_graph = { parent : "page_content", id : "swap_graph", type : this.OT_CANVAS, label : this.lang.swap_info, class_name : "canvas_info", json_uri : "system/json/?widget=swap", refresh : 5, min_val : 0, max_val : "auto", raw_num : true, measure : "MB" }; this.w_table_files_check = { parent : "page_content", id : "files_check", type : this.OT_TABLE_H, label : this.lang.fs_check, class_name : "tbl_info", raw_num : true, json_uri : "system/scripts/check_files.php" }; this.w_reboot_iframe = { parent : "page_content", id : "reboot_iframe", type : this.OT_IFRAME, label : this.lang.reboot, class_name : "app_widget", json_uri : "system/action/?lang=" + $_GET("lang") + "&do=reboot" }; this.w_shutdown_iframe = { parent : "page_content", id : "shutdown_iframe", type : this.OT_IFRAME, label : this.lang.shutdown, class_name : "app_widget", json_uri : "system/action/?lang=" + $_GET("lang") + "&do=shutdown" }; this.w_settings_iframe = { parent : "page_content", id : "iframe_settings", type : this.OT_IFRAME, label : this.lang.settings, class_name : "app_widget", json_uri : "system/ui/forms/settings/?lang=" + $_GET("lang") }; this.w_about_iframe = { parent : "page_content", id : "iframe_cp_about", type : this.OT_IFRAME, label : this.lang.help, class_name : "app_widget", json_uri : "system/help/?lang=" + $_GET("lang") + "#about" }; this.w_help_iframe = { parent : "page_content", id : "iframe_cp_help", type : this.OT_IFRAME, label : this.lang.help, class_name : "app_widget", json_uri : "system/help/?lang=" + $_GET("lang") }; /* Widgets lists */ this.widgets_lists = { "storage": [ { "page_title" : this.lang.storage }, this.w_table_drv_temp, this.w_table_drv_smart, this.w_table_fs_info, this.w_table_iostat_info ], "network": [ { "page_title" : this.lang.network }, this.w_canvas_net_down_graph, this.w_canvas_net_up_graph, { "break" : true }, this.w_table_ip_addr, this.w_table_net_band, this.w_table_ip_route, this.w_table_users_online, this.w_table_net_mcast, this.w_table_arp_cache, this.w_table_lstn_socks, { "widget_css" : "div_widget_full_width" }, this.w_table_unix_socks, { "widget_css" : "div_widget_full_width" }, this.w_table_net_conn, this.w_table_transmission ], "smb": [ { "page_title" : this.lang.smb }, this.w_table_smb_proc, this.w_table_smb_shares, { "widget_css" : "div_widget_full_width" }, this.w_table_smb_locks ], "system": [ { "page_title" : this.lang.system, "widget_css" : "div_widget_type_a" }, this.w_table_general_info, this.w_table_memory_info, this.w_table_cpu_info ], "system_pulse": [ { "page_title" : this.lang.system_pulse }, this.w_canvas_cpu_graph, this.w_canvas_mem_graph, this.w_canvas_swap_graph, this.w_canvas_net_down_graph, this.w_canvas_net_up_graph, { "widget_css" : "div_widget_full_width" }, this.w_table_processes ] }; this.server_name_fill(); this.language_selector_add(); var m_menu = new MainMenu(this.lang); m_menu.clear_menu(m_menu.main_menu); m_menu.build_menu(this.menu); this.apps_list_load(); // app.check_apps(); if (window.location.hash.substr(1) !== "") { if (window.location.hash.substr(1) === "settings") { this.settings_show(); } else if (window.location.hash.substr(1) === "cp_help") { this.help_show(false); } else if (window.location.hash.substr(1) === "cp_about") { this.help_show(true); } else if (window.location.hash.substr(1, 3) !== "app") { this.widgets_run(window.location.hash.substr(1)); if (window.location.hash.substr(1) === "system") { this.os_logo_draw(); } } else { this.app_execute(window.location.hash.substr(1)); } } else { this.widgets_run("system"); this.os_logo_draw(); } /* Enable S.M.A.R.T and temperature monitoring */ this.monitoring_enable(); return true; } }; /** * Add language selector to page's header * * @returns {undefined} */ Application.prototype.language_selector_add = function () { var header = document.getElementById("app_header"), select_lang = document.createElement("select"); select_lang.id = "lang"; select_lang.classList.add("select_lang"); if ($_GET("lang")) { select_lang.classList.add("input_" + $_GET("lang")); } else { select_lang.classList.add("input_" + this.settings.lang); } select_lang.onchange = function () { /* * window.open(URL,name,specs,replace): where name: * * _blank - URL is loaded into a new window. This is default * _parent - URL is loaded into the parent frame * _self - URL replaces the current page * _top - URL replaces any framesets that may be loaded * name - The name of the window (Note: the name does not specify * the title of the new window) */ window.open(this.options[this.selectedIndex].value, "_self"); }; for (var language in this.settings.langs) { if (this.settings.langs.hasOwnProperty(language)) { var opt_lang = document.createElement("option"); opt_lang.value = "?lang=" + language; opt_lang.appendChild(document.createTextNode(this.settings.langs[language])); if ($_GET("lang") && $_GET("lang") === language) { opt_lang.selected = true; } else if (!$_GET("lang") && this.settings.lang === language){ opt_lang.selected = true; } select_lang.appendChild(opt_lang); } } header.appendChild(select_lang); }; /** * Change page title * * @param {string} new_title New page title * * @returns {undefined} */ Application.prototype.page_title_change = function (new_title) { var srv_title = document.getElementById("s_header").textContent; document.title = document.getElementById("s_header").textContent = srv_title.substring(0, srv_title.indexOf("#") + 1) + " " + new_title; }; /** * Check application existance and remove from menu if unexisted * * @param {string} app_name Application name * @param {string} app_exe Application executable * * @returns {undefined} */ Application.prototype.app_remove_unexisted = function (app_name, app_exe) { this.get_data("system/json/?widget=check_app¶m=" + app_exe) .then(function(result) { var element = document.getElementById("div_menu_" + app_name), json_data = JSON.parse(result); if ((json_data.exec !== "") && (!json_data.installed)) { element.parentNode.removeChild(element); } else { element.classList.remove("hidden"); } }) .catch(function(result) { console_log("app_remove_unexisted error: " + result); }); }; /** * Draw OS distro logo * * @returns {undefined} */ Application.prototype.os_logo_draw = function () { this.get_data("system/json/?widget=os_distr") .then(function(result) { var json_data = JSON.parse(result), div_gi = document.getElementById("general_info"); if (!div_gi) { return; } var img_logo = document.createElement("img"); img_logo.classList.add("distro_logo"); if (json_data.Distr.match(/opensuse/i)) { img_logo.src = "gfx/distros/opensuse.png"; } else if (json_data.Distr.match(/arch/i)) { img_logo.src = "gfx/distros/arch.png"; } else if (json_data.Distr.match(/bsd/i)) { img_logo.src = "gfx/distros/bsd.png"; } else if (json_data.Distr.match(/debian/i)) { img_logo.src = "gfx/distros/debian.png"; } else if (json_data.Distr.match(/fedora/i)) { img_logo.src = "gfx/distros/fedora.png"; } else if (json_data.Distr.match(/ubuntu/i)) { img_logo.src = "gfx/distros/ubuntu.png"; } else if (json_data.Family.match(/linux/i)) { img_logo.src = "gfx/distros/linux.png"; } else if (json_data.Family.match(/darwin/i)) { img_logo.src = "gfx/distros/apple.png"; } else { img_logo.src = "gfx/distros/unknown.png"; } div_gi.appendChild(img_logo); }) .catch(function(result) { console_log("Can't get disto info: " + result); }); }; /** * Clear page content * * returns {undefined} */ Application.prototype.page_clear = function () { var parent_node = document.getElementById("page_content"); /* Clear timers */ for (var key in this.timers) { if (this.timers.hasOwnProperty(key)) { clearInterval(this.timers[key]); } } this.timers = []; /* Remove widgets */ while (parent_node.firstChild) { parent_node.removeChild(parent_node.firstChild); } }; /** * Open control panel with selected application or widgets screen in new * window * * @param {string} hash URL hash * * @returns {undefined} */ Application.prototype.app_new_window = function (hash) { var new_location = location.href.replace(location.hash,""), new_win = window.open(new_location + "#" + hash, "_blank"); new_win.focus(); return; }; /** * Draw application widget * * @param {object} w_info Widget info * * @returns {undefined} */ Application.prototype.app_widget_draw = function (w_info) { var app_hash = w_info.id.substring(7); if (this.ctrl_on) { this.app_new_window(app_hash); return; } var app_widget = new Widget(this, w_info); this.page_clear(); this.page_title_change(w_info.label); app_widget.draw(); location.hash = app_hash; document.getElementById(w_info.id).classList.remove("slightly_visible"); }; /** * Fill server name on HTML page * * @returns {undefined} */ Application.prototype.server_name_fill = function () { this.get_data("system/json/?widget=srv_name") .then(function(result) { var s_header = document.getElementById("s_header"), json_data = JSON.parse(result); if (s_header.textContent !== "Loading...") { var temp = s_header.textContent; s_header.removeChild(s_header.childNodes[0]); s_header.appendChild(document.createTextNode( json_data.server_name + " #" + temp)); } else { s_header.removeChild(s_header.childNodes[0]); s_header.appendChild(document.createTextNode( json_data.server_name + " #")); } document.title = s_header.textContent; }) .catch(function(result) { console_log("server_name_fill error: " + result); }); }; /** * Execute application * * @param {string} app_name application name * * @returns {undefined} */ Application.prototype.app_execute = function (app_name) { var app_instance = this; this.get_data("system/apps/" + app_name.substr(4) + "/app.json") .then(function(result) { // TODO: Check why https_uri var json_data = JSON.parse(result), uri = json_data.https_uri, app_iframe = { parent : "page_content", id : "iframe_" + json_data.app_name, type : app_instance.OT_IFRAME, label : json_data.caption, class_name : "app_widget", json_uri : uri.replace("[server_name]", window.location.hostname) }; app_instance.app_widget_draw(app_iframe); }) .catch(function(result) { console_log("app_execute error: " + result); }); }; /** * Enable HDD S.M.A.R.T. monitoring * * @param {numeric} timeout Timeout in seconds * * @returns {undefined} */ Application.prototype.monitor_hdd_smart = function (timeout) { var app_instance = this; setTimeout(function () { app_instance.get_data("system/json/?widget=hdd_smart") .then(function(result) { var hdd_smart = JSON.parse(result), cur_date = new Date(); for (var hdd in hdd_smart) { if ((hdd_smart[hdd].status.toLowerCase() !== "passed") && (hdd_smart[hdd].status.toLowerCase() !== "ok")) { app_instance.notify(app_instance.lang.attention, {body: cur_date.toLocaleString() + ": " + app_instance.lang.hdd_smart_error + " " + hdd_smart[hdd].drive + " (" + hdd_smart[hdd].status + ")", tag: "cai_cp", icon: "../gfx/icons/attention.png", dir: "auto"}, function () { app_instance.widgets_run("storage"); }); } } console_log("HDD SMART monitor"); app_instance.monitor_hdd_smart(timeout); }) .catch(function(result) { console_log("monitor_hdd_smart error: " + result); app_instance.monitor_hdd_smart(timeout); }); }, timeout * 1000); }; /** * Enable HDD temperature monitoring * * @param {numeric} timeout Timeout in seconds * * @returns {undefined} */ Application.prototype.monitor_hdd_temp = function (timeout) { var app_instance = this; setTimeout(function () { app_instance.get_data("system/scripts/?widget=hdd_temp") .then(function(result) { var hdd_temp = JSON.parse(result), cur_date = new Date(); for (var hdd in hdd_temp) { if (hdd_temp[hdd].temperature.substring(0, hdd_temp[hdd].temperature.length - 2) > app_instance.settings.max_hdd_temp) { app_instance.notify(app_instance.lang.attention, {body: cur_date.toLocaleString() + ": " + app_instance.lang.hdd_overheat + " " + hdd_temp[hdd].drive + " (" + hdd_temp[hdd].model + "): " + hdd_temp[hdd].temperature, tag: "cai_cp", icon: "../gfx/icons/attention.png", dir: "auto"}, function () { app_instance.widgets_run("storage"); }); } } console_log("HDD temperature monitor"); app_instance.monitor_hdd_temp(timeout); }) .catch(function(result) { console_log("monitor_hdd_temp error: " + result); app_instance.monitor_hdd_temp(timeout); }); }, timeout * 1000); }; /** * Enable online users monitoring * * @param {numeric} timeout Timeout in seconds * * @returns {undefined} */ Application.prototype.monitor_users_online = function (timeout) { var app_instance = this; setTimeout(function () { app_instance.get_data("system/scripts/?widget=users_online") .then(function(result) { var users_online = JSON.parse(result), cur_date = new Date(); if (users_online.length > app_instance.mon_users_info.count || users_online[users_online.length - 1].from !== app_instance.mon_users_info.last_addr || users_online[users_online.length - 1].user !== app_instance.mon_users_info.last_user) { app_instance.notify(app_instance.lang.attention, {body: cur_date.toLocaleString() + ": " + app_instance.lang.new_user_connected + " (" + users_online[users_online.length - 1].user + ", " + users_online[users_online.length - 1].from + ")", tag: "cai_cp", icon: "../gfx/icons/attention.png", dir: "auto"}, function () { app_instance.widgets_run("network"); }); } app_instance.mon_users_info.count = users_online.length; app_instance.mon_users_info.last_user = users_online[users_online.length - 1].user; app_instance.mon_users_info.last_addr = users_online[users_online.length - 1].from; console_log("Online users monitor"); app_instance.monitor_users_online(timeout); }) .catch(function(result) { console_log("monitor_users_online error: " + result); app_instance.monitor_users_online(timeout); }); }, timeout * 1000); }; /** * Enable monitoring functions * * @returns {undefined} */ Application.prototype.monitoring_enable = function () { /* Set HDD temperature monitoring */ if (isNaN(this.settings.check_hdd_temp_interval)) { this.settings.check_hdd_temp_interval = 0; } else { this.monitor_hdd_temp(this.settings.check_hdd_temp_interval); } /* Set S.M.A.R.T. monitoring */ if (isNaN(this.settings.check_smart_interval)) { this.settings.check_smart_interval = 0; } else { this.monitor_hdd_smart(this.settings.check_smart_interval); } /* Set connected users monitoring */ if (isNaN(this.settings.check_users_online_interval)) { this.settings.check_users_online_interval = 0; } else { this.monitor_users_online(this.settings.check_users_online_interval); } }; /** * Show browser notification * * @param {string} title Notigication title * @param {object} options Notification options * @param {function} callback Callback function * * @returns {undefined} */ Application.prototype.notify = function (title, options, callback) { if (!("Notification" in window) || (Notification.permission.toLowerCase() === "denied")) { /* Notifications not supported or denied */ return; } if (Notification.permission === "granted") { // Notifications allowed var notification = new Notification(title, options); notification.onclick = callback;/* function () { console.log("notification clicked"); }; */ } else { // Trying to get permissions Notification.requestPermission(function (permission) { if (permission === "granted") { var notification = new Notification(title, options); } /*else { console.log("notifications prohibited"); } */ }); } }; /** * Register applications in menu * * @returns {undefined} */ Application.prototype.apps_register = function () { var m_menu = new MainMenu(this.lang); for (var key in this.apps_list) { if (this.apps_list.hasOwnProperty(key)) { m_menu.register_app(this, this.apps_list[key]); document.getElementById("div_menu_app").classList.remove("hidden"); } } }; /** * Load applications list * * @returns {undefined} */ Application.prototype.apps_list_load = function () { var app_instance = this; this.get_data("system/apps/apps.json") .then(function(result) { var json_data = JSON.parse(result); app_instance.apps_list = json_data; app_instance.apps_register(); }) .catch(function(result) { console_log("apps_list_load error:" + result); }); }; /** * Run widget * * @param {object} widget_info Widget description * * @returns {undefined} */ Application.prototype.widget_run = function (widget_info) { Object.size = function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; var w_index = Object.size(this.widgets); //this.widgets.length; this.widgets[w_index] = new Widget(this, widget_info); this.widgets[w_index].draw(this.widgets[w_index]); if (widget_info.type === this.OT_TABLE_H || widget_info.type === this.OT_TABLE_V) { this.widgets[w_index].update_table_data(this, w_index); if (widget_info.refresh > 0) { this.timers[widget_info.id] = setInterval(this.widgets[w_index].update_table_data, widget_info.refresh * 1000, this, w_index); } } else if (widget_info.type === this.OT_CANVAS) { this.widgets[w_index].update_canvas_data(this, w_index); if (widget_info.refresh > 0) { this.timers[widget_info.id] = setInterval(this.widgets[w_index].update_canvas_data, widget_info.refresh * 1000, this, w_index); } } }; /** * Draws application widgets * * @param {array} block_name Name of widgets block * * @returns {undefined} */ Application.prototype.widgets_run = function (block_name) { /* Open in new window if ctrl is pressed */ if (this.ctrl_on) { this.app_new_window(block_name); return; } if (typeof block_name === "undefined") { return; } this.cur_block = this.blocks_rotation.indexOf(block_name); var class_name = "div_widget", no_widgets = false; this.page_clear(); location.hash = block_name; this.widgets = {}; for (var i = 0; i < this.widgets_lists[block_name].length; i++) { no_widgets = false; if (this.widgets_lists[block_name][i].widget_css !== undefined) { /* Apply widget css */ no_widgets = true; class_name = this.widgets_lists[block_name][i].widget_css; } else if (this.widgets_lists[block_name][i].break !== undefined && this.widgets_lists[block_name][i].break === true) { /* Insert break */ var div_break = document.createElement("div"); div_break.className = "div_clear"; document.getElementById("page_content").appendChild(div_break); no_widgets = true; } if (this.widgets_lists[block_name][i].page_title !== undefined) { this.page_title_change(this.widgets_lists[block_name][i].page_title); no_widgets = true; } /* If widget info */ if (!no_widgets) { if (!this.settings.w_transmission_enabled && this.widgets_lists[block_name][i].id === "transmission_info") { /* Skip transmission widget if disabled */ } else { this.widget_run(this.widgets_lists[block_name][i]); /* Apply widget style class */ if (class_name !== "div_widget") { document.getElementById(this.widgets_lists[block_name][i].id).classList.remove("div_widget"); document.getElementById(this.widgets_lists[block_name][i].id).classList.add(class_name); } } } } }; /** * Show help * * @param {bool} about_info Show "About" info * * @returns {undefined} */ Application.prototype.help_show = function (about_info) { if (!this.ctrl_on) { this.page_clear(); } if (about_info) { this.app_widget_draw(this.w_about_iframe); } else { this.app_widget_draw(this.w_help_iframe); } }; /** * Show settings form * * @returns {undefined} */ Application.prototype.settings_show = function () { if (!this.ctrl_on) { this.page_clear(); } this.app_widget_draw(this.w_settings_iframe); }; /** * Shutdown server * * @param {bool} reboot Reboot system flag * * @returns {undefined} */ Application.prototype.shutdown = function (reboot) { if (reboot && window.confirm (this.lang.reboot_confirm)) { this.page_clear(); this.app_widget_draw(this.w_reboot_iframe); } else if (!reboot && window.confirm (this.lang.shutdown_confirm)) { this.page_clear(); this.app_widget_draw(this.w_shutdown_iframe); } }; /** * Main menu constructor * * @param {string} lang Language * * @returns {undefined} */ function MainMenu(lang) { this.main_menu = document.getElementById("div_menu"); this.info_menu = document.getElementById("div_menu_info"); this.app_menu = document.getElementById("div_menu_app"); this.settings_menu = document.getElementById("div_menu_settings"); this.lang = lang; } /** * Add icons block to menu * * @param {array} block_info Menu block information * * @returns {object} Menu block's div */ MainMenu.prototype.add_block = function (block_info) { var div_menu_block = document.createElement("div"), div_menu_block_caption = document.createElement("div"); div_menu_block.id = block_info.id; div_menu_block.classList.add("div_menu_block"); if (!block_info.visible) { div_menu_block.classList.add("hidden"); } this.main_menu.appendChild(div_menu_block); div_menu_block_caption.classList.add("div_menu_block_caption"); div_menu_block_caption.appendChild(document.createTextNode(block_info.caption)); div_menu_block.appendChild(div_menu_block_caption); if (block_info.separator) { div_menu_block.appendChild(document.createElement("hr")); } return div_menu_block; }; /** * Add menu item to menu block * * @param {object} parent_block Parent block for icon * @param {string} id Menu item id * @param {string} icon_src Path to icon file * @param {string} caption Menu caption * @param {bool} hidden Add menu in hidden state * @param {object} callback_function OnClick callback function * * @returns {undefined} */ MainMenu.prototype.add_item = function (parent_block, id, icon_src, caption, hidden, callback_function) { var m_item_div = document.createElement("div"), m_item_img = document.createElement("img"), m_item_footer_div = document.createElement("div"); m_item_div.id = "div_" + id; m_item_div.classList.add("div_m_item"); m_item_div.onclick = callback_function; /* m_item_div.addEventListener("contextmenu", function(e) { e.preventDefault(); }); */ if (hidden) { m_item_div.classList.add("hidden"); } m_item_img.classList.add("menu_icon"); m_item_img.src = icon_src; m_item_div.appendChild(m_item_img); m_item_footer_div.classList.add("div_m_item_footer"); m_item_footer_div.appendChild(document.createTextNode(caption)); m_item_div.appendChild(m_item_footer_div); parent_block.appendChild(m_item_div); }; /** * Build menu structure * * @param {object} menu_items menu structure * * @returns {undefined} */ MainMenu.prototype.build_menu = function (menu_items) { var div_ctrl_hint = document.createElement("div"); div_ctrl_hint.classList.add("top_right_hint"); div_ctrl_hint.appendChild(document.createTextNode(this.lang.ctrl_click_hint)); this.main_menu.appendChild(div_ctrl_hint); for (var menu_block in menu_items) { if (menu_items.hasOwnProperty(menu_block)) { var div_menu_block = this.add_block(menu_items[menu_block]); for (var menu_item in menu_items[menu_block].elements) { if (menu_items[menu_block].elements.hasOwnProperty(menu_item)) { this.add_item( div_menu_block, menu_item, menu_items[menu_block].elements[menu_item].icon, menu_items[menu_block].elements[menu_item].caption, false, menu_items[menu_block].elements[menu_item].callback ); } } var div_clear = document.createElement("div"); div_clear.classList.add("div_clear"); div_menu_block.appendChild(div_clear); this.main_menu.appendChild(div_menu_block); } } }; /** * Clear menu or submenu * * @param {object} menu Menu object to clear * * @returns {undefined} */ MainMenu.prototype.clear_menu = function (menu) { while (menu.firstChild) { menu.removeChild(menu.firstChild); } }; /** * Register application in menu * * @param {object} app_instance Application instance * @param {string} app_dir Directory containing app.json file with * application info * * @returns {undefined} */ MainMenu.prototype.register_app = function (app_instance, app_dir) { var menu_obj = this; app_instance.get_data("system/apps/" + app_dir + "/app.json") .then(function(result) { var json_data = JSON.parse(result), parent_block = document.getElementById("div_menu_app"), uri, app_iframe; switch (window.location.protocol) { case "https:": if (json_data.use_https && json_data.https_uri !== "") { if (json_data.frame_support) { uri = json_data.https_uri; /* run in frame */ app_iframe = { parent : "page_content", id : "iframe_" + json_data.app_name, type : app_instance.OT_IFRAME, label : json_data.caption, class_name : "app_widget", json_uri : uri.replace("[server_name]", window.location.hostname) }; menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { app_instance.app_widget_draw(app_iframe); } ); } else { menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { var uri = json_data.https_uri; window.open(uri.replace("[server_name]", window.location.hostname), "_blank"); } ); } } else if (json_data.use_http && json_data.http_uri !== "") { menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { var uri = json_data.http_uri; window.open(uri.replace("[server_name]", window.location.hostname), "_blank"); } ); } break; case "http:": if (json_data.use_http && json_data.http_uri !== "") { if (json_data.frame_support) { uri = json_data.http_uri; /* run in frame */ app_iframe = { parent : "page_content", id : "iframe_" + json_data.app_name, type : app_instance.OT_IFRAME, label : json_data.caption, class_name : "app_widget", json_uri : uri.replace("[server_name]", window.location.hostname) }; menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { app_instance.app_widget_draw(app_iframe); } ); } else { menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { var uri = json_data.http_uri; window.open(uri.replace("[server_name]", window.location.hostname), "_blank"); } ); } } else if (json_data.use_https && json_data.https_uri !== "") { menu_obj.add_item(parent_block, "menu_" + json_data.app_name, "system/apps/" + app_dir + "/icon.png", json_data.caption, json_data.exec !== "", function () { var uri = json_data.https_uri; window.open(uri.replace("[server_name]", window.location.hostname), "_blank"); } ); } break; } for (var i = 0; i < json_data.require.length; i++) { app_instance.app_remove_unexisted(json_data.app_name, json_data.require[i].data); } }) .catch(function(result) { console_log("register_app error: " + result); }); }; /** * Widgets constructor * * @param {object} caller Caller object * @param {array} w_info Array with Widget information * @param {string} w_data Widget data * * @returns {undefined} */ function Widget(caller, w_info, w_data) { this.parent_app = caller; this.info = w_info; this.data = w_data || null; this.parent_el = document.getElementById(w_info.parent); /* Double tap on header handler vars */ this.dt_hdr_timeout = null; this.dt_hdr_tap_time = 0; } /** * Toggle maximized widget state * * @returns {undefined} */ Widget.prototype.toggle_maximized = function () { var parent_node = document.getElementById(this.parentNode.id); if (parent_node.classList.contains("canvas_info")) { return; } document.getElementById(this.parentNode.id).classList.toggle("div_maximized"); for (var i = 0; i < parent_node.childNodes.length; i++) { if (parent_node.childNodes[i].classList.contains("div_w_content_container")) { parent_node.childNodes[i].classList.toggle("div_maximized_content"); } } }; /** * Draw widget * * @returns {undefined} */ Widget.prototype.draw = function () { var widget_instance = this, widget_node, widget_c_container; if (document.getElementById(this.info.id) !== null) { widget_node = document.getElementById(this.info.id); widget_c_container = widget_node.childNodes[1]; widget_c_container.removeChild(widget_c_container.childNodes[0]); } else { var widget_head = document.createElement("div"); widget_node = document.createElement("div"); widget_node.classList.add("div_widget"); if (this.parent_app.settings.dim_on_create) { widget_node.classList.add("slightly_visible"); } widget_node.id = this.info.id; if (this.info.class_name !== "") { widget_node.classList.add(this.info.class_name); } widget_head.classList.add("div_w_head"); widget_head.appendChild(document.createTextNode(this.info.label)); widget_head.addEventListener("dblclick", this.toggle_maximized); /* Add double tap event */ widget_head.addEventListener("touchend", function(event) { var cur_time = new Date().getTime(), tap_len = cur_time - this.dt_hdr_tap_time; clearTimeout(widget_instance.dt_hdr_timeout); if (tap_len < 500 && tap_len > 0) { event.preventDefault(); widget_instance.toggle_maximized(); } else { widget_instance.dt_hdr_timeout = setTimeout(function() { clearTimeout(widget_instance.dt_hdr_timeout); }, 500); } widget_instance.dt_hdr_tap_time = cur_time; }); widget_c_container = document.createElement("div"); widget_c_container.classList.add("div_w_content_container"); widget_node.appendChild(widget_head); widget_node.appendChild(widget_c_container); this.parent_el.appendChild(widget_node); } var widget_content = document.createElement("div"); widget_content.classList.add("div_w_content"); widget_c_container.appendChild(widget_content); switch (this.info.type) { case this.parent_app.OT_TABLE_H: case this.parent_app.OT_TABLE_V: var table_node = this.html_table(this.info.type === this.parent_app.OT_TABLE_V); if (this.info.class_name !== "") { table_node.classList.add(this.info.class_name); } widget_content.appendChild(table_node); break; case this.parent_app.OT_IFRAME: var iframe_node = document.createElement("iframe"); iframe_node.src = this.info.json_uri; widget_content.appendChild(iframe_node); break; case this.parent_app.OT_CANVAS: var canvas_node = document.createElement("canvas"), s_settings = {interpolation: this.info.interpolation, //interpolation : "linear", //interpolation : "step", grid : {sharpLines : true, borderVisible : false, verticalSections : 4, millisPerLine : 10000}, labels : {disabled : false}, timestampFormatter : SmoothieChart.timeFormatter, millisPerPixel : 100 //tooltip : true }; canvas_node.id = "canvas_" + this.info.id; canvas_node.width = 400; canvas_node.height = 154; widget_content.appendChild(canvas_node); if (this.info.max_val !== "auto") { s_settings.maxValue = this.info.max_val; } if (this.info.min_val !== "auto") { s_settings.minValue = this.info.min_val; } this.smoothie = new SmoothieChart(s_settings); this.lines = []; this.smoothie.streamTo(document.getElementById(canvas_node.id), this.info.refresh * 1000); } }; /** * Fill table headers * * @param {object} table Parent table * * @returns {object} */ Widget.prototype.fill_table_headers = function (table) { var col_set = []; if (this.data !== null) { var tr = document.createElement("tr"); for (var i = 0, l = this.data.length; i < l; i++) { for (var key in this.data[i]) { if (this.data[i].hasOwnProperty(key) && col_set.indexOf(key) === -1) { col_set.push(key); var th = document.createElement("th"); th.appendChild(document.createTextNode(key)); tr.appendChild(th); } } } table.appendChild(tr); } return col_set; }; /** * Return HTML table filled with data * * @returns {object} */ Widget.prototype.html_table = function () { var table = document.createElement("table"), tr; if (this.data !== null) { if (this.info.type === this.parent_app.OT_TABLE_V) { var even_line = false; for (var key in this.data[0]) { if (this.data[0].hasOwnProperty(key)) { var td_key = document.createElement("td"), td_val = document.createElement("td"); tr = document.createElement("tr"); td_key.appendChild(document.createTextNode(key)); td_key.classList.add("table_header"); if (this.info.raw_num) { td_val.appendChild(document.createTextNode(this.data[0][key] || "")); } else { td_val.appendChild( document.createTextNode( numFormatted(this.data[0][key], "'") || "" ) ); } tr.appendChild(td_key); tr.appendChild(td_val); if (even_line) { tr.classList.add("even_line"); } even_line = !even_line; table.appendChild(tr); } } } else { var columns = this.fill_table_headers(table); for (var i = 0, max_i = this.data.length; i < max_i; ++i) { tr = document.createElement("tr"); for (var j = 0, max_j = columns.length; j < max_j ; ++j) { var td = document.createElement("td"); if (this.info.raw_num) { td.appendChild( document.createTextNode( this.data[i][columns[j]] || "" ) ); } else { td.appendChild( document.createTextNode( numFormatted(this.data[i][columns[j]], "'") || "" ) ); } tr.appendChild(td); } if (i % 2 !== 0) { tr.classList.add("even_line"); } table.appendChild(tr); } } } return table; }; /** * Update canvas widget data * * @param {object} app_instance Application object instance * @param {numeric} index Widget index * * @returns {undefined} */ Widget.prototype.update_canvas_data = function (app_instance, index) { var w_instance = app_instance.widgets[index], colors = [ ["rgb(0, 255, 0)", "rgba(0, 255, 0, 0.4)"], // green ["rgb(255, 0, 0)", "rgba(255, 0, 0, 0.4)"], // red ["rgb(255, 255, 0)", "rgba(255, 255, 0, 0.4)"], // yellow ["rgb(0, 255, 255)", "rgba(0, 255, 255, 0.4)"], ["rgb(0, 0, 255)", "rgba(0, 0, 255, 0.4)"], // blue ["rgb(255, 255, 255)", "rgba(255, 255, 255, 0.4)"], ["rgb(128, 255, 255)", "rgba(128, 255, 255, 0.4)"], ["rgb(255, 128, 255)", "rgba(255, 128, 255, 0.4)"], ["rgb(255, 255, 128)", "rgba(255, 255, 128, 0.4)"], ["rgb(128, 128, 255)", "rgba(128, 128, 255, 0.4)"], ["rgb(255, 128, 128)", "rgba(255, 128, 128, 0.4)"], ["rgb(128, 255, 128)", "rgba(128, 255, 128, 0.4)"], ["rgb(0, 128, 255)", "rgba(0, 128, 255, 0.4)"], ["rgb(255, 0, 128)", "rgba(255, 0, 128, 0.4)"], ["rgb(128, 255, 0)", "rgba(128, 255, 0, 0.4)"], ["rgb(0, 0, 128)", "rgba(0, 0, 128, 0.4)"] ]; app_instance.get_data(w_instance.info.json_uri) .then(function(result) { var json_data = JSON.parse(result), i = 0; if (document.getElementById(w_instance.info.id) === null) { return; } var content_container = document.getElementById(w_instance.info.id).children[1], div_legend; for (var key in json_data) { if (json_data.hasOwnProperty(key)) { if (w_instance.lines.length < i + 1) { div_legend = document.createElement("div"); div_legend.id = w_instance.info.id + "_" + key; div_legend.style.color = colors[i][0]; div_legend.classList.add("canvas_legend"); div_legend.appendChild(document.createTextNode (key)); content_container.appendChild(div_legend); w_instance.lines.push(new TimeSeries()); w_instance.smoothie.addTimeSeries( w_instance.lines[i], {strokeStyle : colors[i][0], fillStyle : colors[i][1], lineWidth : 3} ); } else { div_legend = document.getElementById( w_instance.info.id + "_" + key ); if (div_legend === null) { return; } } div_legend.textContent = key + ": " + json_data[key] + w_instance.info.measure; div_legend.classList.remove("slightly_visible"); w_instance.lines[i].append(new Date().getTime(), Math.floor(json_data[key])); document.getElementById(w_instance.info.id).classList.remove("slightly_visible"); i++; } } }) .catch(function(result) { console_log("update_canvas_data error: " + result); }); }; /** * Draw table widget * * @param {object} app_instance Application object instance * @param {numeric} index Widget index * * @returns {undefined} */ Widget.prototype.update_table_data = function (app_instance, index) { var w_instance = app_instance.widgets[index]; app_instance.get_data(w_instance.info.json_uri) .then(function(result) { var json_data = JSON.parse(result); if (document.getElementById(w_instance.info.id) !== null) { w_instance.data = json_data; w_instance.draw(); document.getElementById(w_instance.info.id).classList.remove("slightly_visible"); } }) .catch(function(result) { console_log("update_table_data error: " + result); }); }; document.addEventListener("DOMContentLoaded", function () { /** * Initialize application object */ var app = new Application(); }); }());