Cleanup code #17
3 changed files with 62 additions and 111 deletions
|
@ -1,4 +1,4 @@
|
|||
enum ServerStatus { unknown, ok, notok, timeout, dnserror, toomanyredirects }
|
||||
enum ServerStatus { unknown, ok, notok, timeout, dnserror }
|
||||
|
||||
class Server {
|
||||
String displayName;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue