prasule/lib/network/tessdata.dart
Matyáš Caras 2f13b295c9
fix(ocr): correctly load data from API
Also for some reason eng traineddata were missing in the app, hopefully fixed by this
2024-01-09 23:03:23 +01:00

89 lines
2.9 KiB
Dart

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
class TessdataApi {
static final Dio _client = Dio(
BaseOptions(
validateStatus: (status) => true,
headers: {"User-Agent": "prasule/1.0.0"},
),
);
/// Gets available languages from the repo
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"}),
);
if ((res.statusCode ?? 500) > 399) {
return Future.error("The server returned status code ${res.statusCode}");
}
final data = List<Map<String, dynamic>>.from(res.data ?? []);
final dataFiles = <String>[];
for (final file in data) {
if (!(file["name"] as String).endsWith(".traineddata")) continue;
dataFiles.add((file["name"] as String).replaceAll(".traineddata", ""));
}
return dataFiles;
}
/// Deletes data from device
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");
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();
}
/// 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");
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,
);
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();
} catch (e) {
logger.e(e);
return Future.error("Could not complete writing file");
}
}
}