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 6 : static Future<File> get logFle async {
18 : if (_logFile != null) {
19 3 : return Future.value(_logFile);
20 : }
21 6 : List<File> scope = [
22 6 : await getApplicationDocumentsDirectory(),
23 6 : await getApplicationSupportDirectory(),
24 6 : Directory.systemTemp,
25 6 : await getTemporaryDirectory(),
26 42 : ].map((dir) => File('${dir.absolute.path}/$filePath')).toList();
27 24 : File? file = scope.where((f) => f.existsSync()).firstOrNull;
28 : int i = 0;
29 12 : 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 2 : 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 4 : _logFile!.writeAsStringSync("$line\n", mode: FileMode.append);
60 : _isLocked = false;
61 : }
62 :
63 6 : static Stream<String> read() async* {
64 30 : Stream<String> lines = (await logFle).openRead().transform(utf8.decoder).transform(const LineSplitter());
65 :
66 6 : 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 : }
|