mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
* feat: win compatibility * fix * fix: uptime parse * opt.: linux uptime accuracy * fix: windows temperature fetching * opt. * opt.: powershell exec * refactor: address PR review feedback and improve code quality ### Major Improvements: - **Refactored Windows status parsing**: Broke down large `_getWindowsStatus` method into 13 smaller, focused helper methods for better maintainability and readability - **Extracted system detection logic**: Created dedicated `SystemDetector` helper class to separate OS detection concerns from ServerProvider - **Improved concurrency handling**: Implemented proper synchronization for server updates using Future-based locks to prevent race conditions ### Bug Fixes: - **Fixed CPU percentage parsing**: Removed incorrect '*100' multiplication in BSD CPU parsing (values were already percentages) - **Enhanced memory parsing**: Added validation and error handling to BSD memory fallback parsing with proper logging - **Improved uptime parsing**: Added support for multiple Windows date formats and robust error handling with validation - **Fixed division by zero**: Added safety checks in Swap.usedPercent getter ### Code Quality Enhancements: - **Added comprehensive documentation**: Documented Windows CPU counter limitations and approach - **Strengthened error handling**: Added detailed logging and validation throughout parsing methods - **Improved robustness**: Enhanced BSD CPU parsing with percentage validation and warnings - **Better separation of concerns**: Each parsing method now has single responsibility ### Files Changed: - `lib/data/helper/system_detector.dart` (new): System detection helper - `lib/data/model/server/cpu.dart`: Fixed percentage parsing and added validation - `lib/data/model/server/memory.dart`: Enhanced fallback parsing and division-by-zero protection - `lib/data/model/server/server_status_update_req.dart`: Refactored into 13 focused parsing methods - `lib/data/provider/server.dart`: Improved synchronization and extracted system detection 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: parse & shell fn struct --------- Co-authored-by: Claude <noreply@anthropic.com>
98 lines
2.4 KiB
Dart
98 lines
2.4 KiB
Dart
import 'package:fl_lib/fl_lib.dart';
|
|
|
|
/// raw dat from server:
|
|
/// ```text
|
|
/// POWER_SUPPLY_NAME=hidpp_battery_0
|
|
/// POWER_SUPPLY_TYPE=Battery
|
|
/// POWER_SUPPLY_ONLINE=1
|
|
/// POWER_SUPPLY_STATUS=Discharging
|
|
/// POWER_SUPPLY_SCOPE=Device
|
|
/// POWER_SUPPLY_MODEL_NAME=MX Anywhere 3
|
|
/// POWER_SUPPLY_MANUFACTURER=Logitech
|
|
/// POWER_SUPPLY_SERIAL_NUMBER=0f-fc-43-f8
|
|
/// POWER_SUPPLY_CAPACITY=35
|
|
/// ```
|
|
class Battery {
|
|
final int? percent;
|
|
final BatteryStatus status;
|
|
final String? name;
|
|
final int? cycle;
|
|
final String? tech;
|
|
|
|
const Battery({required this.status, this.percent, this.name, this.cycle, this.tech});
|
|
|
|
factory Battery.fromRaw(String raw) {
|
|
final lines = raw.split('\n');
|
|
final map = <String, String>{};
|
|
for (final line in lines) {
|
|
final parts = line.split('=');
|
|
if (parts.length != 2) continue;
|
|
map[parts[0]] = parts[1];
|
|
}
|
|
|
|
final capacity = map['POWER_SUPPLY_CAPACITY']; // 30%
|
|
final cycle = map['POWER_SUPPLY_CYCLE_COUNT']; // 30
|
|
|
|
var name = map['POWER_SUPPLY_MODEL_NAME'];
|
|
name ??= map['POWER_SUPPLY_NAME'];
|
|
|
|
return Battery(
|
|
percent: capacity == null ? null : int.tryParse(capacity),
|
|
status: BatteryStatus.parse(map['POWER_SUPPLY_STATUS']),
|
|
name: name,
|
|
cycle: cycle == null ? null : int.tryParse(cycle),
|
|
tech: map['POWER_SUPPLY_TECHNOLOGY'],
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'Battery{$percent, $status, $name, $cycle}';
|
|
}
|
|
|
|
bool get isLiPoly => tech == 'Li-poly';
|
|
}
|
|
|
|
enum BatteryStatus {
|
|
charging,
|
|
discharging,
|
|
full,
|
|
unknown;
|
|
|
|
static BatteryStatus parse(String? status) {
|
|
switch (status) {
|
|
case 'Charging':
|
|
return BatteryStatus.charging;
|
|
case 'Discharging':
|
|
return BatteryStatus.discharging;
|
|
case 'Full':
|
|
return BatteryStatus.full;
|
|
default:
|
|
return BatteryStatus.unknown;
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract final class Batteries {
|
|
static List<Battery> parse(String raw, [bool onlyLiPoly = false]) {
|
|
final lines = raw.split('\n');
|
|
final batteries = <Battery>[];
|
|
final oneBatLines = <String>[];
|
|
for (final line in lines) {
|
|
if (line.isEmpty) {
|
|
try {
|
|
final bat = Battery.fromRaw(oneBatLines.join('\n'));
|
|
if (onlyLiPoly && !bat.isLiPoly) continue;
|
|
batteries.add(bat);
|
|
} catch (e, s) {
|
|
Loggers.app.warning(e, s);
|
|
}
|
|
oneBatLines.clear();
|
|
} else {
|
|
oneBatLines.add(line);
|
|
}
|
|
}
|
|
return batteries;
|
|
}
|
|
}
|