mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
ready for more pkg manager
This commit is contained in:
BIN
assets/linux/freebsd.png
Normal file
BIN
assets/linux/freebsd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 289 KiB |
BIN
assets/linux/rocky.png
Normal file
BIN
assets/linux/rocky.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -2,26 +2,10 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:toolbox/data/model/distribution.dart';
|
|
||||||
|
|
||||||
extension StringX on String {
|
extension StringX on String {
|
||||||
int get i => int.parse(this);
|
int get i => int.parse(this);
|
||||||
|
|
||||||
Distribution get dist {
|
|
||||||
final lower = toLowerCase();
|
|
||||||
for (var dist in debianDistList) {
|
|
||||||
if (lower.contains(dist)) {
|
|
||||||
return Distribution.debian;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var dist in rehlDistList) {
|
|
||||||
if (lower.contains(dist)) {
|
|
||||||
return Distribution.rehl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Distribution.unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uri get uri {
|
Uri get uri {
|
||||||
return Uri.parse(this);
|
return Uri.parse(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'package:toolbox/data/model/distribution.dart';
|
import 'package:toolbox/data/model/server/dist.dart';
|
||||||
|
|
||||||
class UpgradePkgInfo {
|
class UpgradePkgInfo {
|
||||||
final String _raw;
|
final String _raw;
|
||||||
final Distribution _dist;
|
final Dist _dist;
|
||||||
|
|
||||||
late String package;
|
late String package;
|
||||||
late String nowVersion;
|
late String nowVersion;
|
||||||
@@ -11,12 +11,15 @@ class UpgradePkgInfo {
|
|||||||
|
|
||||||
UpgradePkgInfo(this._raw, this._dist) {
|
UpgradePkgInfo(this._raw, this._dist) {
|
||||||
switch (_dist) {
|
switch (_dist) {
|
||||||
case Distribution.debian:
|
case Dist.debian:
|
||||||
case Distribution.unknown:
|
case Dist.ubuntu:
|
||||||
_parseApt();
|
_parseApt();
|
||||||
break;
|
break;
|
||||||
case Distribution.rehl:
|
case Dist.centos:
|
||||||
_parseYum();
|
_parseYum();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception('Unsupported dist: $_dist');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
enum Distribution {
|
|
||||||
unknown,
|
|
||||||
debian,
|
|
||||||
rehl,
|
|
||||||
}
|
|
||||||
|
|
||||||
const debianDistList = [
|
|
||||||
'debian',
|
|
||||||
'ubuntu',
|
|
||||||
'linuxmint',
|
|
||||||
'elementary',
|
|
||||||
'raspbian',
|
|
||||||
'armbian'
|
|
||||||
];
|
|
||||||
|
|
||||||
const rehlDistList = [
|
|
||||||
'redhat',
|
|
||||||
'fedora',
|
|
||||||
'centos',
|
|
||||||
'scientificlinux',
|
|
||||||
'rhel',
|
|
||||||
'oraclelinux'
|
|
||||||
];
|
|
||||||
30
lib/data/model/server/dist.dart
Normal file
30
lib/data/model/server/dist.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
enum Dist {
|
||||||
|
debian,
|
||||||
|
ubuntu,
|
||||||
|
centos,
|
||||||
|
fedora,
|
||||||
|
opensuse,
|
||||||
|
kali,
|
||||||
|
wrt,
|
||||||
|
armbian,
|
||||||
|
arch,
|
||||||
|
freebsd,
|
||||||
|
/// Rocky Linux
|
||||||
|
rocky;
|
||||||
|
|
||||||
|
String? get iconPath {
|
||||||
|
return 'assets/linux/$name.png';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension StringX on String {
|
||||||
|
Dist? get dist {
|
||||||
|
final lower = toLowerCase();
|
||||||
|
for (final dist in Dist.values) {
|
||||||
|
if (lower.contains(dist.name)) {
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,13 +8,16 @@ import 'package:toolbox/core/extension/stringx.dart';
|
|||||||
import 'package:toolbox/core/extension/uint8list.dart';
|
import 'package:toolbox/core/extension/uint8list.dart';
|
||||||
import 'package:toolbox/core/provider_base.dart';
|
import 'package:toolbox/core/provider_base.dart';
|
||||||
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
|
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
|
||||||
import 'package:toolbox/data/model/distribution.dart';
|
import 'package:toolbox/data/model/server/dist.dart';
|
||||||
|
|
||||||
|
enum _Type { apt, yum, dnf, zypper, pkg, pacman, opkg }
|
||||||
|
|
||||||
class AptProvider extends BusyProvider {
|
class AptProvider extends BusyProvider {
|
||||||
final logger = Logger('AptProvider');
|
final logger = Logger('AptProvider');
|
||||||
|
|
||||||
SSHClient? client;
|
SSHClient? client;
|
||||||
Distribution? dist;
|
Dist? dist;
|
||||||
|
_Type? type;
|
||||||
Function()? onUpgrade;
|
Function()? onUpgrade;
|
||||||
Function()? onUpdate;
|
Function()? onUpdate;
|
||||||
PwdRequestFunc? onPasswordRequest;
|
PwdRequestFunc? onPasswordRequest;
|
||||||
@@ -31,7 +34,7 @@ class AptProvider extends BusyProvider {
|
|||||||
|
|
||||||
Future<void> init(
|
Future<void> init(
|
||||||
SSHClient client,
|
SSHClient client,
|
||||||
Distribution dist,
|
Dist? dist,
|
||||||
Function() onUpgrade,
|
Function() onUpgrade,
|
||||||
Function() onUpdate,
|
Function() onUpdate,
|
||||||
PwdRequestFunc onPasswordRequest,
|
PwdRequestFunc onPasswordRequest,
|
||||||
@@ -41,6 +44,37 @@ class AptProvider extends BusyProvider {
|
|||||||
this.onUpgrade = onUpgrade;
|
this.onUpgrade = onUpgrade;
|
||||||
this.onPasswordRequest = onPasswordRequest;
|
this.onPasswordRequest = onPasswordRequest;
|
||||||
whoami = user;
|
whoami = user;
|
||||||
|
|
||||||
|
switch (dist) {
|
||||||
|
case Dist.centos:
|
||||||
|
case Dist.rocky:
|
||||||
|
type = _Type.yum;
|
||||||
|
break;
|
||||||
|
case Dist.debian:
|
||||||
|
case Dist.ubuntu:
|
||||||
|
case Dist.kali:
|
||||||
|
case Dist.armbian:
|
||||||
|
type = _Type.apt;
|
||||||
|
break;
|
||||||
|
case Dist.fedora:
|
||||||
|
type = _Type.dnf;
|
||||||
|
break;
|
||||||
|
case Dist.opensuse:
|
||||||
|
type = _Type.zypper;
|
||||||
|
break;
|
||||||
|
case Dist.freebsd:
|
||||||
|
type = _Type.pkg;
|
||||||
|
break;
|
||||||
|
case Dist.wrt:
|
||||||
|
type = _Type.opkg;
|
||||||
|
break;
|
||||||
|
case Dist.arch:
|
||||||
|
type = _Type.pacman;
|
||||||
|
break;
|
||||||
|
case null:
|
||||||
|
error = 'Unsupported dist: $dist';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isSU => whoami == 'root';
|
bool get isSU => whoami == 'root';
|
||||||
@@ -51,10 +85,10 @@ class AptProvider extends BusyProvider {
|
|||||||
isRequestingPwd = false;
|
isRequestingPwd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> refreshInstalled() async {
|
Future<void> refresh() async {
|
||||||
final result = await _update();
|
final result = await _update();
|
||||||
try {
|
try {
|
||||||
getUpgradeableList(result);
|
_parse(result);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = '[Server Raw]:\n$result\n[App Error]:\n$e';
|
error = '[Server Raw]:\n$result\n[App Error]:\n$e';
|
||||||
} finally {
|
} finally {
|
||||||
@@ -62,18 +96,18 @@ class AptProvider extends BusyProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getUpgradeableList(String? raw) {
|
void _parse(String? raw) {
|
||||||
if (raw == null) return;
|
if (raw == null) return;
|
||||||
var list = raw.split('\n');
|
var list = raw.split('\n');
|
||||||
switch (dist) {
|
switch (type) {
|
||||||
case Distribution.rehl:
|
case _Type.yum:
|
||||||
list = list.sublist(2);
|
list = list.sublist(2);
|
||||||
list.removeWhere((element) => element.isEmpty);
|
list.removeWhere((element) => element.isEmpty);
|
||||||
final endLine = list.lastIndexWhere(
|
final endLine = list.lastIndexWhere(
|
||||||
(element) => element.contains('Obsoleting Packages'));
|
(element) => element.contains('Obsoleting Packages'));
|
||||||
list = list.sublist(0, endLine);
|
list = list.sublist(0, endLine);
|
||||||
break;
|
break;
|
||||||
default:
|
case _Type.apt:
|
||||||
// avoid other outputs
|
// avoid other outputs
|
||||||
// such as: [Could not chdir to home directory /home/test: No such file or directory, , WARNING: apt does not have a stable CLI interface. Use with caution in scripts., , Listing...]
|
// such as: [Could not chdir to home directory /home/test: No such file or directory, , WARNING: apt does not have a stable CLI interface. Use with caution in scripts., , Listing...]
|
||||||
final idx =
|
final idx =
|
||||||
@@ -84,15 +118,18 @@ class AptProvider extends BusyProvider {
|
|||||||
}
|
}
|
||||||
list = list.sublist(idx);
|
list = list.sublist(idx);
|
||||||
list.removeWhere((element) => element.isEmpty);
|
list.removeWhere((element) => element.isEmpty);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
upgradeable = list.map((e) => UpgradePkgInfo(e, dist!)).toList();
|
upgradeable = list.map((e) => UpgradePkgInfo(e, dist!)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> _update() async {
|
Future<String?> _update() async {
|
||||||
switch (dist) {
|
switch (type) {
|
||||||
case Distribution.rehl:
|
case _Type.yum:
|
||||||
return await client?.run(_wrap('yum check-update')).string;
|
return await client?.run(_wrap('yum check-update')).string;
|
||||||
default:
|
case _Type.apt:
|
||||||
await client!.exec(
|
await client!.exec(
|
||||||
_wrap('apt update'),
|
_wrap('apt update'),
|
||||||
onStderr: _onPwd,
|
onStderr: _onPwd,
|
||||||
@@ -105,19 +142,29 @@ class AptProvider extends BusyProvider {
|
|||||||
return await client
|
return await client
|
||||||
?.run('apt list --upgradeable'.withLangExport)
|
?.run('apt list --upgradeable'.withLangExport)
|
||||||
.string;
|
.string;
|
||||||
|
default:
|
||||||
|
error = 'Unsupported dist: $dist';
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> upgrade() async {
|
Future<void> upgrade() async {
|
||||||
final upgradeCmd = () {
|
final upgradeCmd = () {
|
||||||
switch (dist) {
|
switch (type) {
|
||||||
case Distribution.rehl:
|
case _Type.yum:
|
||||||
return 'yum upgrade -y';
|
return 'yum upgrade -y';
|
||||||
default:
|
case _Type.apt:
|
||||||
return 'apt upgrade -y';
|
return 'apt upgrade -y';
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
if (upgradeCmd == null) {
|
||||||
|
error = 'Unsupported dist: $dist';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await client!.exec(
|
await client!.exec(
|
||||||
_wrap(upgradeCmd),
|
_wrap(upgradeCmd),
|
||||||
onStderr: _onPwd,
|
onStderr: _onPwd,
|
||||||
@@ -131,7 +178,7 @@ class AptProvider extends BusyProvider {
|
|||||||
);
|
);
|
||||||
|
|
||||||
upgradeLog = null;
|
upgradeLog = null;
|
||||||
refreshInstalled();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onPwd(String event, StreamSink<Uint8List> stdin) async {
|
Future<void> _onPwd(String event, StreamSink<Uint8List> stdin) async {
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
final linuxIcons = LinuxIcons([
|
|
||||||
'ubuntu',
|
|
||||||
'arch',
|
|
||||||
'centos',
|
|
||||||
'debian',
|
|
||||||
'fedora',
|
|
||||||
'opensuse',
|
|
||||||
'kali',
|
|
||||||
'wrt',
|
|
||||||
'armbian'
|
|
||||||
]);
|
|
||||||
|
|
||||||
class LinuxIcons {
|
|
||||||
List<String> db;
|
|
||||||
|
|
||||||
LinuxIcons(this.db);
|
|
||||||
|
|
||||||
String? search(String sysVer) {
|
|
||||||
for (var item in db) {
|
|
||||||
if (sysVer.toLowerCase().contains(item)) {
|
|
||||||
return 'assets/linux/$item.png';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/extension/stringx.dart';
|
|
||||||
import 'package:toolbox/core/utils.dart';
|
import 'package:toolbox/core/utils.dart';
|
||||||
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
|
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
|
||||||
|
import 'package:toolbox/data/model/server/dist.dart';
|
||||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||||
import 'package:toolbox/data/provider/apt.dart';
|
import 'package:toolbox/data/provider/apt.dart';
|
||||||
import 'package:toolbox/data/provider/server.dart';
|
import 'package:toolbox/data/provider/server.dart';
|
||||||
@@ -68,7 +68,7 @@ class _AptManagePageState extends State<AptManagePage>
|
|||||||
onPwdRequest,
|
onPwdRequest,
|
||||||
widget.spi.user,
|
widget.spi.user,
|
||||||
);
|
);
|
||||||
_aptProvider.refreshInstalled();
|
_aptProvider.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSubmitted() {
|
void onSubmitted() {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import 'package:toolbox/data/provider/server.dart';
|
|||||||
import 'package:toolbox/data/res/build_data.dart';
|
import 'package:toolbox/data/res/build_data.dart';
|
||||||
import 'package:toolbox/data/res/color.dart';
|
import 'package:toolbox/data/res/color.dart';
|
||||||
import 'package:toolbox/data/res/font_style.dart';
|
import 'package:toolbox/data/res/font_style.dart';
|
||||||
import 'package:toolbox/data/res/icon/common.dart';
|
import 'package:toolbox/data/res/icon.dart';
|
||||||
import 'package:toolbox/data/res/tab.dart';
|
import 'package:toolbox/data/res/tab.dart';
|
||||||
import 'package:toolbox/data/res/url.dart';
|
import 'package:toolbox/data/res/url.dart';
|
||||||
import 'package:toolbox/data/store/setting.dart';
|
import 'package:toolbox/data/store/setting.dart';
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:toolbox/core/extension/numx.dart';
|
import 'package:toolbox/core/extension/numx.dart';
|
||||||
|
import 'package:toolbox/data/model/server/dist.dart';
|
||||||
import 'package:toolbox/data/model/server/net_speed.dart';
|
import 'package:toolbox/data/model/server/net_speed.dart';
|
||||||
import 'package:toolbox/data/model/server/server.dart';
|
import 'package:toolbox/data/model/server/server.dart';
|
||||||
import 'package:toolbox/data/model/server/server_status.dart';
|
import 'package:toolbox/data/model/server/server_status.dart';
|
||||||
import 'package:toolbox/data/provider/server.dart';
|
import 'package:toolbox/data/provider/server.dart';
|
||||||
import 'package:toolbox/data/res/color.dart';
|
import 'package:toolbox/data/res/color.dart';
|
||||||
import 'package:toolbox/data/res/font_style.dart';
|
import 'package:toolbox/data/res/font_style.dart';
|
||||||
import 'package:toolbox/data/res/icon/linux_icons.dart';
|
|
||||||
import 'package:toolbox/data/res/padding.dart';
|
import 'package:toolbox/data/res/padding.dart';
|
||||||
import 'package:toolbox/generated/l10n.dart';
|
import 'package:toolbox/generated/l10n.dart';
|
||||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||||
@@ -67,7 +67,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildLinuxIcon(String sysVer) {
|
Widget _buildLinuxIcon(String sysVer) {
|
||||||
final iconPath = linuxIcons.search(sysVer);
|
final iconPath = sysVer.dist?.iconPath;
|
||||||
if (iconPath == null) return const SizedBox();
|
if (iconPath == null) return const SizedBox();
|
||||||
return ConstrainedBox(
|
return ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
|
|||||||
Reference in New Issue
Block a user