Skip to content

Commit 60319db

Browse files
authored
Unused removal #2 (#1183)
* Remove 12 confirmed dead code items Store fields: - HistoryStore.sshCmds (never accessed) - HistoryStore.writeScriptTipShown (never accessed) - SettingStore.storeVersion (never read/written) Provider: - PveNotifier.onlyOneNode (model getter used instead) Enum values: - SSHErrType.chdir (never instantiated) - ContainerErrType.cmdNoPrefix (never referenced) - SystemdUnitFunc.reload, .enable, .disable (never used) Extensions/methods: - SshDiscoveryConfigX.toArgs() (never called) - ChainComparator.empty() (create() used instead) - PortForwardStore.update/have/deleteByServer (never called) Constants: - Miscs.maxDebugLogLines (never referenced) Other: - SensorAdaptor static instances inlined in parse() - Updated tests to match * Remove 4 unused model fields NvidiaSmiItem.uuid: - Parsed from nvidia-smi XML but never read in UI or logic AmdSmiItem.deviceId: - Parsed from amd-smi JSON but never read in UI or logic Conn.active, Conn.passive: - Parsed from /proc/net/snmp but only maxConn and fail are displayed in the connection stats view Windows connCount moved from active to maxConn field since that is the field actually shown in the UI. * Deduplicate repeated code patterns C1: Replace local _shellQuote in sftp.dart and sftp_sudo.dart with canonical shellSingleQuote from shell_quote.dart C2: Replace _formatSize in connection_stats.dart with existing bytes2Str extension from fl_lib C3: Extract _parseFirstInt helper in nvdia.dart to replace 6 instances of int.tryParse(s?.split(' ').firstOrNull ?? '0') ?? 0 C4: Extract _updateDiskUsage helper in server_status_update_req.dart to deduplicate DiskUsage.parse guard pattern in Linux and BSD paths * Performance: cache Proc.binary, optimize NetSpeed iteration D1: Proc.binary getter re-parsed command string on every access (called O(n log n) times during sort). Changed to late final field so it is computed once per Proc instance. D3: NetSpeed speedIn/sizeIn/speedOut/sizeOut used devices.indexOf(device) inside loops (O(n) per iteration). Replaced with index-based iteration for O(1) per iteration. Also optimized deviceIdx to use direct index comparison instead of iterating then calling indexOf. D2 skipped: ref.listen in build() is correct Riverpod pattern (Riverpod deduplicates listeners by identity). * Fix prefix double-counting in NetSpeed, fix shell injection in SFTP edit NetSpeed: realIfacePrefixs contains both 'wl' and 'wlan', so a device like wlan0 matched both prefixes and was counted twice. Added break after first prefix match in all 4 aggregation methods (speedIn, sizeIn, speedOut, sizeOut). SFTP edit: remotePath was wrapped with manual single quotes which doesn't escape embedded single quotes. Replaced with shellSingleQuote(remotePath) for proper escaping.
1 parent 8584f32 commit 60319db

25 files changed

Lines changed: 82 additions & 178 deletions

