First Bjorn Commit !

This commit is contained in:
Fabien POLLY
2024-11-07 16:39:14 +01:00
parent 10ffdfa103
commit 5724ce6bb6
232 changed files with 12441 additions and 385 deletions

292
web/scripts/config.js Normal file
View File

@@ -0,0 +1,292 @@
function generateConfigForm(config) {
const formElement = document.querySelector(".config-form");
formElement.innerHTML = ''; // Clear the form
const leftColumn = document.createElement('div');
leftColumn.classList.add('left-column');
const rightColumn = document.createElement('div');
rightColumn.classList.add('right-column');
for (const [key, value] of Object.entries(config)) {
if (key.startsWith("__title_")) {
rightColumn.innerHTML += `<div class="section-title"><b>${value}</b></div>`;
} else if (typeof value === "boolean") {
const checked = value ? "checked" : "";
leftColumn.innerHTML += `
<div class="label-switch">
<label class="switch">
<input type="checkbox" id="${key}" name="${key}" ${checked}>
<span class="slider round"></span>
</label>
<label for="${key}">${key}</label>
</div>
`;
} else if (Array.isArray(value)) {
const listValue = value.join(',');
rightColumn.innerHTML += `
<div class="section-item">
<label for="${key}">${key}:</label>
<input type="text" id="${key}" name="${key}" value="${listValue}">
</div>
`;
} else if (!isNaN(value) && !key.toLowerCase().includes("ip") && !key.toLowerCase().includes("mac")) {
rightColumn.innerHTML += `
<div class="section-item">
<label for="${key}">${key}:</label>
<input type="number" id="${key}" name="${key}" value="${value}">
</div>
`;
} else {
rightColumn.innerHTML += `
<div class="section-item">
<label for="${key}">${key}:</label>
<input type="text" id="${key}" name="${key}" value="${value}">
</div>
`;
}
}
formElement.appendChild(leftColumn);
formElement.appendChild(rightColumn);
// Add a spacer div at the end for better scrolling experience
formElement.innerHTML += '<div style="height: 50px;"></div>';
}
function saveConfig() {
console.log("Saving configuration...");
const formElement = document.querySelector(".config-form");
if (!formElement) {
console.error("Form element not found.");
return;
}
const formData = new FormData(formElement);
const formDataObj = {};
formData.forEach((value, key) => {
if (value.includes(',')) {
formDataObj[key] = value.split(',').map(item => {
const trimmedItem = item.trim();
return isNaN(trimmedItem) ? trimmedItem : parseFloat(trimmedItem);
});
} else {
formDataObj[key] = value === 'on' ? true : (isNaN(value) ? value : parseFloat(value));
}
});
formElement.querySelectorAll('input[type="checkbox"]').forEach((checkbox) => {
if (!formData.has(checkbox.name)) {
formDataObj[checkbox.name] = false;
}
});
console.log("Form data:", formDataObj);
const xhr = new XMLHttpRequest();
xhr.open("POST", "/save_config", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
console.log("Response status: " + xhr.status);
if (xhr.status == 200) {
loadConfig();
} else {
console.error("Failed to save configuration");
alert("Failed to save configuration");
}
}
};
xhr.send(JSON.stringify(formDataObj));
}
function restoreDefault() {
fetch('/restore_default_config').then(response => response.json()).then(data => {
generateConfigForm(data);
});
}
function loadConfig() {
fetch('/load_config').then(response => response.json()).then(data => {
generateConfigForm(data);
});
}
function toggleWifiPanel() {
let wifiPanel = document.getElementById('wifi-panel');
if (wifiPanel.style.display === 'block') {
clearInterval(wifiIntervalId);
wifiPanel.style.display = 'none';
} else {
scanWifi(true); // Pass true to start the update interval
}
}
function closeWifiPanel() {
clearInterval(wifiIntervalId);
let wifiPanel = document.getElementById('wifi-panel');
wifiPanel.style.display = 'none';
}
let wifiIntervalId;
function scanWifi(update = false) {
fetch('/scan_wifi')
.then(response => response.json())
.then(data => {
console.log("Current SSID:", data.current_ssid); // Debugging
let wifiPanel = document.getElementById('wifi-panel');
let wifiList = document.getElementById('wifi-list');
wifiList.innerHTML = '';
data.networks.forEach(network => {
let li = document.createElement('li');
li.innerText = network;
li.setAttribute('data-ssid', network);
li.onclick = () => connectWifi(network);
if (network === data.current_ssid) {
li.classList.add('current-wifi'); // Apply the class if it's the current SSID
li.innerText += " ✅"; // Add the checkmark icon
}
wifiList.appendChild(li);
});
if (data.networks.length > 0) {
wifiPanel.style.display = 'block';
if (update) {
clearInterval(wifiIntervalId);
wifiIntervalId = setInterval(() => scanWifi(true), 5000);
}
}
})
.catch(error => {
console.error('Error:', error);
});
}
function connectWifi(ssid) {
let password = prompt("Enter the password for " + ssid);
if (password) {
fetch('/connect_wifi', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ ssid: ssid, password: password }),
})
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Error: ' + error));
}
}
function adjustFormPadding() {
const toolbarHeight = document.querySelector('.toolbar').offsetHeight;
const formElement = document.querySelector('.config-form');
formElement.style.paddingBottom = toolbarHeight + 'px';
}
window.addEventListener('load', () => {
adjustFormPadding();
});
window.addEventListener('resize', () => {
adjustFormPadding();
}); // Adjust size on window resize
document.addEventListener("DOMContentLoaded", function() {
loadConfig();
});
let fontSize = 12;
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile devices
}
function adjustConfigFontSize(change) {
fontSize += change;
// Retrieve all elements with the class 'section-item'
var sectionItems = document.getElementsByClassName('section-item');
// Loop through each element and apply the style
for (var i = 0; i < sectionItems.length; i++) {
// Apply the style to the section element
sectionItems[i].style.fontSize = fontSize + 'px';
// Retrieve all inputs inside this section element
var inputs = sectionItems[i].getElementsByTagName('input');
// Loop through each input and apply the style
for (var j = 0; j < inputs.length; j++) {
inputs[j].style.fontSize = fontSize + 'px';
}
// Retrieve all elements with the class 'switch' inside this section element
var switches = sectionItems[i].getElementsByClassName('switch');
// Loop through each switch and apply the style
for (var k = 0; k < switches.length; k++) {
switches[k].style.fontSize = fontSize + 'px';
}
// Retrieve all elements with the class 'slider round' inside this section element
var sliders = sectionItems[i].getElementsByClassName('slider round');
// Loop through each slider and apply the style
for (var l = 0; l < sliders.length; l++) {
sliders[l].style.width = fontSize * 2 + 'px'; // Adjust width based on fontSize
sliders[l].style.height = fontSize + 'px'; // Adjust height based on fontSize
sliders[l].style.borderRadius = fontSize / 2 + 'px'; // Adjust border-radius based on fontSize
}
}
// Retrieve all elements with the class 'section-title'
var sectionTitles = document.getElementsByClassName('section-title');
// Loop through each element and apply the style
for (var i = 0; i < sectionTitles.length; i++) {
sectionTitles[i].style.fontSize = fontSize + 'px';
}
// Retrieve all elements with the class 'label-switch'
var labelSwitches = document.getElementsByClassName('label-switch');
// Loop through each element and apply the style
for (var i = 0; i < labelSwitches.length; i++) {
labelSwitches[i].style.fontSize = fontSize + 'px';
}
// Apply the style to the element with the class 'config-form'
document.querySelector('.config-form').style.fontSize = fontSize + 'px';
}
function toggleConfigToolbar() {
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar')
const toggleIcon = document.getElementById('toggle-icon');
if (mainToolbar.classList.contains('hidden')) {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'false');
} else {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'true');
}
}

