Jacek Kowalski
2019-06-10 6b6842c72b28c1346ef501bc656ec3016d00e1c7
commit | author | age
138f39 1 <?php
1a98b6 2 require_once(__DIR__.'/lib/database.php');
4673cc 3 require_once(__DIR__.'/lib/fetch.php');
JK 4 require_once(__DIR__.'/lib/mapper.php');
138f39 5
4673cc 6 $logger = new Monolog\Logger('Parse changes');
138f39 7
4673cc 8 $sources = [
0c85a7 9     'bus' => [
6b6842 10         'gtfs' => 'ftp://ztp.krakow.pl/GTFS_KRK_A.zip',
JK 11         'gtfs_file' => 'GTFS_KRK_A.zip',
0c85a7 12         'gtfsrt' => 'ftp://ztp.krakow.pl/VehiclePositions_A.pb',
JK 13         'gtfsrt_file' => 'VehiclePositions_A.pb',
4673cc 14         'ttss' => 'http://91.223.13.70/internetservice/geoserviceDispatcher/services/vehicleinfo/vehicles',
JK 15         'ttss_file' => 'vehicles_A.json',
1a98b6 16         'database' => 'mapping_A.sqlite3',
914dc8 17         'result' => 'mapping_A.json',
4673cc 18     ],
JK 19 ];
138f39 20
4673cc 21 foreach($sources as $name => $source) {
JK 22     $logger = new Monolog\Logger('fetch_'.$name);
23     try {
0c85a7 24         foreach(['gtfsrt_file', 'ttss_file', 'database', 'result'] as $field) {
1a98b6 25             $source[$field] = __DIR__.'/data/'.$source[$field];
JK 26         }
27         $source['result_temp'] = $source['result'].'.tmp';
28         
4673cc 29         $logger->info('Fetching '.$name.' position data from FTP...');
0c85a7 30         $updated = ftp_fetch_if_newer($source['gtfsrt'], $source['gtfsrt_file']);
4673cc 31         if(!$updated) {
JK 32             $logger->info('Nothing to do, remote file not newer than local one');
33             continue;
34         }
35         
0c85a7 36         $logger->info('Fetching '.$name.' position data from TTSS...');
JK 37         fetch($source['ttss'], $source['ttss_file']);
4673cc 38         
JK 39         $logger->info('Loading data...');
40         $mapper = new Mapper();
9afb6b 41         
1a98b6 42         $mapper->loadTTSS($source['ttss_file']);
6b6842 43
9afb6b 44         $timeDifference = time() - $mapper->getTTSSDate();
JK 45         if(abs($timeDifference) > 60) {
46             throw new Exception('TTSS timestamp difference ('.$timeDifference.'s) is too high, aborting!');
47         }
48         
0c85a7 49         $mapper->loadGTFSRT($source['gtfsrt_file']);
9afb6b 50         $timeDifference = time() - $mapper->getGTFSRTDate();
JK 51         if(abs($timeDifference) > 60) {
52             throw new Exception('GTFSRT timestamp difference ('.$timeDifference.'s) is too high, aborting!');
53         }
1a98b6 54         
6b6842 55         $mapper->loadGTFS($source['gtfs_file']);
JK 56         
1a98b6 57         $db = new Database($source['database']);
4673cc 58         
JK 59         $logger->info('Finding correct offset...');
60         $offset = $mapper->findOffset();
1a98b6 61         if(!$offset) {
JK 62             throw new Exception('Offset not found');
4673cc 63         }
1a98b6 64         
JK 65         $logger->info('Got offset '.$offset.', creating mapping...');
0c85a7 66         $mapping = $mapper->mapUsingOffset($offset);
1a98b6 67         
JK 68         $logger->info('Checking the data for correctness...');
69         $weight = count($mapping);
33182e 70         
JK 71         $correct = 0;
72         $incorrect = 0;
73         $old = 0;
74         $maxWeight = 0;
1a98b6 75         foreach($mapping as $id => $vehicle) {
JK 76             $dbVehicle = $db->getById($id);
77             if($dbVehicle) {
33182e 78                 $maxWeight = max($maxWeight, $dbVehicle['weight']);
JK 79                 if((int)substr($vehicle['num'], 2) == (int)$dbVehicle['num']) {
80                     $correct += 1;
81                 } else {
82                     $incorrect += 1;
1a98b6 83                 }
JK 84                 continue;
85             }
86             
87             $dbVehicle = $db->getByNum($vehicle['num']);
88             if($dbVehicle && $dbVehicle['id'] != $id) {
33182e 89                 $old += 1;
1a98b6 90             }
JK 91         }
33182e 92         $logger->info('Weight: '.$weight.', correct: '.$correct.', incorrect: '.$incorrect.', old: '.$old);
1a98b6 93         
JK 94         $previousMapping = NULL;
33182e 95         if($incorrect > $correct && $maxWeight > $weight) {
1a98b6 96             throw new Exception('Ignoring result due to better data already present');
5af1a7 97         } elseif($old > $correct) {
33182e 98             $logger->warn('Replacing DB data with the new mapping');
1a98b6 99             $db->clear();
JK 100         } else {
101             $previousMapping = @json_decode(@file_get_contents($source['result']), TRUE);
102         }
103         
104         $db->addMapping($mapping);
105         
106         if(is_array($previousMapping)) {
107             $logger->info('Merging previous data with current mapping');
423dc9 108             $mapping = $mapping + $previousMapping;
1a98b6 109             ksort($mapping);
JK 110         }
111         
112         $json = json_encode($mapping);
113         if(!file_put_contents($source['result_temp'], $json)) {
114             throw new Exception('Result save failed');
115         }
116         rename($source['result_temp'], $source['result']);
4673cc 117         $logger->info('Finished');
JK 118     } catch(Throwable $e) {
119         $logger->error($e->getMessage(), ['exception' => $e, 'exception_string' => (string)$e]);
120     }
138f39 121 }