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> getAvailableData() async { final res = await _client.get>( "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>.from(res.data ?? []); final dataFiles = []; 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 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> getDownloadedData() async { final tessDir = Directory(await FlutterTesseractOcr.getTessdataPath()); if (!tessDir.existsSync()) { tessDir.createSync(); } return tessDir .listSync() .where((element) => element.path.endsWith(".traineddata")) .map((e) => e.path.split("/").last) .toList(); } /// Downloads data from the repo to the device static Future 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>( "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"); } } }