mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
opt.: sftp dl
This commit is contained in:
@@ -58,7 +58,7 @@ Future<SSHClient> genClient(
|
|||||||
Spi? jumpSpi,
|
Spi? jumpSpi,
|
||||||
|
|
||||||
/// Handle keyboard-interactive authentication
|
/// Handle keyboard-interactive authentication
|
||||||
FutureOr<List<String>?> Function(SSHUserInfoRequest)? onKeyboardInteractive,
|
SSHUserInfoRequestHandler? onKeyboardInteractive,
|
||||||
}) async {
|
}) async {
|
||||||
onStatus?.call(GenSSHClientStatus.socket);
|
onStatus?.call(GenSSHClientStatus.socket);
|
||||||
|
|
||||||
|
|||||||
@@ -99,16 +99,21 @@ Future<void> _download(
|
|||||||
mainSendPort.send(size);
|
mainSendPort.send(size);
|
||||||
mainSendPort.send(SftpWorkerStatus.loading);
|
mainSendPort.send(SftpWorkerStatus.loading);
|
||||||
|
|
||||||
// Read 2m each time
|
|
||||||
// Issue #161
|
// Issue #161
|
||||||
// The download speed is about 2m/s may due to single core performance
|
// Due to single core performance, limit the chunk size
|
||||||
const defaultChunkSize = 1024 * 1024 * 2;
|
const defaultChunkSize = 1024 * 1024 * 5;
|
||||||
final chunkSize = size > defaultChunkSize ? defaultChunkSize : size;
|
var totalRead = 0;
|
||||||
for (var i = 0; i < size; i += chunkSize) {
|
|
||||||
final fileData = file.read(length: chunkSize);
|
while (totalRead < size) {
|
||||||
await for (var form in fileData) {
|
final remaining = size - totalRead;
|
||||||
localFile.add(form);
|
final chunkSize = remaining > defaultChunkSize ? defaultChunkSize : remaining;
|
||||||
mainSendPort.send((i + form.length) / size * 100);
|
dprint('Size: $size, Total Read: $totalRead, Chunk Size: $chunkSize');
|
||||||
|
|
||||||
|
final fileData = file.read(offset: totalRead, length: chunkSize);
|
||||||
|
await for (var chunk in fileData) {
|
||||||
|
localFile.add(chunk);
|
||||||
|
totalRead += chunk.length;
|
||||||
|
mainSendPort.send(totalRead / size * 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,7 @@ extension _Init on SSHPageState {
|
|||||||
void _initStoredCfg() {
|
void _initStoredCfg() {
|
||||||
final fontFamilly = Stores.setting.fontPath.fetch().getFileName();
|
final fontFamilly = Stores.setting.fontPath.fetch().getFileName();
|
||||||
final textSize = Stores.setting.termFontSize.fetch();
|
final textSize = Stores.setting.termFontSize.fetch();
|
||||||
final textStyle = TextStyle(
|
final textStyle = TextStyle(fontFamily: fontFamilly, fontSize: textSize);
|
||||||
fontFamily: fontFamilly,
|
|
||||||
fontSize: textSize,
|
|
||||||
);
|
|
||||||
|
|
||||||
_terminalStyle = TerminalStyle.fromTextStyle(textStyle);
|
_terminalStyle = TerminalStyle.fromTextStyle(textStyle);
|
||||||
}
|
}
|
||||||
@@ -37,15 +34,12 @@ extension _Init on SSHPageState {
|
|||||||
onStatus: (p0) {
|
onStatus: (p0) {
|
||||||
_writeLn(p0.toString());
|
_writeLn(p0.toString());
|
||||||
},
|
},
|
||||||
onKeyboardInteractive: _onKeyboardInteractive,
|
onKeyboardInteractive: (_) => KeybordInteractive.defaultHandle(widget.args.spi, ctx: context),
|
||||||
);
|
);
|
||||||
|
|
||||||
_writeLn('${libL10n.execute}: Shell');
|
_writeLn('${libL10n.execute}: Shell');
|
||||||
final session = await _client?.shell(
|
final session = await _client?.shell(
|
||||||
pty: SSHPtyConfig(
|
pty: SSHPtyConfig(width: _terminal.viewWidth, height: _terminal.viewHeight),
|
||||||
width: _terminal.viewWidth,
|
|
||||||
height: _terminal.viewHeight,
|
|
||||||
),
|
|
||||||
environment: widget.args.spi.envs,
|
environment: widget.args.spi.envs,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -98,30 +92,30 @@ extension _Init on SSHPageState {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.cast<List<int>>().transform(const Utf8Decoder()).listen(
|
stream
|
||||||
_terminal.write,
|
.cast<List<int>>()
|
||||||
onError: (Object error, StackTrace stack) {
|
.transform(const Utf8Decoder())
|
||||||
// _terminal.write('Stream error: $error\n');
|
.listen(
|
||||||
Loggers.root.warning('Error in SSH stream', error, stack);
|
_terminal.write,
|
||||||
},
|
onError: (Object error, StackTrace stack) {
|
||||||
cancelOnError: false,
|
// _terminal.write('Stream error: $error\n');
|
||||||
);
|
Loggers.root.warning('Error in SSH stream', error, stack);
|
||||||
|
},
|
||||||
|
cancelOnError: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setupDiscontinuityTimer() {
|
void _setupDiscontinuityTimer() {
|
||||||
_discontinuityTimer = Timer.periodic(
|
_discontinuityTimer = Timer.periodic(const Duration(seconds: 5), (_) async {
|
||||||
const Duration(seconds: 5),
|
var throwTimeout = true;
|
||||||
(_) async {
|
Future.delayed(const Duration(seconds: 3), () {
|
||||||
var throwTimeout = true;
|
if (throwTimeout) {
|
||||||
Future.delayed(const Duration(seconds: 3), () {
|
_catchTimeout();
|
||||||
if (throwTimeout) {
|
}
|
||||||
_catchTimeout();
|
});
|
||||||
}
|
await _client?.ping();
|
||||||
});
|
throwTimeout = false;
|
||||||
await _client?.ping();
|
});
|
||||||
throwTimeout = false;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _catchTimeout() {
|
void _catchTimeout() {
|
||||||
|
|||||||
@@ -164,8 +164,4 @@ extension _VirtKey on SSHPageState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FutureOr<List<String>?> _onKeyboardInteractive(SSHUserInfoRequest req) {
|
|
||||||
return KeybordInteractive.defaultHandle(widget.args.spi, ctx: context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,11 +73,24 @@ class _LocalFilePageState extends State<LocalFilePage> with AutomaticKeepAliveCl
|
|||||||
},
|
},
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
),
|
),
|
||||||
|
if (!isMobile)
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.refresh),
|
||||||
|
tooltip: MaterialLocalizations.of(context).refreshIndicatorSemanticLabel,
|
||||||
|
onPressed: () => setState(() {}),
|
||||||
|
),
|
||||||
if (!isPickFile) _buildMissionBtn(),
|
if (!isPickFile) _buildMissionBtn(),
|
||||||
_buildSortBtn(),
|
_buildSortBtn(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: _sortType.listen(_buildBody),
|
body: isMobile
|
||||||
|
? RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: _sortType.listen(_buildBody),
|
||||||
|
)
|
||||||
|
: _sortType.listen(_buildBody),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ extension _Actions on _SftpPageState {
|
|||||||
|
|
||||||
/// Local file dir + server id + remote path
|
/// Local file dir + server id + remote path
|
||||||
String _getLocalPath(String remotePath) {
|
String _getLocalPath(String remotePath) {
|
||||||
return Paths.file.joinPath(widget.args.spi.id).joinPath(remotePath);
|
return Paths.file.joinPath(widget.args.spi.oldId).joinPath(remotePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Only return true if the path is changed
|
/// Only return true if the path is changed
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.4+2"
|
version: "0.3.4+2"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
|
||||||
|
|||||||
35
pubspec.yaml
35
pubspec.yaml
@@ -12,29 +12,30 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
hive_ce_flutter: ^2.3.1
|
choice: ^2.3.2
|
||||||
|
crypto: ^3.0.6
|
||||||
dio: ^5.2.1
|
dio: ^5.2.1
|
||||||
easy_isolate: ^1.3.0
|
|
||||||
intl: ^0.20.2
|
|
||||||
highlight: ^0.7.0
|
|
||||||
flutter_highlight: ^0.7.0
|
|
||||||
re_editor: ^0.7.0
|
|
||||||
shared_preferences: ^2.1.1
|
|
||||||
dynamic_color: ^1.6.6
|
dynamic_color: ^1.6.6
|
||||||
xml: ^6.4.2 # for parsing nvidia-smi
|
easy_isolate: ^1.3.0
|
||||||
flutter_displaymode: ^0.6.0
|
|
||||||
fl_chart: ^1.0.0
|
|
||||||
wakelock_plus: ^1.2.4
|
|
||||||
wake_on_lan: ^4.1.1+3
|
|
||||||
extended_image: ^10.0.0
|
extended_image: ^10.0.0
|
||||||
file_picker: ^10.1.9
|
file_picker: ^10.1.9
|
||||||
json_annotation: ^4.9.0
|
|
||||||
choice: ^2.3.2
|
|
||||||
webdav_client_plus: ^1.0.2
|
|
||||||
freezed_annotation: ^3.0.0
|
|
||||||
flutter_riverpod: ^2.6.1
|
flutter_riverpod: ^2.6.1
|
||||||
riverpod_annotation: ^2.6.1
|
flutter_highlight: ^0.7.0
|
||||||
|
flutter_displaymode: ^0.6.0
|
||||||
|
fl_chart: ^1.0.0
|
||||||
|
freezed_annotation: ^3.0.0
|
||||||
|
highlight: ^0.7.0
|
||||||
|
hive_ce_flutter: ^2.3.1
|
||||||
|
intl: ^0.20.2
|
||||||
|
json_annotation: ^4.9.0
|
||||||
responsive_framework: ^1.5.1
|
responsive_framework: ^1.5.1
|
||||||
|
re_editor: ^0.7.0
|
||||||
|
riverpod_annotation: ^2.6.1
|
||||||
|
shared_preferences: ^2.1.1
|
||||||
|
wakelock_plus: ^1.2.4
|
||||||
|
wake_on_lan: ^4.1.1+3
|
||||||
|
webdav_client_plus: ^1.0.2
|
||||||
|
xml: ^6.4.2 # for parsing nvidia-smi
|
||||||
dartssh2:
|
dartssh2:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/lollipopkit/dartssh2
|
url: https://github.com/lollipopkit/dartssh2
|
||||||
|
|||||||
Reference in New Issue
Block a user