prasule/lib/network/tessdata.dart

93 lines
3 KiB
Dart
Raw Normal View History

2024-06-30 20:25:36 +02:00
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
2023-09-08 11:50:21 +02:00
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_tesseract_ocr/flutter_tesseract_ocr.dart';
import 'package:prasule/main.dart';
/// Used for communication with my repo mirror
///
/// Downloads Tessdata for OCR
2023-09-08 11:50:21 +02:00
class TessdataApi {
static final Dio _client = Dio(
BaseOptions(
validateStatus: (status) => true,
headers: {"User-Agent": "prasule/1.0.0"},
2023-09-08 11:50:21 +02:00
),
);
/// Gets available languages from the repo
2023-09-08 11:50:21 +02:00
static Future<List<String>> getAvailableData() async {
final res = await _client.get<List<dynamic>>(
"https://git.mnau.xyz/api/v1/repos/hernik/tessdata_fast/contents",
options: Options(headers: {"Accept": "application/json"}),
);
2023-09-08 11:50:21 +02:00
if ((res.statusCode ?? 500) > 399) {
return Future.error("The server returned status code ${res.statusCode}");
}
final data = List<Map<String, dynamic>>.from(res.data ?? []);
2023-09-08 11:50:21 +02:00
final dataFiles = <String>[];
for (final file in data) {
if (!(file["name"] as String).endsWith(".traineddata")) continue;
dataFiles.add((file["name"] as String).replaceAll(".traineddata", ""));
2023-09-08 11:50:21 +02:00
}
return dataFiles;
}
/// Deletes data from device
2023-09-08 11:50:21 +02:00
static Future<void> deleteData(String name) async {
final dataDir = Directory(await FlutterTesseractOcr.getTessdataPath());
if (!dataDir.existsSync()) {
dataDir.createSync();
}
final dataFile = File("${dataDir.path}/$name.traineddata");
2023-09-08 11:50:21 +02:00
if (!dataFile.existsSync()) return;
dataFile.deleteSync();
}
/// Finds existing data on the device
static Future<List<String>> getDownloadedData() async {
final tessDir = Directory(await FlutterTesseractOcr.getTessdataPath());
if (!tessDir.existsSync()) {
tessDir.createSync();
}
return tessDir
.listSync()
.where((element) => element.path.endsWith(".traineddata"))
.map<String>((e) => e.path.split("/").last)
.toList();
}
2023-09-08 11:50:21 +02:00
/// Downloads data from the repo to the device
static Future<void> downloadData(
String isoCode, {
void Function(int, int)? callback,
}) async {
final tessDir = Directory(await FlutterTesseractOcr.getTessdataPath());
if (!tessDir.existsSync()) {
tessDir.createSync();
}
final file = File("${tessDir.path}/$isoCode.traineddata");
2023-09-08 11:50:21 +02:00
if (file.existsSync()) return; // TODO: maybe ask to redownload?
final res = await _client.get<List<int>>(
"https://git.mnau.xyz/hernik/tessdata_fast/raw/branch/main/$isoCode.traineddata",
options: Options(responseType: ResponseType.bytes),
onReceiveProgress: callback,
);
2023-09-08 11:50:21 +02:00
if ((res.statusCode ?? 500) > 399) {
return Future.error("The server returned status code ${res.statusCode}");
}
try {
file.openSync(mode: FileMode.write)
..writeFromSync(res.data!)
..closeSync();
2023-09-08 11:50:21 +02:00
} catch (e) {
logger.e(e);
return Future.error("Could not complete writing file");
}
}
}