Line data Source code
1 : // Copyright 2024 The terCAD team. All rights reserved. 2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file. 3 : 4 : import 'dart:convert'; 5 : import 'dart:io'; 6 : 7 : import 'package:app_finance/_classes/storage/transaction_log/interface_storage.dart'; 8 : import 'package:app_finance/_ext/int_ext.dart'; 9 : import 'package:path_provider/path_provider.dart'; 10 : 11 : abstract class AbstractStorage implements InterfaceStorage { 12 : static File? _logFile; 13 : static bool _isLocked = false; 14 : 15 : static const filePath = '.terCAD/app-finance.log'; 16 : 17 3 : static Future<File> get logFle async { 18 : if (_logFile != null) { 19 1 : return Future.value(_logFile); 20 : } 21 3 : List<File> scope = [ 22 3 : await getApplicationDocumentsDirectory(), 23 3 : await getApplicationSupportDirectory(), 24 3 : Directory.systemTemp, 25 3 : await getTemporaryDirectory(), 26 21 : ].map((dir) => File('${dir.absolute.path}/$filePath')).toList(); 27 12 : File? file = scope.where((f) => f.existsSync()).firstOrNull; 28 : int i = 0; 29 6 : while (i < scope.length && file == null) { 30 : try { 31 0 : File tmp = scope[i]; 32 0 : if (!tmp.existsSync()) { 33 0 : tmp.createSync(recursive: true); 34 0 : tmp.writeAsString("\n", mode: FileMode.append); 35 : } 36 : file = tmp; 37 : } catch (e) { 38 0 : i++; 39 : } 40 : } 41 : if (file == null) { 42 0 : throw Exception('Write access denied for: $scope.'); 43 : } 44 : return _logFile = file; 45 : } 46 : 47 0 : static Future<String> getSize() async { 48 0 : int size = (await logFle).lengthSync(); 49 0 : return size.toByteSize(); 50 : } 51 : 52 0 : static void saveRaw(String line) { 53 : int retrial = 1; 54 0 : while (_isLocked && retrial < 1000) { 55 0 : sleep(Duration(microseconds: retrial * 10)); 56 0 : retrial++; 57 : } 58 : _isLocked = true; 59 0 : _logFile!.writeAsStringSync("$line\n", mode: FileMode.append); 60 : _isLocked = false; 61 : } 62 : 63 3 : static Stream<String> read() async* { 64 15 : Stream<String> lines = (await logFle).openRead().transform(utf8.decoder).transform(const LineSplitter()); 65 : 66 3 : await for (var line in lines) { 67 : yield line; 68 : } 69 : } 70 : 71 0 : static void clear() { 72 0 : _logFile?.deleteSync(); 73 0 : _logFile?.createSync(); 74 : } 75 : }