From fc00b4b96128fd90e3b577e425b4a387974cbf1e Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Wed, 6 Mar 2024 15:31:54 +0800 Subject: [PATCH] opt.: display total disk space on server tab --- lib/data/model/server/disk.dart | 84 ++++++++----------- lib/data/model/server/net_speed.dart | 5 +- lib/data/model/server/server.dart | 2 + .../server/server_status_update_req.dart | 1 + lib/view/page/server/tab.dart | 12 +-- 5 files changed, 46 insertions(+), 58 deletions(-) diff --git a/lib/data/model/server/disk.dart b/lib/data/model/server/disk.dart index b28ac873..265c227b 100644 --- a/lib/data/model/server/disk.dart +++ b/lib/data/model/server/disk.dart @@ -1,3 +1,4 @@ +import 'package:toolbox/core/extension/listx.dart'; import 'package:toolbox/core/extension/numx.dart'; import 'package:toolbox/data/model/server/time_seq.dart'; @@ -20,12 +21,6 @@ class Disk { required this.avail, }); - /// raw: - /// ``` - /// Filesystem 1K-blocks Used Available Use% Mounted on - /// overlay 959122528 154470540 755857572 17% / - /// tmpfs 65536 0 65536 0% /dev - /// ``` static List parse(String raw) { final list = []; final items = raw.split('\n'); @@ -66,22 +61,16 @@ class DiskIO extends TimeSeq { @override void onUpdate() { - + cachedAllSpeed = _getAllSpeed(); } (double?, double?) _getSpeed(String dev) { - final pres = this.pre.where( - (element) => element.dev == dev.replaceFirst('/dev/', ''), - ); - final nows = this.now.where( - (element) => element.dev == dev.replaceFirst('/dev/', ''), - ); - if (pres.isEmpty || nows.isEmpty) return (null, null); - final pre = pres.first; - final now = nows.first; - final sectorsRead = now.sectorsRead - pre.sectorsRead; - final sectorsWrite = now.sectorsWrite - pre.sectorsWrite; - final time = now.time - pre.time; + final old = pre.firstWhereOrNull((e) => e.dev == '/dev/$dev'); + final new_ = now.firstWhereOrNull((e) => e.dev == '/dev/$dev'); + if (old == null || new_ == null) return (null, null); + final sectorsRead = new_.sectorsRead - old.sectorsRead; + final sectorsWrite = new_.sectorsWrite - old.sectorsWrite; + final time = new_.time - old.time; final read = sectorsRead / time * 512; final write = sectorsWrite / time * 512; return (read, write); @@ -95,7 +84,8 @@ class DiskIO extends TimeSeq { return (read, write); } - (String?, String?) getAllSpeed() { + (String?, String?) cachedAllSpeed = (null, null); + (String?, String?) _getAllSpeed() { if (pre.isEmpty || now.isEmpty) return (null, null); var (read, write) = (0.0, 0.0); for (var pre in pre) { @@ -108,18 +98,6 @@ class DiskIO extends TimeSeq { return (readStr, writeStr); } - // Raw: - // 254 0 vda 584193 186416 40419294 845790 5024458 2028159 92899586 6997559 0 5728372 8143590 0 0 0 0 2006112 300240 - // 254 1 vda1 584029 186416 40412734 845668 5024453 2028159 92899586 6997558 0 5728264 7843226 0 0 0 0 0 0 - // 11 0 sr0 36 0 280 49 0 0 0 0 0 56 49 0 0 0 0 0 0 - // 7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 1 loop1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 2 loop2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 3 loop3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 4 loop4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 5 loop5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 6 loop6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - // 7 7 loop7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 static List parse(String raw, int time) { final lines = raw.split('\n'); if (lines.isEmpty) return []; @@ -163,25 +141,29 @@ class DiskIOPiece extends TimeSeqIface { bool same(DiskIOPiece other) => dev == other.dev; } -/// Issue 88 -/// -/// Due to performance issues, -/// if there is no `Disk.loc == '/' || Disk.loc == '/sysroot'`, -/// return the first [Disk] of [disks]. -/// -/// If we find out the biggest [Disk] of [disks], -/// the fps may lower than 60. -Disk? findRootDisk(List disks) { - if (disks.isEmpty) return null; - final roots = disks.where((element) => element.mount == '/'); - if (roots.isEmpty) { - final sysRoots = disks.where((element) => element.mount == '/sysroot'); - if (sysRoots.isEmpty) { - return disks.first; - } else { - return sysRoots.first; +class DiskUsage { + final BigInt used; + final BigInt size; + + DiskUsage({ + required this.used, + required this.size, + }); + + double get usedPercent => used / size * 100; + + /// Find all devs, add their used and size + static DiskUsage parse(List disks) { + final devs = {}; + var used = BigInt.zero; + var size = BigInt.zero; + for (var disk in disks) { + if (!disk.dev.startsWith('/dev')) continue; + if (devs.contains(disk.dev)) continue; + devs.add(disk.dev); + used += disk.used; + size += disk.size; } - } else { - return roots.first; + return DiskUsage(used: used, size: size); } } diff --git a/lib/data/model/server/net_speed.dart b/lib/data/model/server/net_speed.dart index 669781ba..042f774c 100644 --- a/lib/data/model/server/net_speed.dart +++ b/lib/data/model/server/net_speed.dart @@ -44,7 +44,7 @@ class NetSpeed extends TimeSeq { /// Issue #295 /// Non-virtual network device prefix - static const List realIfacePrefixs = ['eth', 'wlan', 'en', 'ww', 'wl']; + static const realIfacePrefixs = ['eth', 'wlan', 'en', 'ww', 'wl']; /// Cached non-virtual network device prefix final realIfaces = []; @@ -166,7 +166,8 @@ class NetSpeed extends TimeSeq { for (final item in split.sublist(2)) { try { final data = item.trim().split(':'); - final device = data.first; + final device = data.firstOrNull; + if (device == null) continue; final bytes = data.last.trim().split(' '); bytes.removeWhere((element) => element == ''); final bytesIn = BigInt.parse(bytes.first); diff --git a/lib/data/model/server/server.dart b/lib/data/model/server/server.dart index f48f21da..abbc3536 100644 --- a/lib/data/model/server/server.dart +++ b/lib/data/model/server/server.dart @@ -57,6 +57,7 @@ class ServerStatus { final List batteries = []; final Map more = {}; final List sensors = []; + DiskUsage? diskUsage; ServerStatus({ required this.cpu, @@ -70,6 +71,7 @@ class ServerStatus { required this.diskIO, this.err, this.nvidia, + this.diskUsage, }); } diff --git a/lib/data/model/server/server_status_update_req.dart b/lib/data/model/server/server_status_update_req.dart index 9b18f41a..0da747b9 100644 --- a/lib/data/model/server/server_status_update_req.dart +++ b/lib/data/model/server/server_status_update_req.dart @@ -93,6 +93,7 @@ Future _getLinuxStatus(ServerStatusUpdateReq req) async { try { req.ss.disk = Disk.parse(StatusCmdType.disk.find(segments)); + req.ss.diskUsage = DiskUsage.parse(req.ss.disk); } catch (e, s) { Loggers.parse.warning(e, s); } diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 3c775ea8..10ed1fc0 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -19,7 +19,6 @@ import 'package:toolbox/data/res/store.dart'; import '../../../core/route.dart'; import '../../../data/model/app/net_view.dart'; -import '../../../data/model/server/disk.dart'; import '../../../data/model/server/server.dart'; import '../../../data/model/server/server_private_info.dart'; import '../../../data/provider/server.dart'; @@ -430,11 +429,10 @@ class _ServerPageState extends State return ListenableBuilder( listenable: cardNoti, builder: (_, __) { - final rootDisk = findRootDisk(ss.disk); final isSpeed = cardNoti.value.diskIO ?? !Stores.setting.serverTabPreferDiskAmount.fetch(); - final (r, w) = ss.diskIO.getAllSpeed(); + final (r, w) = ss.diskIO.cachedAllSpeed; return AnimatedSwitcher( duration: const Duration(milliseconds: 377), @@ -442,8 +440,12 @@ class _ServerPageState extends State return FadeTransition(opacity: animation, child: child); }, child: _buildIOData( - isSpeed ? '${l10n.read}:\n$r' : 'Total:\n${rootDisk?.size.kb2Str}', - isSpeed ? '${l10n.write}:\n$w' : 'Used:\n${rootDisk?.usedPercent}%', + isSpeed + ? '${l10n.read}:\n$r' + : 'Total:\n${ss.diskUsage?.size.kb2Str}', + isSpeed + ? '${l10n.write}:\n$w' + : 'Used:\n${ss.diskUsage?.used.kb2Str}', onTap: () { cardNoti.value = cardNoti.value.copyWith(diskIO: !isSpeed); },