Files
flutter_server_box/lib/data/model/server/sensors.dart
lollipopkit🏳️‍⚧️ 3a615449e3 feat: Windows compatibility (#836)
* 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>
2025-08-08 16:56:36 +08:00

88 lines
2.5 KiB
Dart

import 'package:fl_lib/fl_lib.dart';
final class SensorAdaptor {
final String raw;
const SensorAdaptor(this.raw);
static const acpiRaw = 'ACPI interface';
static const pciRaw = 'PCI adapter';
static const virtualRaw = 'Virtual device';
static const isaRaw = 'ISA adapter';
static const acpi = SensorAdaptor(acpiRaw);
static const pci = SensorAdaptor(pciRaw);
static const virtual = SensorAdaptor(virtualRaw);
static const isa = SensorAdaptor(isaRaw);
static SensorAdaptor parse(String raw) => switch (raw) {
acpiRaw => acpi,
pciRaw => pci,
virtualRaw => virtual,
isaRaw => isa,
_ => SensorAdaptor(raw),
};
}
final class SensorItem {
final String device;
final SensorAdaptor adapter;
final Map<String, String> details;
const SensorItem({required this.device, required this.adapter, required this.details});
String get toMarkdown {
final sb = StringBuffer();
sb.writeln('| ${libL10n.name} | ${libL10n.content} |');
sb.writeln('| --- | --- |');
for (final entry in details.entries) {
sb.writeln('| ${entry.key} | ${entry.value} |');
}
return sb.toString();
}
String? get summary {
return details.values.firstOrNull;
}
static List<SensorItem> parse(String raw) {
final eachSensorLines = <List<String>>[[]];
final lines = raw.split('\n');
var emptyLinesCount = 0;
for (var i = 0; i < lines.length; i++) {
final line = lines[i];
if (line.isEmpty) {
eachSensorLines.add([]);
emptyLinesCount++;
continue;
}
eachSensorLines.last.add(line);
}
if (emptyLinesCount + 1 != eachSensorLines.length) {
Loggers.app.warning('Empty lines count not match');
}
final sensors = <SensorItem>[];
for (final sensorLines in eachSensorLines) {
// At least 3 lines: [device, adapter, temp]
final len = sensorLines.length;
if (len < 3) continue;
final device = sensorLines.first;
final adapter = SensorAdaptor.parse(sensorLines[1].split(':').last.trim());
final details = <String, String>{};
for (var idx = 2; idx < len; idx++) {
final part = sensorLines[idx];
final detailParts = part.split(':');
if (detailParts.length < 2) continue;
final key = detailParts[0].trim();
final value = detailParts[1].trim();
details[key] = value;
}
sensors.add(SensorItem(device: device, adapter: adapter, details: details));
}
return sensors;
}
}