Move functions into classes to make them autoloader-compatibile
3 files modified
3 files deleted
5 files added
| | |
| | | <?php |
| | | $tramTypes = new TramTypes(); |
| | | $sources = [ |
| | | 'bus' => [ |
| | | 'gtfsrt' => 'ftp://ztp.krakow.pl/VehiclePositions_A.pb', |
| | |
| | | 'database' => 'mapping_A.sqlite3', |
| | | 'result' => 'mapping_A.json', |
| | | 'result_vehicles' => 'vehicles_A.html', |
| | | 'mapper' => 'numToTypeB', |
| | | 'mapper' => new BusTypes(), |
| | | 'prefix' => 'b', |
| | | ], |
| | | 'tram' => [ |
| | |
| | | 'database' => 'mapping_T.sqlite3', |
| | | 'result' => 'mapping_T.json', |
| | | 'result_vehicles' => 'vehicles_T.html', |
| | | 'mapper' => 'numToTypeT', |
| | | 'mapper' => $tramTypes, |
| | | 'prefix' => 't', |
| | | ], |
| | | 'tram2' => [ |
| | |
| | | 'database' => 'mapping_T.sqlite3', |
| | | 'result' => 'mapping_T.json', |
| | | 'result_vehicles' => 'vehicles_T.html', |
| | | 'mapper' => 'numToTypeT', |
| | | 'mapper' => $tramTypes, |
| | | 'prefix' => 't', |
| | | ], |
| | | ]; |
New file |
| | |
| | | <?php |
| | | class BusTypes extends VehicleTypes { |
| | | public function __construct() { |
| | | $data = <<<'END' |
| | | 2 4 DN Solaris Urbino 18 IV Electric |
| | | 71 83 BH Solaris Urbino 18 III Hybrid |
| | | 84 96 BH Volvo 7900A Hybrid |
| | | 103 105 PA Mercedes-Benz 516 |
| | | 106 112 DA Autosan M09LE |
| | | 113 121 BA Autosan M09LE |
| | | 122 128 DA Autosan M09LE |
| | | 129 139 BA Autosan M09LE |
| | | 141 146 PM MAN NL283 Lion's City |
| | | 200 200 DO Mercedes Conecto |
| | | 206 210 PO Mercedes O530 C2 Hybrid |
| | | 211 218 DO Mercedes O530 |
| | | 219 243 PO Mercedes O530 C2 Hybrid |
| | | 244 269 DO Mercedes O530 C2 |
| | | 270 299 BO Mercedes O530 C2 |
| | | 301 338 DU Solaris Urbino 12 IV |
| | | 339 340 BU Solaris Urbino 12 IV |
| | | 341 345 DU Solaris Urbino 12 III |
| | | 400 403 BH Solaris Urbino 12,9 III Hybrid |
| | | 404 408 DH Solaris Urbino 12,9 III Hybrid |
| | | 501 510 BR Solaris Urbino 18 IV |
| | | 511 568 DR Solaris Urbino 18 IV |
| | | 569 579 BR Solaris Urbino 18 IV |
| | | 580 595 DR Solaris Urbino 18 IV |
| | | 601 601 DE Solaris Urbino 12 III Electric |
| | | 602 605 DE Solaris Urbino 8,9LE Electric |
| | | 606 606 DE Solaris Urbino 12 III Electric |
| | | 607 623 DE Solaris Urbino 12 IV Electric |
| | | 700 700 DC Mercedes Conecto G |
| | | 701 731 DC Mercedes O530G |
| | | 732 732 DC Mercedes Conecto G |
| | | 737 741 BR Solaris Urbino 18 III |
| | | 742 745 DR Solaris Urbino 18 III |
| | | 746 764 PR Solaris Urbino 18 III |
| | | 765 768 DR Solaris Urbino 18 III |
| | | 769 776 PR Solaris Urbino 18 MetroStyle |
| | | 777 777 DR Solaris Urbino 18 III |
| | | 778 797 PR Solaris Urbino 18 IV |
| | | 851 903 BU Solaris Urbino 12 III |
| | | 904 905 DU Solaris Urbino 12 III |
| | | 906 926 BU Solaris Urbino 12 III |
| | | 927 976 PU Solaris Urbino 12 III |
| | | 977 977 DU Solaris Urbino 12 III |
| | | 978 991 PU Solaris Urbino 12 IV |
| | | 992 997 BU Solaris Urbino 12 IV |
| | | END; |
| | | parent::__construct($data, 2); |
| | | } |
| | | } |
New file |
| | |
| | | <?php |
| | | class Fetch { |
| | | static function ftp($url, $file = NULL) { |
| | | $url = parse_url($url); |
| | | if(!isset($url['scheme']) || $url['scheme'] != 'ftp') { |
| | | throw new Exception('Only FTP URLs are supported'); |
| | | } |
| | | if(!isset($url['host'])) { |
| | | throw new Exception('Hostname not present in the URL'); |
| | | } |
| | | if(!isset($url['path'])) { |
| | | throw new Exception('Path component not present in the URL'); |
| | | } |
| | | if(!isset($url['port'])) { |
| | | $url['port'] = 21; |
| | | } |
| | | if(!isset($url['user'])) { |
| | | $url['user'] = 'anonymous'; |
| | | } |
| | | if(!isset($url['pass'])) { |
| | | $url['pass'] = 'anonymous@mpk.jacekk.net'; |
| | | } |
| | | if($file == NULL) { |
| | | $file = basename($url['path']); |
| | | } |
| | | |
| | | $localTime = -1; |
| | | $localSize = -1; |
| | | if(is_file($file)) { |
| | | $localTime = filemtime($file); |
| | | $localSize = filesize($file); |
| | | } |
| | | |
| | | $ftp = FtpConnection::create($url['host'], $url['port'], $url['user'], $url['pass']); |
| | | $remoteSize = $ftp->size($url['path']); |
| | | $remoteTime = $ftp->mdtm($url['path']); |
| | | |
| | | $updated = FALSE; |
| | | |
| | | if($localTime < $remoteTime || ($localTime == $remoteTime && $localSize != $remoteSize)) { |
| | | if(file_exists($file.'.tmp')) { |
| | | unlink($file.'.tmp'); |
| | | } |
| | | $ftp->get($file.'.tmp', $url['path'], FTP_BINARY); |
| | | touch($file.'.tmp', $remoteTime); |
| | | if(!rename($file.'.tmp', $file)) { |
| | | throw new Exception('Temporary file rename failed'); |
| | | } |
| | | $updated = TRUE; |
| | | } |
| | | |
| | | return $updated; |
| | | } |
| | | |
| | | static function generic($url, $file = NULL) { |
| | | if($file == NULL) { |
| | | $file = basename($url['url']); |
| | | } |
| | | $data = file_get_contents($url); |
| | | if($data === FALSE) { |
| | | throw new Exception('URL fetch failed'); |
| | | } |
| | | if(file_put_contents($file.'.tmp', $data) === FALSE) { |
| | | throw new Exception('Temporary file creation failed'); |
| | | } |
| | | if(!rename($file.'.tmp', $file)) { |
| | | throw new Exception('Temporary file rename failed'); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <?php |
| | | class Output { |
| | | static function createMapping($db, VehicleTypes $vehicleTypes, $saveConfig = FALSE) { |
| | | $mapping = []; |
| | | foreach($db->getAll() as $vehicle) { |
| | | $mapping[$vehicle['id']] = $vehicleTypes->getByNumber($vehicle['num']); |
| | | } |
| | | |
| | | if($saveConfig) { |
| | | $json = json_encode($mapping); |
| | | if(!file_put_contents($saveConfig['result_temp'], $json)) { |
| | | throw new Exception('Result save failed'); |
| | | } |
| | | rename($saveConfig['result_temp'], $saveConfig['result']); |
| | | } |
| | | |
| | | return $mapping; |
| | | } |
| | | |
| | | function createVehiclesList($trips, $mapping, $saveConfig = FALSE) { |
| | | $lines = []; |
| | | $vehicles = []; |
| | | foreach($trips as $trip) { |
| | | $vehicle = $mapping[$trip['id']] ?? []; |
| | | $vehicle += ['trip' => $trip['id']]; |
| | | $lines[$trip['line']][] = [ |
| | | 'trip' => $trip, |
| | | 'vehicle' => $vehicle, |
| | | ]; |
| | | $vehicles[$vehicle['type'] ?? '?'][] = $vehicle; |
| | | } |
| | | foreach($lines as &$line) { |
| | | usort($line, function($a, $b) { |
| | | return (substr($a['vehicle']['num'] ?? '', 2) <=> substr($b['vehicle']['num'] ?? '', 2)); |
| | | }); |
| | | } |
| | | unset($line); |
| | | ksort($lines); |
| | | foreach($vehicles as &$vehicle) { |
| | | usort($vehicle, function($a, $b) { |
| | | return (substr($a['num'] ?? '', 2) <=> substr($b['num'] ?? '', 2)); |
| | | }); |
| | | } |
| | | unset($vehicle); |
| | | ksort($vehicles); |
| | | |
| | | if($saveConfig) { |
| | | $twigLoader = new \Twig\Loader\FilesystemLoader(__DIR__.'/../templates'); |
| | | $twig = new \Twig\Environment($twigLoader); |
| | | |
| | | $vehiclesHtml = $twig->render('vehicles.html', [ |
| | | 'lines' => $lines, |
| | | 'vehicles' => $vehicles, |
| | | 'prefix' => $saveConfig['prefix'], |
| | | ]); |
| | | if(!file_put_contents($saveConfig['result_vehicles_temp'], $vehiclesHtml)) { |
| | | throw new Exception('Vehicles save failed'); |
| | | } |
| | | rename($saveConfig['result_vehicles_temp'], $saveConfig['result_vehicles']); |
| | | } |
| | | |
| | | return $lines; |
| | | } |
| | | } |
New file |
| | |
| | | <?php |
| | | class TramTypes extends VehicleTypes { |
| | | public function __construct() { |
| | | $data = <<<'END' |
| | | 101 107 HW E1 0 |
| | | 108 113 RW E1 0 |
| | | 114 126 HW E1 0 |
| | | 127 127 RW E1 0 |
| | | 128 130 HW E1 0 |
| | | 131 132 RW E1 0 |
| | | 133 133 HW E1 0 |
| | | 134 134 RW E1 0 |
| | | 135 136 HW E1 0 |
| | | 137 139 RW E1 0 |
| | | 140 147 HW E1 0 |
| | | 148 150 RW E1 0 |
| | | 151 152 HW E1 0 |
| | | 153 153 RW E1 0 |
| | | 154 154 HW E1 0 |
| | | 155 155 RW E1 0 |
| | | 156 158 HW E1 0 |
| | | 159 159 RW E1 0 |
| | | 160 174 HW E1 0 |
| | | 201 245 RZ 105N 0 |
| | | 246 299 HZ 105N 0 |
| | | 301 310 RF GT8S 0 |
| | | 311 311 RF GT8N 1 |
| | | 312 312 RF GT8S 0 |
| | | 313 313 RF GT8C 1 |
| | | 314 317 RF GT8S 0 |
| | | 318 329 RF GT8N 1 |
| | | 401 440 HL EU8N 1 |
| | | 451 456 HK N8C-NF 1 |
| | | 457 461 HK N8S-NF 1 |
| | | 462 462 HK N8C-NF 1 |
| | | 601 614 RP NGT6 (1) 2 |
| | | 615 626 RP NGT6 (2) 2 |
| | | 627 650 RP NGT6 (3) 2 |
| | | 801 824 RY NGT8 2 |
| | | 899 899 RY 126N 2 |
| | | 901 914 RG 2014N 2 |
| | | 915 936 HG 2014N 2 |
| | | 999 999 HG 405N 1 |
| | | END; |
| | | parent::__construct($data); |
| | | } |
| | | |
| | | public function getByNumber($id) { |
| | | if((int)$id == 250) { |
| | | $id = 410; |
| | | } |
| | | return parent::getByNumber($id); |
| | | } |
| | | } |
New file |
| | |
| | | <?php |
| | | abstract class VehicleTypes { |
| | | protected $typesByNumber = []; |
| | | |
| | | protected function __construct($data, $defaultLow=NULL) { |
| | | $data = explode("\n", trim($data)); |
| | | foreach($data as $line) { |
| | | $line = explode("\t", trim($line)); |
| | | for($i = (int)$line[0]; $i <= (int)$line[1]; $i++) { |
| | | $this->typesByNumber[$i] = [ |
| | | 'num' => $line[2] . str_pad($i, 3, '0', STR_PAD_LEFT), |
| | | 'type' => $line[3], |
| | | 'low' => (int)(isset($line[4]) ? $line[4] : $defaultLow), |
| | | ]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public function getByNumber($id) { |
| | | return $this->typesByNumber[$id] ?? [ |
| | | 'num' => '??'.$id, |
| | | 'type' => '?', |
| | | 'low' => NULL, |
| | | ]; |
| | | } |
| | | } |
| | |
| | | <?php |
| | | require_once(__DIR__.'/vendor/autoload.php'); |
| | | require_once(__DIR__.'/lib/fetch.php'); |
| | | require_once(__DIR__.'/lib/output.php'); |
| | | require_once(__DIR__.'/lib/vehicle_types.php'); |
| | | require_once(__DIR__.'/config.php'); |
| | | |
| | | foreach($sources as $name => $source) { |
| | | $logger = new Monolog\Logger('fetch_'.$name); |
| | | try { |
| | | $logger->info('Fetching '.$name.' position data from FTP...'); |
| | | $updated = ftp_fetch_if_newer($source['gtfsrt'], $source['gtfsrt_file']); |
| | | $updated = Fetch::ftp($source['gtfsrt'], $source['gtfsrt_file']); |
| | | if(!$updated) { |
| | | $logger->info('Nothing to do, remote file not newer than local one'); |
| | | continue; |
| | | } |
| | | |
| | | $logger->info('Fetching '.$name.' position data from TTSS...'); |
| | | fetch($source['ttss'], $source['ttss_file']); |
| | | Fetch::generic($source['ttss'], $source['ttss_file']); |
| | | |
| | | $logger->info('Loading data...'); |
| | | $mapper = new Mapper(); |
| | |
| | | |
| | | $db->addMapping($mapping); |
| | | |
| | | $finalMapping = createMapping($db, $source['mapper'], $source); |
| | | $finalMapping = Output::createMapping($db, $source['mapper'], $source); |
| | | |
| | | |
| | | $logger->info('Creating vehicle list...'); |
| | | |
| | | createVehiclesList($mapper->getTTSSTrips(), $finalMapping, $source); |
| | | Output::createVehiclesList($mapper->getTTSSTrips(), $finalMapping, $source); |
| | | |
| | | $logger->info('Finished'); |
| | | } catch(Throwable $e) { |
| | |
| | | <?php |
| | | require_once(__DIR__.'/vendor/autoload.php'); |
| | | require_once(__DIR__.'/lib/output.php'); |
| | | require_once(__DIR__.'/lib/vehicle_types.php'); |
| | | require_once(__DIR__.'/config.php'); |
| | | |
| | | foreach($sources as $name => $source) { |
| | |
| | | try { |
| | | $logger->info('Regenerating '.$name.'...'); |
| | | $db = new Database($source['database']); |
| | | createMapping($db, $source['mapper'], $source); |
| | | Output::createMapping($db, $source['mapper'], $source); |
| | | $logger->info('Finished'); |
| | | } catch(Throwable $e) { |
| | | $logger->error($e->getMessage(), ['exception' => $e, 'exception_string' => (string)$e]); |