add support for some samsung drives
This commit is contained in:
@ -51,9 +51,9 @@ sector_size: "512"
|
|||||||
sleep_time: "5"
|
sleep_time: "5"
|
||||||
install_kiosk: false
|
install_kiosk: false
|
||||||
quick_refresh: false
|
quick_refresh: false
|
||||||
service_only: false
|
service_only: true
|
||||||
armcpu_check: false
|
armcpu_check: false
|
||||||
service_mode: false
|
service_mode: true
|
||||||
install_docker: true
|
install_docker: true
|
||||||
|
|
||||||
...
|
...
|
||||||
@ -37,29 +37,26 @@ function fetchSSDData() {
|
|||||||
Search for disk:<br>
|
Search for disk:<br>
|
||||||
<input id="search" type="text" placeholder="Search by ID, model, serial…" /><p>
|
<input id="search" type="text" placeholder="Search by ID, model, serial…" /><p>
|
||||||
<?php
|
<?php
|
||||||
$ssdData = fetchSSDData(); // Fetch data from the API
|
$ssdData = fetchSSDData();
|
||||||
// Start the table
|
|
||||||
echo '<table class="ssd-list" style="border-collapse:collapse;width:100%;">';
|
echo '<table class="ssd-list" style="border-collapse:collapse;width:100%;">';
|
||||||
// Table header (optional but handy)
|
|
||||||
echo '<thead>
|
echo '<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Disk ID</th>
|
<th data-sort="id">Disk ID</th>
|
||||||
<th>Model String</th>
|
<th data-sort="model">Model String</th>
|
||||||
<th>Serial Number</th>
|
<th data-sort="serial">Serial Number</th>
|
||||||
<th>GB Written</th>
|
<th data-sort="gb_written">GB Written</th>
|
||||||
<th>Disk Capacity</th>
|
<th data-sort="capacity">Disk Capacity</th>
|
||||||
<th>Disk Flavor</th>
|
<th data-sort="flavor">Disk Flavor</th>
|
||||||
<th>SMART Result</th>
|
<th data-sort="smart">SMART Result</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>';
|
</thead>';
|
||||||
// Table body - one row per SSD
|
|
||||||
echo '<tbody id="ssd-body">';
|
echo '<tbody id="ssd-body">';
|
||||||
foreach ($ssdData as $ssd) {
|
foreach ($ssdData as $ssd) {
|
||||||
// Escape the values so the page stays safe
|
// Escape the values so the page stays safe
|
||||||
$id = htmlspecialchars($ssd['id']);
|
$id = htmlspecialchars($ssd['id']);
|
||||||
$model = htmlspecialchars($ssd['model']);
|
$model = htmlspecialchars($ssd['model']);
|
||||||
$serial = htmlspecialchars($ssd['serial']);
|
$serial = htmlspecialchars($ssd['serial']);
|
||||||
$tbw = htmlspecialchars($ssd['gb_written']);
|
$gbw = htmlspecialchars($ssd['gb_written']);
|
||||||
$cap = htmlspecialchars($ssd['capacity']);
|
$cap = htmlspecialchars($ssd['capacity']);
|
||||||
$flavor = htmlspecialchars($ssd['flavor']);
|
$flavor = htmlspecialchars($ssd['flavor']);
|
||||||
$smart = htmlspecialchars($ssd['smart']);
|
$smart = htmlspecialchars($ssd['smart']);
|
||||||
@ -68,7 +65,7 @@ function fetchSSDData() {
|
|||||||
<td>{$id}</td>
|
<td>{$id}</td>
|
||||||
<td>{$model}</td>
|
<td>{$model}</td>
|
||||||
<td>{$serial}</td>
|
<td>{$serial}</td>
|
||||||
<td>{$tbw}</td>
|
<td>{$gbw}</td>
|
||||||
<td>{$cap}</td>
|
<td>{$cap}</td>
|
||||||
<td>{$flavor}</td>
|
<td>{$flavor}</td>
|
||||||
<td>{$smart}</td>
|
<td>{$smart}</td>
|
||||||
@ -112,4 +109,82 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
|
/* ----- Search filter ----- */
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
const tbody = document.getElementById('ssd-body');
|
||||||
|
const rowsSnapshot = Array.from(tbody.rows); // keep a static snapshot
|
||||||
|
|
||||||
|
const debounce = (fn, delay) => {
|
||||||
|
let timer;
|
||||||
|
return (...args) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(() => fn.apply(this, args), delay);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const filterRows = debounce(() => {
|
||||||
|
const q = searchInput.value.trim().toLowerCase();
|
||||||
|
rowsSnapshot.forEach(r => {
|
||||||
|
const rowText = Array.from(r.cells)
|
||||||
|
.map(c => c.textContent.trim().toLowerCase())
|
||||||
|
.join(' ');
|
||||||
|
r.style.display = rowText.includes(q) ? '' : 'none';
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', filterRows);
|
||||||
|
|
||||||
|
/* ----- Table sorting ----- */
|
||||||
|
const table = document.querySelector('.ssd-list');
|
||||||
|
const headerCells = table.querySelectorAll('th[data-sort]');
|
||||||
|
const bodyRows = Array.from(tbody.rows);
|
||||||
|
|
||||||
|
headerCells.forEach((th, index) => {
|
||||||
|
th.classList.add('sortable'); // gives the arrow styling
|
||||||
|
th.style.cursor = 'pointer';
|
||||||
|
|
||||||
|
th.addEventListener('click', () => {
|
||||||
|
const currentSort = th.dataset.currentSort || 'none';
|
||||||
|
const ascending = currentSort !== 'asc';
|
||||||
|
|
||||||
|
// reset other headers
|
||||||
|
headerCells.forEach(h => {
|
||||||
|
h.dataset.currentSort = 'none';
|
||||||
|
h.classList.remove('asc', 'desc');
|
||||||
|
});
|
||||||
|
|
||||||
|
// set current header state
|
||||||
|
th.dataset.currentSort = ascending ? 'asc' : 'desc';
|
||||||
|
th.classList.toggle('asc', ascending);
|
||||||
|
th.classList.toggle('desc', !ascending);
|
||||||
|
|
||||||
|
// sort
|
||||||
|
bodyRows.sort((a, b) => {
|
||||||
|
const aText = a.cells[index].textContent.trim();
|
||||||
|
const bText = b.cells[index].textContent.trim();
|
||||||
|
|
||||||
|
// try numeric comparison
|
||||||
|
const aNum = parseFloat(aText.replace(/,/g, ''));
|
||||||
|
const bNum = parseFloat(bText.replace(/,/g, ''));
|
||||||
|
|
||||||
|
if (!isNaN(aNum) && !isNaN(bNum)) {
|
||||||
|
return ascending ? aNum - bNum : bNum - aNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to localeCompare (case‑insensitive)
|
||||||
|
return ascending
|
||||||
|
? aText.localeCompare(bText, undefined, { sensitivity: 'base' })
|
||||||
|
: bText.localeCompare(aText, undefined, { sensitivity: 'base' });
|
||||||
|
});
|
||||||
|
|
||||||
|
// re‑attach sorted rows
|
||||||
|
bodyRows.forEach(r => tbody.appendChild(r));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@ -129,3 +129,17 @@ li {
|
|||||||
background-color: #2c3e50; /* Dark background for meter */
|
background-color: #2c3e50; /* Dark background for meter */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort arrow */
|
||||||
|
th.sortable::after {
|
||||||
|
content: '';
|
||||||
|
float: right;
|
||||||
|
margin-left: 4px;
|
||||||
|
border: 4px solid transparent;
|
||||||
|
}
|
||||||
|
th.sortable.asc::after {
|
||||||
|
border-bottom-color: #333; /* ▲ */
|
||||||
|
}
|
||||||
|
th.sortable.desc::after {
|
||||||
|
border-top-color: #333; /* ▼ */
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -138,12 +138,22 @@ def return_sector_size(drive_id):
|
|||||||
sector_size_result = subprocess.run(sector_size_command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
sector_size_result = subprocess.run(sector_size_command, shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
return int(sector_size_result.stdout.decode("utf-8"))
|
return int(sector_size_result.stdout.decode("utf-8"))
|
||||||
|
|
||||||
|
# this had to be updated to allow for inconsistent SMART data
|
||||||
def return_ls_written(data):
|
def return_ls_written(data):
|
||||||
pages = data.get("ata_device_statistics", {}).get("pages", [])
|
if "ata_device_statistics" in data:
|
||||||
for page in pages:
|
pages = data.get("ata_device_statistics", {}).get("pages", [])
|
||||||
for entry in page.get("table", []):
|
for page in pages:
|
||||||
if entry.get("name") == "Logical Sectors Written":
|
for entry in page.get("table", []):
|
||||||
return entry.get("value")
|
if entry.get("name") == "Logical Sectors Written":
|
||||||
|
return entry.get("value")
|
||||||
|
|
||||||
|
if "ata_smart_attributes" in data:
|
||||||
|
print("type two")
|
||||||
|
pages = data.get("ata_smart_attributes", [])
|
||||||
|
for entry in pages.get("table", []):
|
||||||
|
if entry.get("name") == "Total_LBAs_Written":
|
||||||
|
print(entry.get("value").get("raw", {}))
|
||||||
|
return entry.get("raw").get("value")
|
||||||
|
|
||||||
# Function to return all drive records in database
|
# Function to return all drive records in database
|
||||||
def get_all_drive_records():
|
def get_all_drive_records():
|
||||||
|
|||||||
@ -88,9 +88,9 @@ if __name__ == '__main__':
|
|||||||
scheduler.start()
|
scheduler.start()
|
||||||
|
|
||||||
if secure_api:
|
if secure_api:
|
||||||
app.run(debug=True, host='172.17.0.1', port=5000)
|
app.run(debug=False, host='172.17.0.1', port=5000)
|
||||||
else:
|
else:
|
||||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
app.run(debug=False, host='0.0.0.0', port=5000)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -391,9 +391,9 @@ if __name__ == '__main__':
|
|||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
if secure_api:
|
if secure_api:
|
||||||
app.run(debug=True, host='172.17.0.1', port=5000)
|
app.run(debug=False, host='172.17.0.1', port=5000)
|
||||||
else:
|
else:
|
||||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
app.run(debug=False, host='0.0.0.0', port=5000)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -17,10 +17,10 @@
|
|||||||
when: not install_kiosk | bool and not service_only | bool and not armcpu_check | bool
|
when: not install_kiosk | bool and not service_only | bool and not armcpu_check | bool
|
||||||
include_tasks: autologin.yaml
|
include_tasks: autologin.yaml
|
||||||
|
|
||||||
# disablep autologin
|
# disable autologin
|
||||||
- name: Drive health - disable autologin
|
- name: Drive health - disable autologin
|
||||||
when: install_kiosk | bool or service_only | bool
|
when: install_kiosk | bool or service_only | bool
|
||||||
include_tasks: autologin.yaml
|
include_tasks: no_autologin.yaml
|
||||||
|
|
||||||
# Install chrome kiosk
|
# Install chrome kiosk
|
||||||
- name: install chromium kiosk
|
- name: install chromium kiosk
|
||||||
|
|||||||
Reference in New Issue
Block a user