0b6d2f4164b9d823fb2a49d9fb4e83242f695e09..9419f76eae6a64f329c7fe4df2bf9c5a2ef94f93
2019-07-23 Jacek Kowalski
Allow to fetch GTFS data from sources other than FTP servers
9419f7 diff | tree
2019-07-23 Jacek Kowalski
Remove "tram2" source from config.php (no longer available)
b41a44 diff | tree
3 files modified
101 ■■■■ changed files
config.php 13 ●●●●● patch | view | raw | blame | history
lib/Fetch.php 80 ●●●● patch | view | raw | blame | history
parse.php 8 ●●●● patch | view | raw | blame | history
config.php
@@ -23,18 +23,7 @@
        'mapper' => $tramTypes,
        'prefix' => 't',
    ],
    'tram2' => [
        'gtfsrt' => 'ftp://ztp.krakow.pl/VehiclePositions.pb',
        'gtfsrt_file' => 'VehiclePositions_T.pb',
        'ttss' => 'http://www.ttss.krakow.pl/internetservice/geoserviceDispatcher/services/vehicleinfo/vehicles',
        'ttss_file' => 'vehicles_T.json',
        'database' => 'mapping_T.sqlite3',
        'result' => 'mapping_T.json',
        'result_vehicles' => 'vehicles_T.html',
        'mapper' => $tramTypes,
        'prefix' => 't',
    ],
];
];
foreach($sources as $name => &$source) {
    foreach(['gtfsrt_file', 'ttss_file', 'database', 'result', 'result_vehicles'] as $field) {
lib/Fetch.php
@@ -20,7 +20,7 @@
        if(!isset($url['pass'])) {
            $url['pass'] = 'anonymous@mpk.jacekk.net';
        }
        if($file == NULL) {
        if($file === NULL) {
            $file = basename($url['path']);
        }
        
@@ -37,34 +37,86 @@
        
        $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;
        if($localTime >= $remoteTime && $localSize == $remoteSize) {
            return FALSE;
        }
        
        return $updated;
        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');
        }
        return TRUE;
    }
    static function parse_http_headers($headers) {
        $hasHeader = FALSE;
        foreach($headers as $header) {
            if(substr($header, 0, 5) === 'HTTP/') {
                $code = substr($header, 9, 3);
                if($code === '304') {
                    return NULL;
                } elseif(substr($code, 0, 1) == '2') {
                    $hasHeader = TRUE;
                }
            } elseif($hasHeader && strtolower(substr($header, 0, 15)) === 'last-modified: ') {
                return strptime(substr($header, 15), 'D, d M Y H:i:s T');
            }
        }
        return FALSE;
    }
    
    static function generic($url, $file = NULL) {
        if($file == NULL) {
        if($file === NULL) {
            $file = basename($url['url']);
        }
        $data = file_get_contents($url);
        $context = [];
        if(is_file($file)) {
            $file_date = filemtime($file);
            $context['http'] = [
                'header' => [
                    'If-Modified-Since: '.gmdate('D, d M Y H:i:s T', $file_date),
                ],
            ];
        }
        $data = file_get_contents($url, FALSE, stream_context_create($context));
        $remoteTime = FALSE;
        if(isset($http_response_header) && is_array($http_response_header)) {
            $remoteTime = self::parse_http_headers($http_response_header);
            if($remoteTime === NULL) {
                return FALSE;
            }
        }
        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($remoteTime !== FALSE) {
            touch($file.'.tmp', $remoteTime);
        }
        if(!rename($file.'.tmp', $file)) {
            throw new Exception('Temporary file rename failed');
        }
        return TRUE;
    }
    static function auto($url, $file = NULL) {
        if($file === NULL) {
            $file = basename($url['url']);
        }
        if(substr($url, 0, 4) == 'ftp:') {
            return self::ftp($url, $file);
        }
        return self::generic($url, $file);
    }
}
parse.php
@@ -5,15 +5,15 @@
foreach($sources as $name => $source) {
    $logger = new Monolog\Logger('fetch_'.$name);
    try {
        $logger->info('Fetching '.$name.' position data from FTP...');
        $updated = Fetch::ftp($source['gtfsrt'], $source['gtfsrt_file']);
        $logger->info('Fetching '.$name.' GTFS position data ...');
        $updated = Fetch::auto($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::generic($source['ttss'], $source['ttss_file']);
        $logger->info('Fetching '.$name.' TTSS position data...');
        Fetch::auto($source['ttss'], $source['ttss_file']);
        
        $logger->info('Loading data...');
        $mapper = new Mapper();