View File

@@ -0,0 +1,51 @@
let fontSize = 12;
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile
}
function fetchCredentials() {
fetch('/list_credentials')
.then(response => response.text())
.then(data => {
document.getElementById('credentials-table').innerHTML = data;
})
.catch(error => {
console.error('Error:', error);
});
}
document.addEventListener("DOMContentLoaded", function() {
fetchCredentials();
setInterval(fetchCredentials, 20000); // 20000 ms = 20 seconds
});
function adjustCredFontSize(change) {
fontSize += change;
document.getElementById('credentials-table').style.fontSize = fontSize + 'px';
}
function toggleCredToolbar() {
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar')
const toggleIcon = document.getElementById('toggle-icon');
if (mainToolbar.classList.contains('hidden')) {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'false');
} else {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'true');
}
}
document.addEventListener("DOMContentLoaded", function() {
fetchCredentials(); // Initial fetch
setInterval(fetchCredentials, 10000); // Refresh every 10 seconds
});

399
web/scripts/index.js Normal file
View File

@@ -0,0 +1,399 @@
const logConsole = document.getElementById('log-console');
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar');
let fontSize = 16; // size for desktop
const maxLines = 2000; // Number of lines to keep in the console
const fileColors = new Map();
const levelClasses = {
"DEBUG": "debug",
"INFO": "info",
"WARNING": "warning",
"ERROR": "error",
"CRITICAL": "critical",
"SUCCESS": "success"
};
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile
}
logConsole.style.fontSize = fontSize + 'px';
function getRandomColor() {
const letters = '89ABCDEF'; // Using only hex value for lighter colors
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * letters.length)];
}
return color;
}
let logInterval;
let isConsoleOn = false;
function fetchLogs() {
fetch('/get_logs')
.then(response => response.text())
.then(data => {
const lines = data.split('\n');
const newContent = [];
lines.forEach(line => {
let modifiedLine = line;
const regexFile = /(\w+\.py)/g;
let matchFile;
while ((matchFile = regexFile.exec(line)) !== null) {
const fileName = matchFile[1];
if (line.includes('==>') || line.includes('<=='))
return;
if (!fileColors.has(fileName)) {
fileColors.set(fileName, getRandomColor());
}
modifiedLine = modifiedLine.replace(fileName, `<span style="color: ${fileColors.get(fileName)};">${fileName}</span>`);
}
const regexLevel = /\b(DEBUG|INFO|WARNING|ERROR|CRITICAL|SUCCESS)\b/g;
modifiedLine = modifiedLine.replace(regexLevel, (match) => {
return `<span class="${levelClasses[match]}">${match}</span>`;
});
const regexLineNumber = /^\d+/;
modifiedLine = modifiedLine.replace(regexLineNumber, (match) => {
return `<span class="line-number">${match}</span>`;
});
const regexNumbers = /\b\d+\b/g;
modifiedLine = modifiedLine.replace(regexNumbers, (match) => {
return `<span class="number">${match}</span>`;
});
newContent.push(modifiedLine);
});
logConsole.innerHTML += newContent.join('<br>') + '<br>';
let allLines = logConsole.innerHTML.split('<br>');
if (allLines.length > maxLines) {
allLines = allLines.slice(allLines.length - maxLines);
logConsole.innerHTML = allLines.join('<br>');
}
logConsole.scrollTop = logConsole.scrollHeight;
})
.catch(error => console.error('Error fetching logs:', error));
}
// setInterval(fetchLogs, 1500); /
function startConsole() {
// Start fetching logs every 1.5 seconds
logInterval = setInterval(fetchLogs, 1500); // Fetch logs every 1.5 seconds
}
function stopConsole() {
clearInterval(logInterval);
}
function toggleConsole() {
const toggleImage = document.getElementById('toggle-console-image');
if (isConsoleOn) {
stopConsole();
toggleImage.src = '/web/images/off.png';
} else {
startConsole();
toggleImage.src = '/web/images/on.png';
}
isConsoleOn = !isConsoleOn;
}
function adjustFontSize(change) {
fontSize += change;
logConsole.style.fontSize = fontSize + 'px';
}
document.addEventListener('DOMContentLoaded', () => {
const mainToolbar = document.getElementById('mainToolbar');
const toggleButton = document.getElementById('toggle-toolbar');
const toggleIcon = document.getElementById('toggle-icon');
toggleButton.addEventListener('click', toggleToolbar);
function toggleToolbar() {
const isOpen = toggleButton.getAttribute('data-open') === 'true';
if (isOpen) {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'false');
} else {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'true');
}
toggleConsoleSize();
}
function toggleConsoleSize() {
//Function to adjust the size of the console based on the toolbar visibility
}
});
function loadDropdown() {
const dropdownContent = `
<div class="dropdown">
<button type="button" class="toolbar-button" onclick="toggleDropdown()" data-open="false">
<img src="/web/images/manual_icon.png" alt="Icon_actions" style="height: 50px;">
</button>
<div class="dropdown-content">
<button type="button" onclick="clear_files()">Clear Files</button>
<button type="button" onclick="clear_files_light()">Clear Files Light</button>
<button type="button" onclick="reboot_system()">Reboot</button>
<button type="button" onclick="disconnect_wifi()">Disconnect Wi-Fi</button>
<button type="button" onclick="shutdown_system()">Shutdown</button>
<button type="button" onclick="restart_bjorn_service()">Restart Bjorn Service</button>
<button type="button" onclick="backup_data()">Backup</button>
<button type="button" onclick="restore_data()">Restore</button>
<button type="button" onclick="stop_orchestrator()">Stop Orchestrator</button>
<button type="button" onclick="start_orchestrator()">Start Orchestrator</button>
<button type="button" onclick="initialize_csv()">Create Livestatus, Actions & Netkb CSVs</button>
</div>
</div>
`;
document.getElementById('dropdown-container').innerHTML = dropdownContent;
}
function loadBjornDropdown() {
const bjornDropdownContent = `
<div class="dropdown bjorn-dropdown">
<button type="button" class="toolbar-button" onclick="toggleBjornDropdown()" data-open="false">
<img src="/web/images/bjorn_icon.png" alt="Icon_bjorn" style="height: 50px;">
</button>
<div class="dropdown-content">
<img id="screenImage_Home" onclick="window.location.href='/bjorn.html'" src="screen.png" alt="Bjorn" style="width: 100%;">
</div>
</div>
`;
document.getElementById('bjorn-dropdown-container').innerHTML = bjornDropdownContent;
startLiveview(); // Start live view when Bjorn dropdown is loaded
}
// Call the function to load the dropdowns when the DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
loadDropdown();
loadBjornDropdown();
});
function clear_files() {
fetch('/clear_files', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to clear files: ' + error.message));
}
function clear_files_light() {
fetch('/clear_files_light', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to clear files: ' + error.message));
}
function reboot_system() {
fetch('/reboot', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to reboot: ' + error.message));
}
function shutdown_system() {
fetch('/shutdown', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to shutdown: ' + error.message));
}
function restart_bjorn_service() {
fetch('/restart_bjorn_service', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to restart service: ' + error.message));
}
function backup_data() {
fetch('/backup', { method: 'POST' })
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
const link = document.createElement('a');
link.href = data.url;
link.download = data.filename;
link.click();
alert('Backup completed successfully');
} else {
alert('Backup failed: ' + data.message);
}
})
.catch(error => alert('Backup failed: ' + error.message));
}
function restore_data() {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.zip';
input.onchange = () => {
const file = input.files[0];
const formData = new FormData();
formData.append('file', file);
fetch('/restore', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Restore failed: ' + error.message));
};
input.click();
}
function stop_orchestrator() {
fetch('/stop_orchestrator', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to stop orchestrator: ' + error.message));
}
function start_orchestrator() {
fetch('/start_orchestrator', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to start orchestrator: ' + error.message));
}
function disconnect_wifi() {
fetch('/disconnect_wifi', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to disconnect: ' + error.message));
}
function initialize_csv() {
fetch('/initialize_csv', { method: 'POST' })
.then(response => response.json())
.then(data => alert(data.message))
.catch(error => alert('Failed to initialize CSV: ' + error.message));
}
// Dropdown toggle logic
function toggleDropdown() {
const dropdown = document.querySelector('.dropdown');
const button = document.querySelector('.action-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
} else {
dropdown.classList.add('show');
button.setAttribute('data-open', 'true');
}
}
function closeDropdownIfOpen(event) {
const dropdown = document.querySelector('.dropdown');
const button = document.querySelector('.action-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (!event.target.closest('.dropdown') && isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
}
}
// actions.js
let imageIntervalId;
let intervalId;
const delay = 2000 // Adjust this value to match your delay
let lastUpdate = 0;
function updateImage() {
const now = Date.now();
if (now - lastUpdate >= delay) {
lastUpdate = now;
const image = document.getElementById("screenImage_Home");
const newImage = new Image();
newImage.onload = function() {
image.src = newImage.src; // Update only if the new image loads successfully
};
newImage.onerror = function() {
console.warn("New image could not be loaded, keeping the previous image.");
};
newImage.src = "screen.png?t=" + new Date().getTime(); // Prevent caching
}
}
function startLiveview() {
updateImage(); // Immediately update the image
intervalId = setInterval(updateImage, delay); // Then update at the specified interval
}
function stopLiveview() {
clearInterval(intervalId);
}
// Dropdown toggle logic for Bjorn
function toggleBjornDropdown() {
const dropdown = document.querySelector('.bjorn-dropdown');
const button = document.querySelector('.bjorn-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
stopLiveview(); // Stop image refresh when closing
} else {
dropdown.classList.add('show');
button.setAttribute('data-open', 'true');
startLiveview(); // Start image refresh when opening
}
}
function closeBjornDropdownIfOpen(event) {
const dropdown = document.querySelector('.bjorn-dropdown');
const button = document.querySelector('.bjorn-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (!event.target.closest('.bjorn-dropdown') && isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
stopLiveview(); // Stop image refresh when closing
}
}
document.addEventListener('click', closeBjornDropdownIfOpen);
document.addEventListener('touchstart', closeBjornDropdownIfOpen);
// Existing logic for Actions dropdown
function toggleDropdown() {
const dropdown = document.querySelector('.dropdown');
const button = document.querySelector('.action-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
} else {
dropdown.classList.add('show');
button.setAttribute('data-open', 'true');
}
}
function closeDropdownIfOpen(event) {
const dropdown = document.querySelector('.dropdown');
const button = document.querySelector('.action-button');
const isOpen = button.getAttribute('data-open') === 'true';
if (!event.target.closest('.dropdown') && isOpen) {
dropdown.classList.remove('show');
button.setAttribute('data-open', 'false');
}
}

75
web/scripts/loot.js Normal file
View File

@@ -0,0 +1,75 @@
let fontSize = 14;
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile
}
document.addEventListener("DOMContentLoaded", function() {
fetch('/list_files')
.then(response => response.json())
.then(data => {
document.getElementById('file-list').innerHTML = generateFileListHTML(data, "/", 0);
})
.catch(error => {
console.error('Error:', error);
});
});
function generateFileListHTML(files, path, indent) {
let html = '<ul>';
files.forEach(file => {
if (file.is_directory) {
const icon = path === "/" ? "web/images/mainfolder.png" : "web/images/subfolder.png";
html += `
<li style="margin-left: ${indent * 5}px;">
<img src="${icon}" alt="Folder Icon" style="height: 20px;">
<strong>${file.name}</strong>
<ul>
${generateFileListHTML(file.children || [], `${path}/${file.name}`, indent + 1)}
</ul>
</li>`;
} else {
const icon = "web/images/file.png";
html += `
<li style="margin-left: ${indent * 5}px;">
<img src="${icon}" alt="File Icon" style="height: 20px;">
<a href="/download_file?path=${encodeURIComponent(file.path)}">${file.name}</a>
</li>`;
}
});
html += '</ul>';
return html;
}
function adjustLootFontSize(change) {
fontSize += change;
document.getElementById('file-list').style.fontSize = fontSize + 'px';
}
function toggleLootToolbar() {
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar');
const toggleIcon = document.getElementById('toggle-icon');
if (mainToolbar.classList.contains('hidden')) {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'false');
} else {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'true');
}
}
document.addEventListener("DOMContentLoaded", function() {
setInterval(() => {
fetch('/list_files')
.then(response => response.json())
.then(data => {
document.getElementById('file-list').innerHTML = generateFileListHTML(data, "/", 0);
})
.catch(error => {
console.error('Error:', error);
});
}, 10000); // Refresh every 10 seconds
});

45
web/scripts/netkb.js Normal file
View File

@@ -0,0 +1,45 @@
let fontSize = 12;
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile
}
function fetchNetkbData() {
fetch('/netkb_data')
.then(response => response.text())
.then(data => {
document.getElementById('netkb-table').innerHTML = data;
})
.catch(error => {
console.error('Error:', error);
});
}
function adjustNetkbFontSize(change) {
fontSize += change;
document.getElementById('netkb-table').style.fontSize = fontSize + 'px';
}
function toggleNetkbToolbar() {
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar')
const toggleIcon = document.getElementById('toggle-icon');
if (mainToolbar.classList.contains('hidden')) {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'false');
} else {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'true');
}
}
document.addEventListener("DOMContentLoaded", function() {
fetchNetkbData(); // Initial fetch
setInterval(fetchNetkbData, 10000); // Refresh every 10 seconds
});

