android comp
This commit is contained in:
1 parent
6111acd7e0
commit
249ec4209e
4 files changed
+76
-14
No files matched your search
@@ -15,17 +15,24 @@ class HardwareStatistics:
|
||||
self.os_info = None
|
||||
self.boot_time = None
|
||||
|
||||
@staticmethod
|
||||
def _try(read, fallback=None):
|
||||
try:
|
||||
return read()
|
||||
except Exception:
|
||||
return fallback
|
||||
|
||||
@staticmethod
|
||||
def collect():
|
||||
self = HardwareStatistics()
|
||||
self.cpu = self._get_cpu_stats()
|
||||
self.mem = self._get_memory_stats()
|
||||
self.gpu = self._get_gpu_stats()
|
||||
self.disk = self._get_disk_stats()
|
||||
self.os_info = self._get_os_info()
|
||||
self.boot_time = datetime.datetime.fromtimestamp(
|
||||
psutil.boot_time()
|
||||
).isoformat()
|
||||
self.cpu = self._try(self._get_cpu_stats)
|
||||
self.mem = self._try(self._get_memory_stats)
|
||||
self.gpu = self._try(self._get_gpu_stats, [])
|
||||
self.disk = self._try(self._get_disk_stats, [])
|
||||
self.os_info = self._try(self._get_os_info)
|
||||
self.boot_time = self._try(
|
||||
lambda: datetime.datetime.fromtimestamp(psutil.boot_time()).isoformat()
|
||||
)
|
||||
return self
|
||||
|
||||
def to_dict(self):
|
||||
@@ -63,6 +70,7 @@ class HardwareStatistics:
|
||||
stats["gpu_mem_total_gb"] = round(sum(g["memory_total"] for g in self.gpu) / 1024, 2)
|
||||
stats["gpu_mem_used_gb"] = round(sum(g["memory_used"] for g in self.gpu) / 1024, 2)
|
||||
|
||||
if self.boot_time:
|
||||
stats["uptime_hours"] = HardwareScorer.longevity_score(self)
|
||||
return stats
|
||||
|
||||
@@ -87,7 +95,7 @@ class HardwareStatistics:
|
||||
return {
|
||||
"cores": psutil.cpu_count(logical=False),
|
||||
"threads": psutil.cpu_count(logical=True),
|
||||
"usage_percent": psutil.cpu_percent(interval=0.2)
|
||||
"usage_percent": self._try(lambda: psutil.cpu_percent(interval=0.2))
|
||||
}
|
||||
|
||||
def _get_memory_stats(self):
|
||||
@@ -100,10 +108,7 @@ class HardwareStatistics:
|
||||
}
|
||||
|
||||
def _get_gpu_stats(self):
|
||||
try:
|
||||
gpus = GPUtil.getGPUs()
|
||||
except Exception:
|
||||
return []
|
||||
if not gpus:
|
||||
return []
|
||||
return [
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
const STORAGE_KEY = "colony.map.v1";
|
||||
const PAD = 48;
|
||||
const FIT_MS = 260;
|
||||
const COMPACT_MAX_WIDTH = 600;
|
||||
|
||||
const stage = document.getElementById("stage");
|
||||
const svgRoot = document.getElementById("map");
|
||||
@@ -149,10 +150,29 @@
|
||||
updateControls();
|
||||
}
|
||||
|
||||
function regionView(region) {
|
||||
return C.viewFor({ x: region.x - 40, y: region.y - 40, w: region.w + 80, h: region.h + 80 }, size, 24);
|
||||
}
|
||||
|
||||
function fitRegion(net) {
|
||||
const region = map && map.regionAt.get(net);
|
||||
if (!region) return;
|
||||
animateTo(C.viewFor({ x: region.x - 40, y: region.y - 40, w: region.w + 80, h: region.h + 80 }, size, 24), true);
|
||||
animateTo(regionView(region), true);
|
||||
}
|
||||
|
||||
// On a phone, fitting the whole map shrinks it below the zoom where names and stats are drawn,
|
||||
// so the first view is the region of this node instead. COMPACT_MAX_WIDTH matches the phone
|
||||
// breakpoint in style.css. This only sets `view` and `autoFit`; the caller applies the view afterwards.
|
||||
let startedCompact = false;
|
||||
function startCompact() {
|
||||
if (startedCompact) return;
|
||||
startedCompact = true; // decided once, on the first map: later changes to the window or the topology must not move the view
|
||||
if (size.w > COMPACT_MAX_WIDTH) return;
|
||||
const self = model.nodes.find((node) => node.self);
|
||||
const region = self && map.regionAt.get(self.net);
|
||||
if (!region) return;
|
||||
autoFit = false;
|
||||
view = regionView(region);
|
||||
}
|
||||
|
||||
function resize() {
|
||||
@@ -482,6 +502,7 @@
|
||||
drawNodes();
|
||||
drawSpokes();
|
||||
drawPorts();
|
||||
startCompact();
|
||||
if (autoFit) fitAll(false);
|
||||
else setView(view, false);
|
||||
drawTrace();
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Colony</title>
|
||||
<script>
|
||||
/* The Android app asks for ?theme=dark: a WebView reports the theme of its host app, not the phone's setting. */
|
||||
const theme = new URLSearchParams(location.search).get("theme");
|
||||
if (theme === "dark" || theme === "light") document.documentElement.dataset.theme = theme;
|
||||
</script>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
:root:not([data-theme="light"]) {
|
||||
color-scheme: dark;
|
||||
--bg: #12161c;
|
||||
--card: #1b2129;
|
||||
--text: #e6eaf0;
|
||||
@@ -38,6 +39,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
:root[data-theme="dark"] {
|
||||
color-scheme: dark;
|
||||
--bg: #12161c;
|
||||
--card: #1b2129;
|
||||
--text: #e6eaf0;
|
||||
--muted: #93a0b3;
|
||||
--line: #313a47;
|
||||
--down: #6b7686;
|
||||
--track: #2a3340;
|
||||
--panel: rgba(27, 33, 41, 0.92);
|
||||
--warn: #ffb04a;
|
||||
--crit: #ff6b6b;
|
||||
--n0: #6c9cff;
|
||||
--n1: #3cc7c7;
|
||||
--n2: #ab8cff;
|
||||
--n3: #ff7cc8;
|
||||
--n4: #e0b04a;
|
||||
--n5: #8fd06a;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
html, body { height: 100%; }
|
||||
@@ -196,3 +217,13 @@ p { margin: 4px 0; }
|
||||
.swatch.none { background: transparent; border: 2px dashed var(--muted); }
|
||||
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
||||
|
||||
/* Phones: the desktop sizes are small on a 400px screen, so the page text and touch targets grow. */
|
||||
@media (max-width: 600px) {
|
||||
body { font-size: 16px; }
|
||||
header { padding: 0 12px 6px; }
|
||||
h1 { font-size: 24px; }
|
||||
.alert, .route, .muted, .legend { font-size: 14px; }
|
||||
.legend { max-width: calc(100% - 24px); }
|
||||
.legend, .legend-open { bottom: 64px; }
|
||||
}
|
||||
Reference in new issue
Block a user