125 lines
3.7 KiB
Dart
125 lines
3.7 KiB
Dart
import 'dart:io';
|
|
import 'dart:convert';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http_parser/http_parser.dart';
|
|
import '../core/constants/api_url.dart';
|
|
import '../core/cache_manager.dart';
|
|
|
|
class FaceRepository {
|
|
Future<Map<String, dynamic>> enrollFace({
|
|
required File videoFile,
|
|
}) async {
|
|
final url = '${ApiUrl.baseUrl}/face/enroll';
|
|
final fileSize = await videoFile.length();
|
|
final fileSizeMB = (fileSize / 1024 / 1024).toStringAsFixed(2);
|
|
|
|
print('[FaceRepo] URL: $url');
|
|
print('[FaceRepo] File: ${videoFile.path}, Size: $fileSizeMB MB');
|
|
|
|
try {
|
|
final token = CacheManager.authBox.get('auth_token');
|
|
print('[FaceRepo] Token: ${token != null ? "ada (${token.toString().substring(0, 20)}...)" : "NULL!"}');
|
|
|
|
var request = http.MultipartRequest('POST', Uri.parse(url));
|
|
|
|
request.headers.addAll({
|
|
'Authorization': 'Bearer $token',
|
|
'Accept': 'application/json',
|
|
});
|
|
|
|
request.files.add(await http.MultipartFile.fromPath(
|
|
'video_wajah',
|
|
videoFile.path,
|
|
contentType: MediaType('video', 'mp4'),
|
|
));
|
|
|
|
print('[FaceRepo] Sending request...');
|
|
final stopwatch = Stopwatch()..start();
|
|
|
|
var streamedResponse = await request.send().timeout(
|
|
const Duration(minutes: 5),
|
|
);
|
|
|
|
stopwatch.stop();
|
|
print('[FaceRepo] Response received in ${stopwatch.elapsed.inSeconds}s, status: ${streamedResponse.statusCode}');
|
|
|
|
var response = await http.Response.fromStream(streamedResponse);
|
|
print('[FaceRepo] Body: ${response.body}');
|
|
|
|
Map<String, dynamic> body;
|
|
try {
|
|
body = jsonDecode(response.body);
|
|
} catch (_) {
|
|
throw Exception('Server mengembalikan format tidak valid. Coba ulangi lagi.');
|
|
}
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) {
|
|
return {
|
|
'status': true,
|
|
'message': body['message'] ?? 'Pendaftaran wajah berhasil',
|
|
'data': body['data'],
|
|
};
|
|
} else {
|
|
throw Exception(body['message'] ?? 'Gagal mendaftarkan wajah: ${response.statusCode}');
|
|
}
|
|
} catch (e) {
|
|
print('[FaceRepo] ERROR: $e');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> verifyFace(File videoFile, {String tipe = 'presensi'}) async {
|
|
final token = CacheManager.authBox.get('auth_token');
|
|
var request = http.MultipartRequest(
|
|
'POST',
|
|
Uri.parse('${ApiUrl.baseUrl}/face/verify'),
|
|
);
|
|
|
|
request.headers.addAll({
|
|
'Authorization': 'Bearer $token',
|
|
'Accept': 'application/json',
|
|
});
|
|
|
|
request.files.add(await http.MultipartFile.fromPath(
|
|
'file_wajah',
|
|
videoFile.path,
|
|
contentType: MediaType('video', 'mp4'),
|
|
));
|
|
request.fields['tipe'] = tipe;
|
|
|
|
var streamedResponse = await request.send().timeout(
|
|
const Duration(minutes: 3),
|
|
);
|
|
var response = await http.Response.fromStream(streamedResponse);
|
|
|
|
final body = jsonDecode(response.body);
|
|
|
|
if (response.statusCode == 200 && body['success'] == true) {
|
|
return body['data'];
|
|
}
|
|
|
|
throw Exception(body['message'] ?? 'Verifikasi gagal');
|
|
}
|
|
|
|
Future<Map<String, dynamic>> getFaceStatus() async {
|
|
try {
|
|
final token = CacheManager.authBox.get('auth_token');
|
|
final response = await http.get(
|
|
Uri.parse('${ApiUrl.baseUrl}/face/status'),
|
|
headers: {
|
|
'Authorization': 'Bearer $token',
|
|
'Accept': 'application/json',
|
|
},
|
|
);
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = jsonDecode(response.body);
|
|
return data['data'];
|
|
}
|
|
throw Exception('Gagal mengambil status: ${response.statusCode}');
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|