47
web/scripts/network.js Normal file
View File

@@ -0,0 +1,47 @@
let fontSize = 12;
// Adjust font size based on device type
if (/Mobi|Android/i.test(navigator.userAgent)) {
fontSize = 7; // size for mobile
}
function fetchNetworkData() {
fetch('/network_data')
.then(response => response.text())
.then(data => {
document.getElementById('network-table').innerHTML = data;
})
.catch(error => {
console.error('Error:', error);
});
}
function adjustNetworkFontSize(change) {
fontSize += change;
document.getElementById('network-table').style.fontSize = fontSize + 'px';
}
function toggleNetworkToolbar() {
const mainToolbar = document.querySelector('.toolbar');
const toggleButton = document.getElementById('toggle-toolbar');
const toggleIcon = document.getElementById('toggle-icon');
if (mainToolbar.classList.contains('hidden')) {
mainToolbar.classList.remove('hidden');
toggleIcon.src = '/web/images/hide.png';
toggleButton.setAttribute('data-open', 'true');
} else {
mainToolbar.classList.add('hidden');
toggleIcon.src = '/web/images/reveal.png';
toggleButton.setAttribute('data-open', 'false');
}
}
document.addEventListener("DOMContentLoaded", function() {
fetchNetworkData(); // Initial fetch
setInterval(fetchNetworkData, 60000); // Refresh every 60 seconds
});