Line data Source code
1 : import 'dart:io';
2 :
3 : import 'package:app_pym/core/directory_manager/directory_manager.dart';
4 : import 'package:app_pym/core/error/exceptions.dart';
5 : import 'package:app_pym/core/utils/gtfs_utils.dart';
6 : import 'package:app_pym/data/datasources/gtfs_type_local_data_source.dart';
7 : import 'package:app_pym/data/models/mobility/calendar_model.dart';
8 : import 'package:app_pym/data/models/mobility/route_model.dart';
9 : import 'package:app_pym/data/models/mobility/stop_model.dart';
10 : import 'package:app_pym/data/models/mobility/stop_time_model.dart';
11 : import 'package:app_pym/data/models/mobility/trip_model.dart';
12 : import 'package:archive/archive.dart';
13 : import 'package:flutter/foundation.dart';
14 : import 'package:injectable/injectable.dart';
15 :
16 : abstract class SNCFLocalDataSource extends GTFSTypeLocalDataSource {
17 : Future<DateTime> get timestamp;
18 : Future<void> setTimestamp(DateTime timestamp);
19 : }
20 :
21 : @prod
22 : @LazySingleton(as: SNCFLocalDataSource)
23 : class SNCFLocalDataSourceImpl implements SNCFLocalDataSource {
24 : final DirectoryManager directoryManager;
25 : final ZipDecoder zipDecoder;
26 :
27 1 : SNCFLocalDataSourceImpl({
28 : @required this.directoryManager,
29 : @required this.zipDecoder,
30 : });
31 :
32 : @override
33 0 : Future<bool> get fileExists async {
34 0 : return File('${await directoryManager.sncf}/export-ter-gtfs-last.zip')
35 0 : .existsSync();
36 : }
37 :
38 : @override
39 1 : Future<DateTime> get timestamp async {
40 5 : final file = File('${await directoryManager.sncf}/timestamp.txt');
41 1 : if (file.existsSync()) {
42 3 : return DateTime.parse(file.readAsLinesSync().first);
43 : }
44 1 : return DateTime.parse("1970-01-01 12:00:00");
45 : }
46 :
47 : @override
48 1 : Future<List<CalendarModel>> fetchCalendars() async {
49 5 : final file = File('${await directoryManager.sncf}/calendar.txt');
50 1 : if (file.existsSync()) {
51 1 : return file.parseCalendars();
52 : } else {
53 1 : throw CacheException('Calendars not found.');
54 : }
55 : }
56 :
57 : @override
58 1 : Future<List<RouteModel>> fetchRoutes() async {
59 5 : final file = File('${await directoryManager.sncf}/routes.txt');
60 1 : if (file.existsSync()) {
61 1 : return file.parseRoutes();
62 : } else {
63 1 : throw CacheException('Routes not found.');
64 : }
65 : }
66 :
67 : @override
68 1 : Future<List<StopModel>> fetchStops() async {
69 5 : final file = File('${await directoryManager.sncf}/stops.txt');
70 1 : if (file.existsSync()) {
71 1 : return file.parseStops();
72 : } else {
73 1 : throw CacheException('Stops not found.');
74 : }
75 : }
76 :
77 : @override
78 1 : Future<List<StopTimeModel>> fetchStopTimes() async {
79 5 : final file = File('${await directoryManager.sncf}/stop_times.txt');
80 1 : if (file.existsSync()) {
81 1 : return file.parseStopTimes();
82 : } else {
83 1 : throw CacheException('StopTimes not found.');
84 : }
85 : }
86 :
87 : @override
88 1 : Future<List<TripModel>> fetchTrips() async {
89 5 : final file = File('${await directoryManager.sncf}/trips.txt');
90 1 : if (file.existsSync()) {
91 1 : return file.parseTrips();
92 : } else {
93 1 : throw CacheException('Trips not found.');
94 : }
95 : }
96 :
97 : @override
98 1 : Future<void> setTimestamp(DateTime timestamp) async {
99 3 : final path = await directoryManager.sncf;
100 2 : Directory(path).createSync(recursive: true);
101 2 : final File file = File('${path}/timestamp.txt');
102 2 : return file.writeAsString(timestamp.toIso8601String());
103 : }
104 :
105 : @override
106 0 : Stream<List<int>> useAsset() async* {
107 0 : final bytedata = await directoryManager.terZip;
108 0 : final buffer = bytedata.buffer;
109 0 : yield buffer.asUint8List(bytedata.offsetInBytes, bytedata.lengthInBytes);
110 : }
111 :
112 : @override
113 1 : Future<void> writeFile(Stream<List<int>> bytes) async {
114 : // Write the Zip file
115 : final File file =
116 5 : File('${await directoryManager.sncf}/export-ter-gtfs-last.zip');
117 1 : final IOSink sink = file.openWrite();
118 3 : await bytes.forEach(sink.add);
119 2 : await sink.flush();
120 2 : await sink.close();
121 1 : return _unzip(file);
122 : }
123 :
124 1 : Future<void> _unzip(File file) async {
125 : // Decode the Zip file
126 3 : final Archive archive = zipDecoder.decodeBytes(file.readAsBytesSync());
127 :
128 : // Extract the contents of the Zip archive to disk.
129 2 : for (final ArchiveFile archiveFile in archive) {
130 1 : if (archiveFile.isFile) {
131 1 : final List<int> data = archiveFile.content as List<int>;
132 : final openFile =
133 6 : File('${await directoryManager.sncf}/' + archiveFile.name)
134 1 : ..createSync(recursive: true);
135 1 : openFile.writeAsBytesSync(data);
136 : }
137 : }
138 : }
139 : }
|