Added utils to connect to server.
This commit is contained in:
parent
82f002998b
commit
cdc04a3401
|
@ -1,84 +0,0 @@
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:logger/logger.dart';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
|
|
||||||
final log = Logger();
|
|
||||||
|
|
||||||
|
|
||||||
class Connection {
|
|
||||||
// Connection constructor.
|
|
||||||
Connection(this.username, this.password, this.baseAddress);
|
|
||||||
// baseAddress contains the base address to the BotZ server
|
|
||||||
// assuming that the APIs are located at /api/.
|
|
||||||
final String baseAddress;
|
|
||||||
// Username is the username to autenticate against the foreign
|
|
||||||
// service.
|
|
||||||
final String username;
|
|
||||||
// Password is the password to autenticate against the foreign
|
|
||||||
// service.
|
|
||||||
final String password;
|
|
||||||
// _stateCookie is private. It contains the HTTP state cookie
|
|
||||||
// assigned by the server.
|
|
||||||
String _stateCookie = "";
|
|
||||||
bool _loggedIn = false;
|
|
||||||
|
|
||||||
|
|
||||||
void login() async {
|
|
||||||
// TODO: perform the login and obtain the cookie. Set the
|
|
||||||
// _loggedIn state accordingly.
|
|
||||||
}
|
|
||||||
void logout() async {
|
|
||||||
// TODO: perform the logout. If successful, empty the _stateCookie
|
|
||||||
// and set the _loggedIn state accordingly.
|
|
||||||
}
|
|
||||||
void checkin() async {
|
|
||||||
// TODO: perform the checkin if possible.
|
|
||||||
}
|
|
||||||
void checkout() async {
|
|
||||||
// TODO: perform the checkout if possible.
|
|
||||||
}
|
|
||||||
Future<Map<String, dynamic>> getMovements() async {
|
|
||||||
// TODO: query /api/movements and retrieve the list of movements.
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class UnauthorizedException implements ClientException {
|
|
||||||
UnauthorizedException(this.uri);
|
|
||||||
final String message = "Unauthorized";
|
|
||||||
final Uri uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Response handleResponse(Response resp) {
|
|
||||||
final c = resp.statusCode;
|
|
||||||
if (c >= 200 && c < 400) {
|
|
||||||
} else if (c == 401) {
|
|
||||||
throw UnauthorizedException(resp.request.url);
|
|
||||||
} else if (c >=400 || c < 500) {
|
|
||||||
throw ClientException("Unexpected return code: $c", resp.request.url);
|
|
||||||
} else if (c >= 500) {
|
|
||||||
throw ClientException("Server error: $c", resp.request.url);
|
|
||||||
}
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class BotZContent {
|
|
||||||
BotZContent(this.response) {
|
|
||||||
this.response.then((resp) => handleResponse(resp))
|
|
||||||
.then((value) => this.initContent(value))
|
|
||||||
.catchError((err) => log.e(err));
|
|
||||||
}
|
|
||||||
final Future<Response> response;
|
|
||||||
Map<String, dynamic> body;
|
|
||||||
List<String> cookies;
|
|
||||||
|
|
||||||
void initContent(Response resp) {
|
|
||||||
this.cookies = resp.headers['cookies'].split(';');
|
|
||||||
this.body = jsonDecode(resp.body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
189
lib/utils/connection.dart
Normal file
189
lib/utils/connection.dart
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:logger/logger.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
|
||||||
|
final log = Logger();
|
||||||
|
const defaultRoutes = {
|
||||||
|
"login": "/api/login",
|
||||||
|
"logout": "/api/logout",
|
||||||
|
"checkin": "/api/checkin",
|
||||||
|
"checkout": "/api/checkout",
|
||||||
|
"movements": "/api/movements",
|
||||||
|
"status": "/api/status",
|
||||||
|
"ping": "/api/ping",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Connection {
|
||||||
|
// Connection constructor.
|
||||||
|
Connection(this.username, this.password, this.baseAddress, [this.routes = defaultRoutes]);
|
||||||
|
// baseAddress contains the base address to the BotZ server
|
||||||
|
final Uri baseAddress;
|
||||||
|
// Username is the username to autenticate against the foreign
|
||||||
|
// service.
|
||||||
|
final String username;
|
||||||
|
// Password is the password to autenticate against the foreign
|
||||||
|
// service.
|
||||||
|
final String password;
|
||||||
|
final Map<String, String> routes;
|
||||||
|
// _stateCookie is private. It contains the HTTP state cookie
|
||||||
|
// assigned by the server.
|
||||||
|
String _cookies = "";
|
||||||
|
bool _loggedIn = false;
|
||||||
|
bool _checkedIn = false;
|
||||||
|
|
||||||
|
void updateState(String cookies, bool loggedIn) {
|
||||||
|
this._cookies = loggedIn ? cookies : "";
|
||||||
|
this._loggedIn = loggedIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMovement(bool checkedIn) => this._checkedIn = checkedIn;
|
||||||
|
|
||||||
|
bool isLoggedIn() => this._loggedIn;
|
||||||
|
|
||||||
|
bool isCheckedIn() => this._checkedIn;
|
||||||
|
|
||||||
|
// Perform the login and obtain the cookie.
|
||||||
|
void login() async {
|
||||||
|
var targetUri = this.baseAddress.toString() + this.routes['login'];
|
||||||
|
var payload = jsonEncode({
|
||||||
|
"username": this.username,
|
||||||
|
"password": this.password,
|
||||||
|
});
|
||||||
|
|
||||||
|
var resp = await post(
|
||||||
|
targetUri,
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: payload,
|
||||||
|
);
|
||||||
|
|
||||||
|
log.d("[login] Post sent to: $targetUri");
|
||||||
|
handleResponse(resp);
|
||||||
|
var body = jsonDecode(resp.body);
|
||||||
|
log.d("[login] Response: $body");
|
||||||
|
this.updateState(resp.headers['cookies'], body['logged_in']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the logout.
|
||||||
|
void logout() async {
|
||||||
|
var targetUri = this.baseAddress.toString() + this.routes['logout'];
|
||||||
|
|
||||||
|
var resp = await post(
|
||||||
|
targetUri,
|
||||||
|
headers: {'cookies': this._cookies},
|
||||||
|
);
|
||||||
|
|
||||||
|
log.d("[logout] Post sent to: $targetUri");
|
||||||
|
handleResponse(resp);
|
||||||
|
var body = jsonDecode(resp.body);
|
||||||
|
log.d("[logout] Response: $body");
|
||||||
|
this.updateState(this._cookies, body['logged_in']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the checkin if possible.
|
||||||
|
void checkin() async {
|
||||||
|
if (!this._loggedIn) {
|
||||||
|
throw UnacceptableInvocationException("Not logged in");
|
||||||
|
}
|
||||||
|
if (this._checkedIn) {
|
||||||
|
throw UnacceptableInvocationException("Yet checked in");
|
||||||
|
}
|
||||||
|
var targetUri = this.baseAddress.toString() + this.routes['checkin'];
|
||||||
|
|
||||||
|
var resp = await post(
|
||||||
|
targetUri,
|
||||||
|
headers: {'cookies': this._cookies},
|
||||||
|
);
|
||||||
|
|
||||||
|
handleResponse(resp);
|
||||||
|
var body = jsonDecode(resp.body);
|
||||||
|
log.d("[checkin] Response: $body");
|
||||||
|
this.updateMovement(body['checked_in']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the checkout if possible.
|
||||||
|
void checkout() async {
|
||||||
|
if (!this._loggedIn) {
|
||||||
|
throw UnacceptableInvocationException("Not logged in");
|
||||||
|
}
|
||||||
|
if (!this._checkedIn) {
|
||||||
|
throw UnacceptableInvocationException("Not yet checked in");
|
||||||
|
}
|
||||||
|
var targetUri = this.baseAddress.toString() + this.routes['checkout'];
|
||||||
|
|
||||||
|
var resp = await post(
|
||||||
|
targetUri,
|
||||||
|
headers: {'cookies': this._cookies},
|
||||||
|
);
|
||||||
|
|
||||||
|
handleResponse(resp);
|
||||||
|
var body = jsonDecode(resp.body);
|
||||||
|
log.d("[checkout] Response: $body");
|
||||||
|
this.updateMovement(body['checked_in']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query the server for the list of movements.
|
||||||
|
Future<Map<String, String>> getMovements() async {
|
||||||
|
if (!this._loggedIn) {
|
||||||
|
throw UnacceptableInvocationException("Not logged in");
|
||||||
|
}
|
||||||
|
if (!this._checkedIn) {
|
||||||
|
throw UnacceptableInvocationException("Not yet checked in");
|
||||||
|
}
|
||||||
|
var targetUri = this.baseAddress.toString() + this.routes['movements'];
|
||||||
|
|
||||||
|
var resp = await get(
|
||||||
|
targetUri,
|
||||||
|
headers: {'cookies': this._cookies},
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
handleResponse(resp);
|
||||||
|
} on NotFoundException {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
var body = jsonDecode(resp.body);
|
||||||
|
Map<String, String> movements;
|
||||||
|
for (var values in body['movements']) {
|
||||||
|
movements[values['time']] = values['type'];
|
||||||
|
}
|
||||||
|
return movements;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UnauthorizedException implements ClientException {
|
||||||
|
UnauthorizedException(this.uri);
|
||||||
|
final String message = "Unauthorized";
|
||||||
|
final Uri uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class NotFoundException implements ClientException {
|
||||||
|
NotFoundException(this.uri);
|
||||||
|
final String message = "Resource not found";
|
||||||
|
final Uri uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UnacceptableInvocationException implements Exception {
|
||||||
|
UnacceptableInvocationException(this.message);
|
||||||
|
final String message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Response handleResponse(Response resp) {
|
||||||
|
final c = resp.statusCode;
|
||||||
|
if (c >= 200 && c < 400) {
|
||||||
|
} else if (c == 401) {
|
||||||
|
throw UnauthorizedException(resp.request.url);
|
||||||
|
} else if (c == 404) {
|
||||||
|
throw NotFoundException(resp.request.url);
|
||||||
|
}else if (c >=400 || c < 500) {
|
||||||
|
throw ClientException("Unexpected return code: $c", resp.request.url);
|
||||||
|
} else if (c >= 500) {
|
||||||
|
throw ClientException("Server error: $c", resp.request.url);
|
||||||
|
}
|
||||||
|
return resp;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user