2019-04-22 17:16:26 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
2020-04-20 07:02:54 +00:00
|
|
|
import 'package:comunic/helpers/events_helper.dart';
|
2019-11-01 08:59:05 +00:00
|
|
|
import 'package:comunic/helpers/preferences_helper.dart';
|
2019-04-22 17:16:26 +00:00
|
|
|
import 'package:comunic/models/api_request.dart';
|
|
|
|
import 'package:comunic/models/api_response.dart';
|
|
|
|
import 'package:comunic/models/config.dart';
|
2019-04-25 18:14:19 +00:00
|
|
|
import 'package:dio/dio.dart';
|
2019-04-22 17:16:26 +00:00
|
|
|
|
|
|
|
/// API Helper
|
|
|
|
///
|
|
|
|
/// @author Pierre HUBERT
|
|
|
|
|
|
|
|
class APIHelper {
|
|
|
|
/// Execute a [request] on the server and returns a [APIResponse]
|
|
|
|
///
|
|
|
|
/// This method should never throw but the response code of the [APIResponse]
|
|
|
|
/// should be verified before accessing response content
|
2019-04-25 18:14:19 +00:00
|
|
|
Future<APIResponse> exec(APIRequest request, {bool multipart = false}) async {
|
2019-04-22 17:16:26 +00:00
|
|
|
try {
|
|
|
|
//Add API tokens
|
|
|
|
request.addString("serviceName", config().serviceName);
|
|
|
|
request.addString("serviceToken", config().serviceToken);
|
|
|
|
|
|
|
|
//Add user tokens (if required)
|
2019-04-23 12:35:41 +00:00
|
|
|
if (request.needLogin) {
|
2019-11-01 08:59:05 +00:00
|
|
|
final tokens = (await PreferencesHelper.getInstance()).getLoginTokens();
|
2019-04-23 12:35:41 +00:00
|
|
|
assert(tokens != null);
|
|
|
|
request.addString("userToken1", tokens.tokenOne);
|
|
|
|
request.addString("userToken2", tokens.tokenTwo);
|
|
|
|
}
|
2019-04-22 17:16:26 +00:00
|
|
|
|
|
|
|
// Determine server URL
|
|
|
|
final path = config().apiServerUri + request.uri;
|
|
|
|
Uri url;
|
|
|
|
if (!config().apiServerSecure)
|
|
|
|
url = Uri.http(config().apiServerName, path);
|
|
|
|
else
|
|
|
|
url = Uri.https(config().apiServerName, path);
|
|
|
|
|
2020-03-24 14:01:34 +00:00
|
|
|
final data = FormData.fromMap(request.args);
|
2019-04-25 18:14:19 +00:00
|
|
|
|
|
|
|
// Process files (if required)
|
2020-04-17 06:44:57 +00:00
|
|
|
if (multipart) {
|
|
|
|
// Process filesystem files
|
|
|
|
for (final key in request.files.keys) {
|
2020-03-24 14:01:34 +00:00
|
|
|
var v = request.files[key];
|
|
|
|
data.files.add(MapEntry(
|
|
|
|
key,
|
|
|
|
await MultipartFile.fromFile(v.path,
|
|
|
|
filename: v.path.split("/").last)));
|
|
|
|
}
|
2019-04-25 18:14:19 +00:00
|
|
|
|
2020-04-17 06:44:57 +00:00
|
|
|
// Process in-memory files
|
|
|
|
for (final key in request.bytesFiles.keys) {
|
|
|
|
var v = request.bytesFiles[key];
|
|
|
|
data.files.add(MapEntry(
|
|
|
|
key,
|
2020-04-24 11:35:05 +00:00
|
|
|
MultipartFile.fromBytes(
|
|
|
|
v.bytes,
|
|
|
|
filename: v.filename.split("/").last,
|
|
|
|
contentType: v.type,
|
|
|
|
)));
|
2020-04-17 06:44:57 +00:00
|
|
|
}
|
2021-02-07 16:09:08 +00:00
|
|
|
|
|
|
|
// Process picked files
|
|
|
|
for (final key in request.pickedFiles.keys) {
|
|
|
|
var v = request.pickedFiles[key];
|
|
|
|
data.files.add(MapEntry(
|
|
|
|
key,
|
|
|
|
MultipartFile.fromBytes(
|
|
|
|
await v.readAsBytes(),
|
|
|
|
filename: v.path.split("/").last,
|
|
|
|
)));
|
|
|
|
}
|
2020-04-17 06:44:57 +00:00
|
|
|
}
|
|
|
|
|
2019-04-25 18:14:19 +00:00
|
|
|
// Execute the request
|
|
|
|
final response = await Dio().post(
|
2019-04-25 09:44:58 +00:00
|
|
|
url.toString(),
|
2019-04-25 18:14:19 +00:00
|
|
|
data: data,
|
|
|
|
options: Options(
|
|
|
|
receiveDataWhenStatusError: true,
|
|
|
|
validateStatus: (s) => true,
|
|
|
|
responseType: ResponseType.plain,
|
|
|
|
),
|
2019-04-25 09:44:58 +00:00
|
|
|
);
|
2019-04-22 17:16:26 +00:00
|
|
|
|
2020-04-20 07:02:54 +00:00
|
|
|
// Check if login token is rejected by server
|
|
|
|
if (response.statusCode == 412)
|
|
|
|
EventsHelper.emit(InvalidLoginTokensEvent());
|
|
|
|
|
2019-04-22 17:16:26 +00:00
|
|
|
if (response.statusCode != HttpStatus.ok)
|
2020-04-30 11:32:22 +00:00
|
|
|
return APIResponse(response.statusCode, response.data);
|
2019-04-22 17:16:26 +00:00
|
|
|
|
2019-04-25 18:14:19 +00:00
|
|
|
return APIResponse(response.statusCode, response.data);
|
2020-04-17 06:44:57 +00:00
|
|
|
} catch (e, stack) {
|
2019-04-22 17:16:26 +00:00
|
|
|
print(e.toString());
|
|
|
|
print("Could not execute a request!");
|
2020-04-17 06:44:57 +00:00
|
|
|
print(stack);
|
2019-04-22 17:16:26 +00:00
|
|
|
return APIResponse(-1, null);
|
|
|
|
}
|
|
|
|
}
|
2019-04-25 18:14:19 +00:00
|
|
|
|
|
|
|
/// Same as exec, but also allows to send files
|
|
|
|
Future<APIResponse> execWithFiles(APIRequest request) async {
|
|
|
|
return await exec(request, multipart: true);
|
|
|
|
}
|
2019-04-22 17:16:26 +00:00
|
|
|
}
|