Skip to content

Commit

Permalink
Merge pull request #27 from bostrot/quick_settings_feature
Browse files Browse the repository at this point in the history
Added LXC repo, stdin & stdout listener
  • Loading branch information
bostrot authored Apr 15, 2022
2 parents 176cc11 + b3ee45e commit 7b2c3a2
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 130 deletions.
97 changes: 89 additions & 8 deletions lib/components/api.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:io';
import 'dart:convert' show utf8, json;
import 'dart:convert' show Utf8Decoder, json, utf8;
import 'package:dio/dio.dart';
import 'constants.dart';
import 'helpers.dart';
Expand Down Expand Up @@ -247,6 +248,56 @@ class WSLApi {
return results.stdout;
}

List<String> resultQueue = [];

/// Get the current cached output
/// @return String
String getCurrentOutput() {
String tmp = resultQueue.join('\n');
resultQueue = [];
return tmp;
}

/// Executes a command list in a WSL distro
/// @param distribution: String
/// @param cmd: List<String>
/// @return Future<List<int>>
Future<List<int>> execCmds(
String distribution,
List<String> cmds, {
required Function(String) onMsg,
required Function onDone,
}) async {
List<int> processes = [];
Process result = await Process.start(
'wsl', ['-d', distribution, '-u', 'root'],
mode: ProcessStartMode.detachedWithStdio);

Timer currentWaiter = Timer(const Duration(seconds: 15), () {
result.kill();
onDone();
});

result.stdout
.cast<List<int>>()
.transform(const Utf8Decoder())
.listen((String line) {
resultQueue.add(line);
onMsg(line);
currentWaiter.cancel();
// No new output within the last 30 seconds
currentWaiter = Timer(const Duration(seconds: 15), () {
result.kill();
onDone();
});
});

for (var cmd in cmds) {
result.stdin.writeln(cmd);
}
return processes;
}

/// Executes a command in a WSL distro. passwd will open a shell
/// @param distribution: String
/// @param cmd: List<String>
Expand Down Expand Up @@ -307,8 +358,8 @@ class WSLApi {
/// @param installPath: String distro name or tar file
/// @param filename: String
/// @return Future<String>
Future<dynamic> create(
String distribution, String filename, String installPath) async {
Future<dynamic> create(String distribution, String filename,
String installPath, Function(String) status) async {
if (installPath == '') {
installPath = defaultPath + distribution;
}
Expand All @@ -320,10 +371,15 @@ class WSLApi {
!(await File(downloadPath).exists())) {
String url = distroRootfsLinks[filename]!;
// Download file
Dio dio = Dio();
Response response = await dio.download(url, downloadPath);
if (response.statusCode != 200) {
return response;
try {
Dio dio = Dio();
await dio.download(url, downloadPath,
onReceiveProgress: (int count, int total) {
status('Step 1: Downloading distro: '
'${(count / total * 100).toStringAsFixed(0)}%');
});
} catch (error) {
status('Error downloading: $error');
}
}

Expand Down Expand Up @@ -401,7 +457,32 @@ class WSLApi {
nameStarted = true;
}
});*/
List<String> list = distroRootfsLinks.keys.toList();
// Get even more distros
String repoLink =
"http://ftp.halifax.rwth-aachen.de/turnkeylinux/images/proxmox/";
await Dio().get(repoLink).then((value) => {
value.data.split('\n').forEach((line) {
if (line.contains('tar.gz"') &&
line.contains('href=') &&
(line.contains('debian-10') || line.contains('debian-11'))) {
String name = line
.split('href="')[1]
.split('"')[0]
.toString()
.replaceAll('.tar.gz', '')
.replaceAll('1_amd64', '')
.replaceAll(RegExp(r'-|_'), ' ')
.replaceAllMapped(RegExp(r' .|^.'),
(Match m) => m[0].toString().toUpperCase());
distroRootfsLinks.addAll({
name:
repoLink + line.split('href="')[1].split('"')[0].toString()
});
}
})
});
List<String> list = [];
list.addAll(distroRootfsLinks.keys);
return list;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/components/constants.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO: Update on release
const String currentVersion = "v0.9.1";
const String currentVersion = "v1.0.0";
const String windowsStoreUrl = "https://www.microsoft.com/store/"
"productId/9NWS9K95NMJB";
const String defaultPath = 'C:\\WSL2-Distros\\';
Expand All @@ -11,7 +11,7 @@ const String motdUrl =
'https://raw.githubusercontent.com/bostrot/wsl2-distro-manager/main/motd.json';

// https://docs.microsoft.com/en-us/windows/wsl/install-on-server
const Map<String, String> distroRootfsLinks = {
Map<String, String> distroRootfsLinks = {
'Ubuntu 21.04':
'https://cloud-images.ubuntu.com/releases/hirsute/release/ubuntu-21.04-server-cloudimg-amd64-wsl.rootfs.tar.gz',
'Ubuntu 20.04':
Expand Down
11 changes: 11 additions & 0 deletions lib/components/list.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:wsl2distromanager/components/api.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:wsl2distromanager/dialogs/dialogs.dart';
Expand Down Expand Up @@ -28,9 +30,17 @@ class _DistroListState extends State<DistroList> {
@override
void initState() {
initPrefs();
reloadEvery5Seconds();
super.initState();
}

void reloadEvery5Seconds() async {
for (;;) {
await Future.delayed(const Duration(seconds: 5));
setState(() {});
}
}

@override
Widget build(BuildContext context) {
return distroList(widget.api, widget.statusMsg, hover);
Expand All @@ -43,6 +53,7 @@ FutureBuilder<Instances> distroList(WSLApi api,
return FutureBuilder<Instances>(
future: api.list(),
builder: (context, snapshot) {
// Update every 20 seconds
if (snapshot.hasData) {
List<Widget> newList = [];
List<String> list = snapshot.data?.all ?? [];
Expand Down
1 change: 1 addition & 0 deletions lib/dialogs/base_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dialog({
context: context,
builder: (context) {
return ContentDialog(
constraints: const BoxConstraints(maxHeight: 300.0, maxWidth: 400.0),
title: centerText ? Center(child: Text(title)) : Text(title),
content: Column(
children: [
Expand Down
Loading

0 comments on commit 7b2c3a2

Please sign in to comment.