Cleanup code #17

Merged
Jeremy Kescher merged 2 commits from jeremy/0129/cleanup into master 2020-01-29 09:40:48 +00:00
3 changed files with 62 additions and 111 deletions

View File

@ -1,4 +1,4 @@
enum ServerStatus { unknown, ok, notok, timeout, dnserror, toomanyredirects }
enum ServerStatus { unknown, ok, notok, timeout, dnserror }
class Server {
String displayName;

View File

@ -11,15 +11,6 @@ import 'server.dart';
class ServerList extends StatefulWidget {
ServerList({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
@ -27,6 +18,7 @@ class ServerList extends StatefulWidget {
}
class _ServerListState extends State<ServerList> {
// Currently expanded server list entry, -1 = no field is expanded
int selectedServer = -1;
List<Server> servers = [
new Server(
@ -44,7 +36,7 @@ class _ServerListState extends State<ServerList> {
new Server(
"Raspberry Pi",
"https://pi.kescher.at/isup",
)
),
];
Timer timer;
@ -55,9 +47,8 @@ class _ServerListState extends State<ServerList> {
super.initState();
_updateAllServers();
timer = new Timer.periodic(new Duration(seconds: 30), (timer) {
_updateAllServers();
});
timer = new Timer.periodic(
new Duration(seconds: 30), (_) => _updateAllServers());
}
void _updateAllServers() async {
@ -65,11 +56,7 @@ class _ServerListState extends State<ServerList> {
}
void _updateServerStatus(Server s) {
_checkStatus(s.uri).then((value) {
setState(() {
s.status = value;
});
});
_checkStatus(s.uri).then((value) => setState(() => s.status = value));
}
@override
@ -263,7 +250,7 @@ class _ServerListState extends State<ServerList> {
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Are you shure you want to delete ' +
title: Text('Are you sure you want to delete ' +
servers[index].displayName +
'?'),
content: Form(
@ -323,9 +310,7 @@ class _ServerListState extends State<ServerList> {
}
return GestureDetector(
onTap: () {
setState(() {
selectedServer = index;
});
setState(() => selectedServer = index);
print(index.toString() + " clicked");
},
child: Container(
@ -368,8 +353,7 @@ class _ServerListState extends State<ServerList> {
return list;
}
static Future<ServerStatus> _checkStatus(String uri,
{int iterations = 0}) async {
static Future<ServerStatus> _checkStatus(String uri) async {
Uri parsedUri;
try {
@ -378,126 +362,89 @@ class _ServerListState extends State<ServerList> {
return ServerStatus.dnserror;
}
if (parsedUri.isScheme("http") || parsedUri.isScheme("https")) {
InternetAddress ia;
try {
// Check if host is IP address
InternetAddress(parsedUri.host);
} catch (ArgumentError) /* Host is a DNS name */ {
try {
ia = InternetAddress(parsedUri.host);
return await _checkResponse(parsedUri, iterations);
} catch (ArgumentError) /* Host is a DNS name */ {
try {
var v4recs =
await DnsUtils.lookupRecord(parsedUri.host, RRecordType.A);
var v6recs =
await DnsUtils.lookupRecord(parsedUri.host, RRecordType.AAAA);
var v4 = await _getDNS(v4recs, RRecordType.A);
var v6 = await _getDNS(v6recs, RRecordType.AAAA);
if (v4 != "" && v6 != "") {
return ServerStatus.dnserror;
}
} catch (SocketException) {
var v4recs = await DnsUtils.lookupRecord(parsedUri.host, RRecordType.A);
var v6recs =
await DnsUtils.lookupRecord(parsedUri.host, RRecordType.AAAA);
var v4 = await _resolveHostname(v4recs, RRecordType.A);
var v6 = await _resolveHostname(v6recs, RRecordType.AAAA);
if (v4 != "" && v6 != "") {
return ServerStatus.dnserror;
}
return await _checkResponse(parsedUri, iterations);
} catch (SocketException) {
return ServerStatus.dnserror;
}
} else // non-HTTP scheme
return ServerStatus.unknown;
}
try {
return await _checkResponse(parsedUri);
} catch (TimeoutException) {
return ServerStatus.timeout;
}
}
Icon _generateIcon(Server server) {
var icon, color;
switch (server.status) {
case ServerStatus.unknown:
return new Icon(
Icons.sync,
color: Colors.blueGrey.shade400,
);
icon = Icons.timer;
color = Colors.blueGrey.shade400;
break;
case ServerStatus.ok:
return new Icon(
Icons.check_box,
color: Colors.green.shade400,
);
icon = Icons.check_box;
color = Colors.green.shade400;
break;
case ServerStatus.notok:
return new Icon(
Icons.indeterminate_check_box,
color: Colors.red,
);
icon = Icons.indeterminate_check_box;
color = Colors.red;
break;
case ServerStatus.timeout:
return new Icon(
Icons.timer_off,
color: Colors.yellowAccent.shade700,
);
icon = Icons.timer_off;
color = Colors.yellowAccent.shade700;
break;
case ServerStatus.dnserror:
return new Icon(
Icons.dns,
color: Colors.red.shade400,
);
icon = Icons.dns;
color = Colors.red.shade400;
break;
case ServerStatus.toomanyredirects:
return new Icon(
Icons.subdirectory_arrow_right,
color: Colors.red.shade400,
);
default:
icon = Icons.indeterminate_check_box;
color = Colors.red;
break;
}
return new Icon(icon, color: color);
}
static _getDNS(List<RRecord> records, RRecordType type) {
String _return;
static _resolveHostname(List<RRecord> records, RRecordType type) {
String ipAddress;
if (records == null) return ServerStatus.dnserror;
records.forEach((record) {
if (record != null) {
if (ipAddress != null) {
return;
}
if (record == null) {
if (ipAddress == null) {
// ignore: unrelated_type_equality_checks
if (record.rType == type) {
_return = record.data;
ipAddress = record.data;
}
}
});
if (_return == null) _return = "";
return _return;
if (ipAddress == null) ipAddress = "";
return ipAddress;
}
static Future<ServerStatus> _checkResponse(Uri uri, int iterations) async {
var scheme = uri.scheme;
var port = uri.port;
var host = uri.host;
var location = uri.path;
static Future<ServerStatus> _checkResponse(Uri uri) async {
var response = await HttpUtils.getForFullResponse(uri.toString())
.timeout(new Duration(seconds: 3));
for (int i = 0; i < 5; i++) {
var response = await HttpUtils.getForFullResponse(scheme + "://" + host,
headers: <String, String>{"Location": location})
.timeout(new Duration(seconds: 3));
if (response.statusCode > 199 && response.statusCode < 300) {
return ServerStatus.ok;
} else if (response.statusCode == HttpStatus.movedPermanently ||
response.statusCode == HttpStatus.found ||
response.statusCode == HttpStatus.temporaryRedirect ||
response.statusCode == HttpStatus.permanentRedirect) {
if (iterations < 5) return ServerStatus.toomanyredirects;
var responseLocation = response.headers["Location"];
if (responseLocation.startsWith("http://") ||
responseLocation.startsWith("https://")) {
return await _checkStatus(responseLocation,
iterations: iterations + 1);
}
location = responseLocation;
return await _checkStatus(
scheme + "://" + host + ":" + port.toString() + location,
iterations: iterations + 1);
} else {
return ServerStatus.notok;
}
if (response.statusCode > 199 && response.statusCode < 300) {
return ServerStatus.ok;
} else {
return ServerStatus.notok;
}
// Too many redirects
return ServerStatus.unknown;
}
}

View File

@ -26,8 +26,12 @@ dependencies:
# Needed for DNS lookup
basic_utils: ^2.4.8
# Needed for FAB menu
flutter_speed_dial: ^1.2.5
# Might be needed for FAB menu
# flutter_speed_dial: ^1.2.5
# Server list persistence
shared_preferences: ^0.5.6+1
dev_dependencies:
flutter_test: