201 lines
5.2 KiB
Dart
201 lines
5.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:logging/logging.dart';
|
|
import 'package:path_provider/path_provider.dart'; // For cache storage
|
|
import 'package:sheetless/utility.dart';
|
|
|
|
import 'sheet.dart';
|
|
|
|
class ApiClient {
|
|
final log = Logger("ApiClient");
|
|
final String baseUrl;
|
|
String? token;
|
|
|
|
ApiClient({required this.baseUrl, this.token});
|
|
|
|
Future<Result<void>> login(String username, String password) async {
|
|
log.info("Logging in...");
|
|
try {
|
|
final url = '$baseUrl/login';
|
|
final response = await http.post(
|
|
Uri.parse(url),
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: jsonEncode({'email': username, 'password': password}),
|
|
);
|
|
|
|
if (response.statusCode == 200) {
|
|
token = jsonDecode(response.body);
|
|
log.info('Login successful');
|
|
return Result.ok(null);
|
|
} else {
|
|
log.warning('Login failed: ${response.statusCode}, ${response.body}');
|
|
return Result.error(
|
|
Exception(
|
|
"Response code ${response.statusCode}\nResponse: ${response.body}",
|
|
),
|
|
);
|
|
}
|
|
} on Exception catch (e) {
|
|
log.warning('Error during login', e);
|
|
return Result.error(e);
|
|
}
|
|
}
|
|
|
|
void logout() {
|
|
token = null;
|
|
log.info('Logged out successfully.');
|
|
}
|
|
|
|
Future<http.Response?> get(String endpoint, {bool isBinary = false}) async {
|
|
try {
|
|
final url = '$baseUrl$endpoint';
|
|
final headers = {
|
|
'Authorization': 'Bearer $token',
|
|
if (!isBinary) 'Content-Type': 'application/json',
|
|
};
|
|
|
|
final response = await http.get(Uri.parse(url), headers: headers);
|
|
|
|
if (response.statusCode == 200) {
|
|
return response;
|
|
} else {
|
|
log.warning(
|
|
'GET request failed: ${response.statusCode} ${response.body}',
|
|
);
|
|
}
|
|
} catch (e) {
|
|
log.warning('Error during GET request', e);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<http.Response?> post(
|
|
String endpoint,
|
|
Map<String, dynamic> body,
|
|
) async {
|
|
try {
|
|
final url = '$baseUrl$endpoint';
|
|
final headers = {
|
|
'Authorization': 'Bearer $token',
|
|
'Content-Type': 'application/json',
|
|
};
|
|
|
|
final response = await http.post(
|
|
Uri.parse(url),
|
|
headers: headers,
|
|
body: jsonEncode(body),
|
|
);
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
|
return response;
|
|
} else {
|
|
log.info(
|
|
'POST request failed: ${response.statusCode} ${response.body}',
|
|
);
|
|
}
|
|
} catch (e) {
|
|
log.info('Error during POST request: $e');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<http.Response?> postFormData(String endpoint, String body) async {
|
|
try {
|
|
final url = '$baseUrl$endpoint';
|
|
final headers = {
|
|
'Authorization': 'Bearer $token',
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
};
|
|
|
|
final response = await http.post(
|
|
Uri.parse(url),
|
|
headers: headers,
|
|
body: body,
|
|
);
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
|
return response;
|
|
} else {
|
|
log.info(
|
|
'POST Form Data request failed: ${response.statusCode} ${response.body}',
|
|
);
|
|
}
|
|
} catch (e) {
|
|
log.info('Error during POST Form Data request: $e');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<List<Sheet>> fetchSheets() async {
|
|
try {
|
|
final response = await get("/list/sheets");
|
|
|
|
if (response == null) {
|
|
return List.empty();
|
|
}
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = jsonDecode(response.body);
|
|
return (data as List<dynamic>)
|
|
.map((sheet) => Sheet.fromJson(sheet as Map<String, dynamic>))
|
|
.toList();
|
|
} else {
|
|
log.warning(
|
|
'Failed to fetch sheets with status: ${response.statusCode}',
|
|
);
|
|
log.info('Response: ${response.body}');
|
|
}
|
|
} catch (e) {
|
|
log.warning('Error during fetching sheets', e);
|
|
}
|
|
|
|
return List.empty();
|
|
}
|
|
|
|
Future<Uint8List?> fetchPdfFileData(String sheetUuid) async {
|
|
try {
|
|
final response = await get('/sheet/pdf/$sheetUuid', isBinary: true);
|
|
|
|
if (response != null && response.statusCode == 200) {
|
|
log.info("PDF downloaded");
|
|
return response.bodyBytes;
|
|
} else {
|
|
log.warning(
|
|
"Failed to fetch PDF from API. Status: ${response?.statusCode}",
|
|
);
|
|
}
|
|
} catch (e) {
|
|
log.warning("Error fetching PDF", e);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
Future<File?> getPdfFileCached(String sheetUuid) async {
|
|
try {
|
|
final cacheDir = await getTemporaryDirectory();
|
|
final cachedPdfPath = '${cacheDir.path}/$sheetUuid.pdf';
|
|
|
|
final cachedFile = File(cachedPdfPath);
|
|
if (await cachedFile.exists()) {
|
|
log.info("PDF found in cache: $cachedPdfPath");
|
|
return cachedFile;
|
|
}
|
|
|
|
final pdfFileData = await fetchPdfFileData(sheetUuid);
|
|
await cachedFile.writeAsBytes(
|
|
pdfFileData!,
|
|
); // TODO: proper error handling
|
|
log.info("PDF cached at: $cachedPdfPath");
|
|
return cachedFile;
|
|
} catch (e) {
|
|
log.warning("Error fetching PDF", e);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|