lib/core/utils/comparator.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ class ChainComparator<T> {
33
final Comparator<T> _comparator;
44

55
ChainComparator._create(this._parent, this._comparator);
6-
ChainComparator.empty() : this._create(null, (a, b) => 0);
76
ChainComparator.create() : this._create(null, (a, b) => 0);
87

98
static ChainComparator<T> comparing<T, F extends Comparable<F>>(

lib/core/utils/sftp_sudo.dart

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:fl_lib/fl_lib.dart';
66
import 'package:flutter/material.dart';
77
import 'package:server_box/core/extension/context/locale.dart';
88
import 'package:server_box/core/extension/ssh_client.dart';
9+
import 'package:server_box/core/utils/shell_quote.dart';
910
import 'package:server_box/data/model/server/server_private_info.dart';
1011
import 'package:server_box/data/res/store.dart';
1112

@@ -55,7 +56,7 @@ final class SftpSudoHelper {
5556

5657
Future<int> getFileSize(String remotePath, {String? password}) async {
5758
final output = await _runAndRead(
58-
'wc -c < ${_shellQuote(remotePath)}',
59+
'wc -c < ${shellSingleQuote(remotePath)}',
5960
password: password,
6061
);
6162
return int.tryParse(output.trim()) ?? 0;
@@ -67,7 +68,7 @@ final class SftpSudoHelper {
6768
String? password,
6869
}) async {
6970
final text = await _runAndRead(
70-
'cat ${_shellQuote(remotePath)}',
71+
'cat ${shellSingleQuote(remotePath)}',
7172
password: password,
7273
);
7374
final file = File(localPath);
@@ -84,7 +85,7 @@ final class SftpSudoHelper {
8485
final bytes = await file.readAsBytes();
8586
final data = base64Encode(bytes);
8687
await _runAndRead(
87-
"printf '%s' '$data' | base64 -d | tee ${_shellQuote(remotePath)} > /dev/null",
88+
"printf '%s' '$data' | base64 -d | tee ${shellSingleQuote(remotePath)} > /dev/null",
8889
password: password,
8990
);
9091
}
@@ -98,17 +99,17 @@ final class SftpSudoHelper {
9899
);
99100
}
100101
await _runAndRead(
101-
'chmod $perm ${_shellQuote(remotePath)}',
102+
'chmod $perm ${shellSingleQuote(remotePath)}',
102103
password: password,
103104
);
104105
}
105106

106107
Future<void> mkdir(String remotePath, {String? password}) async {
107-
await _runAndRead('mkdir ${_shellQuote(remotePath)}', password: password);
108+
await _runAndRead('mkdir ${shellSingleQuote(remotePath)}', password: password);
108109
}
109110

110111
Future<void> touch(String remotePath, {String? password}) async {
111-
await _runAndRead('touch ${_shellQuote(remotePath)}', password: password);
112+
await _runAndRead('touch ${shellSingleQuote(remotePath)}', password: password);
112113
}
113114

114115
Future<void> rename(
@@ -117,7 +118,7 @@ final class SftpSudoHelper {
117118
String? password,
118119
}) async {
119120
await _runAndRead(
120-
'mv ${_shellQuote(oldPath)} ${_shellQuote(newPath)}',
121+
'mv ${shellSingleQuote(oldPath)} ${shellSingleQuote(newPath)}',
121122
password: password,
122123
);
123124
}
@@ -129,16 +130,16 @@ final class SftpSudoHelper {
129130
String? password,
130131
}) async {
131132
final cmd = switch ((isDir, recursive)) {
132-
(true, true) => 'rm -r ${_shellQuote(remotePath)}',
133-
(true, false) => 'rmdir ${_shellQuote(remotePath)}',
134-
(false, _) => 'rm ${_shellQuote(remotePath)}',
133+
(true, true) => 'rm -r ${shellSingleQuote(remotePath)}',
134+
(true, false) => 'rmdir ${shellSingleQuote(remotePath)}',
135+
(false, _) => 'rm ${shellSingleQuote(remotePath)}',
135136
};
136137
await _runAndRead(cmd, password: password);
137138
}
138139

139140
Future<List<SftpName>> listDir(String remotePath, {String? password}) async {
140141
final output = await _runAndRead(
141-
'find ${_shellQuote(remotePath)} '
142+
'find ${shellSingleQuote(remotePath)} '
142143
'-mindepth 1 -maxdepth 1 '
143144
'-exec sh -c \''
144145
'for path do '
@@ -242,10 +243,6 @@ final class SftpSudoHelper {
242243
return 'echo "$pwdBase64" | base64 -d | sudo -S -- sh -c \'$escapedWrapped\'';
243244
}
244245

245-
static String _shellQuote(String value) {
246-
return "'${value.replaceAll("'", "'\\''")}'";
247-
}
248-
249246
static SftpFileMode _buildMode(String typeChar, int permOct) {
250247
final typeFlag = switch (typeChar) {
251248
'd' => 0x4000,

lib/data/model/app/error.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ enum SSHErrType {
66
connect,
77
auth,
88
noPrivateKey,
9-
chdir,
109
segements,
1110
writeScript,
1211
getStatus,
@@ -17,7 +16,6 @@ class SSHErr extends Err<SSHErrType> {
1716

1817
@override
1918
String? get solution => switch (type) {
20-
SSHErrType.chdir => l10n.needHomeDir,
2119
SSHErrType.auth => l10n.authFailTip,
2220
SSHErrType.writeScript => l10n.writeScriptFailTip,
2321
SSHErrType.noPrivateKey => l10n.noPrivateKeyTip,
@@ -30,7 +28,6 @@ enum ContainerErrType {
3028
noClient,
3129
notInstalled,
3230
invalidVersion,
33-
cmdNoPrefix,
3431
segmentsNotMatch,
3532
parsePs,
3633
parseImages,

lib/data/model/server/amd.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ class AmdSmi {
5050
gpu['card_model'] ??
5151
gpu['device_name'] ??
5252
'Unknown AMD GPU';
53-
final deviceId =
54-
gpu['device_id']?.toString() ?? gpu['gpu_id']?.toString() ?? '0';
5553

5654
// Temperature parsing
5755
final tempRaw = gpu['temperature'] ?? gpu['temp'] ?? gpu['gpu_temp'];
@@ -80,7 +78,6 @@ class AmdSmi {
8078
);
8179

8280
return AmdSmiItem(
83-
deviceId: deviceId,
8481
name: name,
8582
temp: temp,
8683
power: power,
@@ -149,7 +146,6 @@ class AmdSmi {
149146
}
150147

151148
class AmdSmiItem {
152-
final String deviceId;
153149
final String name;
154150
final int temp;
155151
final String power;
@@ -159,7 +155,6 @@ class AmdSmiItem {
159155
final int clockSpeed;
160156

161157
const AmdSmiItem({
162-
required this.deviceId,
163158
required this.name,
164159
required this.temp,
165160
required this.power,

lib/data/model/server/conn.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ import 'package:server_box/data/res/misc.dart';
22

33
class Conn {
44
final int maxConn;
5-
final int active;
6-
final int passive;
75
final int fail;
86

97
const Conn({
108
required this.maxConn,
11-
required this.active,
12-
required this.passive,
139
required this.fail,
1410
});
1511

@@ -23,8 +19,6 @@ class Conn {
2319
final vals = idx.split(Miscs.blankReg);
2420
return Conn(
2521
maxConn: int.tryParse(vals[5]) ?? 0,
26-
active: int.tryParse(vals[6]) ?? 0,
27-
passive: int.tryParse(vals[7]) ?? 0,
2822
fail: int.tryParse(vals[8]) ?? 0,
2923
);
3024
}

lib/data/model/server/discovery_result.dart

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,3 @@ abstract class SshDiscoveryConfig with _$SshDiscoveryConfig {
3838
@Default(4096) int hostEnumerationLimit,
3939
}) = _SshDiscoveryConfig;
4040
}
41-
42-
extension SshDiscoveryConfigX on SshDiscoveryConfig {
43-
List<String> toArgs() {
44-
final args = <String>[];
45-
args.add('--timeout-ms=$timeoutMs');
46-
args.add('--max-concurrency=$maxConcurrency');
47-
args.add('--host-enumeration-limit=$hostEnumerationLimit');
48-
if (enableMdns) args.add('--enable-mdns');
49-
return args;
50-
}
51-
}

lib/data/model/server/net_speed.dart

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ class NetSpeed extends TimeSeq<NetSpeedPart> {
8282
if (pre.length != now.length) return 'N/A';
8383
if (device == null) {
8484
var speed = 0.0;
85-
for (final device in devices) {
85+
for (var i = 0; i < devices.length; i++) {
8686
for (final prefix in realIfacePrefixs) {
87-
if (device.startsWith(prefix)) {
88-
speed += speedInBytes(devices.indexOf(device));
87+
if (devices[i].startsWith(prefix)) {
88+
speed += speedInBytes(i);
89+
break;
8990
}
9091
}
9192
}
@@ -100,10 +101,11 @@ class NetSpeed extends TimeSeq<NetSpeedPart> {
100101
if (pre.length != now.length) return 'N/A';
101102
if (device == null) {
102103
var size = BigInt.from(0);
103-
for (final device in devices) {
104+
for (var i = 0; i < devices.length; i++) {
104105
for (final prefix in realIfacePrefixs) {
105-
if (device.startsWith(prefix)) {
106-
size += sizeInBytes(devices.indexOf(device));
106+
if (devices[i].startsWith(prefix)) {
107+
size += sizeInBytes(i);
108+
break;
107109
}
108110
}
109111
}
@@ -118,10 +120,11 @@ class NetSpeed extends TimeSeq<NetSpeedPart> {
118120
if (pre.length != now.length) return 'N/A';
119121
if (device == null) {
120122
var speed = 0.0;
121-
for (final device in devices) {
123+
for (var i = 0; i < devices.length; i++) {
122124
for (final prefix in realIfacePrefixs) {
123-
if (device.startsWith(prefix)) {
124-
speed += speedOutBytes(devices.indexOf(device));
125+
if (devices[i].startsWith(prefix)) {
126+
speed += speedOutBytes(i);
127+
break;
125128
}
126129
}
127130
}
@@ -136,10 +139,11 @@ class NetSpeed extends TimeSeq<NetSpeedPart> {
136139
if (pre.length != now.length) return 'N/A';
137140
if (device == null) {
138141
var size = BigInt.from(0);
139-
for (final device in devices) {
142+
for (var i = 0; i < devices.length; i++) {
140143
for (final prefix in realIfacePrefixs) {
141-
if (device.startsWith(prefix)) {
142-
size += sizeOutBytes(devices.indexOf(device));
144+
if (devices[i].startsWith(prefix)) {
145+
size += sizeOutBytes(i);
146+
break;
143147
}
144148
}
145149
}
@@ -151,10 +155,8 @@ class NetSpeed extends TimeSeq<NetSpeedPart> {
151155

152156
int deviceIdx(String? device) {
153157
if (device != null) {
154-
for (var item in now) {
155-
if (item.device == device) {
156-
return now.indexOf(item);
157-
}
158+
for (var i = 0; i < now.length; i++) {
159+
if (now[i].device == device) return i;
158160
}
159161
}
160162
return 0;

lib/data/model/server/nvdia.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import 'package:xml/xml.dart';
22

3+
int _parseFirstInt(String? s) =>
4+
int.tryParse(s?.split(' ').firstOrNull ?? '0') ?? 0;
5+
36
/// [
47
/// {
58
/// "name": "GeForce RTX 3090",
@@ -67,7 +70,7 @@ class NvidiaSmi {
6770
return NvidiaSmiMemProcess(
6871
int.tryParse(pid) ?? 0,
6972
name,
70-
int.tryParse(memory.split(' ').firstOrNull ?? '0') ?? 0,
73+
_parseFirstInt(memory),
7174
);
7275
}
7376
return null;
@@ -84,17 +87,16 @@ class NvidiaSmi {
8487
if (name != null && temp != null) {
8588
return NvidiaSmiItem(
8689
name: name,
87-
uuid: gpu.findElements('uuid').firstOrNull?.innerText ?? '',
88-
temp: int.tryParse(temp.split(' ').firstOrNull ?? '0') ?? 0,
89-
percent: int.tryParse(percent?.split(' ').firstOrNull ?? '0') ?? 0,
90+
temp: _parseFirstInt(temp),
91+
percent: _parseFirstInt(percent),
9092
power: '$powerDraw / $powerLimit',
9193
memory: NvidiaSmiMem(
92-
int.tryParse(memoryTotal?.split(' ').firstOrNull ?? '0') ?? 0,
93-
int.tryParse(memoryUsed?.split(' ').firstOrNull ?? '0') ?? 0,
94+
_parseFirstInt(memoryTotal),
95+
_parseFirstInt(memoryUsed),
9496
'MiB',
9597
List.from(memoryProcesses),
9698
),
97-
fanSpeed: int.tryParse(fanSpeed?.split(' ').firstOrNull ?? '0') ?? 0,
99+
fanSpeed: _parseFirstInt(fanSpeed),
98100
);
99101
}
100102
return null;
@@ -105,7 +107,6 @@ class NvidiaSmi {
105107
}
106108

107109
class NvidiaSmiItem {
108-
final String uuid;
109110
final String name;
110111
final int temp;
111112
final String power;
@@ -114,7 +115,6 @@ class NvidiaSmiItem {
114115
final int fanSpeed;
115116

116117
const NvidiaSmiItem({
117-
required this.uuid,
118118
required this.name,
119119
required this.temp,
120120
required this.power,

lib/data/model/server/proc.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ class Proc {
5252
final double? writeSpeed;
5353
final String command;
5454

55-
const Proc({
55+
late final binary = _parseBinary();
56+
57+
Proc({
5658
this.user,
5759
required this.pid,
5860
this.cpu,
@@ -162,7 +164,7 @@ class Proc {
162164
return Miscs.jsonEncoder.convert(toJson());
163165
}
164166

165-
String get binary {
167+
String _parseBinary() {
166168
final parts = command.trim().split(' ').where((e) => e.isNotEmpty).toList();
167169
return parts.isNotEmpty ? parts[0] : '';
168170
}

lib/data/model/server/sensors.dart

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,11 @@ final class SensorAdaptor {
99
static const pciRaw = 'PCI adapter';
1010
static const virtualRaw = 'Virtual device';
1111
static const isaRaw = 'ISA adapter';
12-
static const acpi = SensorAdaptor(acpiRaw);
13-
static const pci = SensorAdaptor(pciRaw);
14-
static const virtual = SensorAdaptor(virtualRaw);
15-
static const isa = SensorAdaptor(isaRaw);
16-
1712
static SensorAdaptor parse(String raw) => switch (raw) {
18-
acpiRaw => acpi,
19-
pciRaw => pci,
20-
virtualRaw => virtual,
21-
isaRaw => isa,
13+
acpiRaw => const SensorAdaptor(acpiRaw),
14+
pciRaw => const SensorAdaptor(pciRaw),
15+
virtualRaw => const SensorAdaptor(virtualRaw),
16+
isaRaw => const SensorAdaptor(isaRaw),
2217
_ => SensorAdaptor(raw),
2318
};
2419
}

0 commit comments

Comments
 (0)