diff --git a/utils/import_cli.php b/utils/import_cli.php new file mode 100755 index 0000000..7a50c8b --- /dev/null +++ b/utils/import_cli.php @@ -0,0 +1,175 @@ +#!/usr/bin/env php +. + */ + +use GetOpt\GetOpt; +use GetOpt\Option; +use GetOpt\Operand; + +require_once(dirname(__DIR__) . "/helpers/auth.php"); +require_once(ROOT_DIR . "/helpers/track.php"); +require_once(ROOT_DIR . "/helpers/position.php"); +require_once(ROOT_DIR . "/helpers/utils.php"); +require_once(ROOT_DIR . "/lang.php"); +require_once(ROOT_DIR . '/vendor/autoload.php'); + +// check we are running in CLI mode +if (PHP_SAPI != 'cli') { + exit('Call me on CLI only!' . PHP_EOL); +} + +// set up argument parsing +$getopt = new GetOpt(); +$getopt->addOptions([ + Option::create('h', 'help') + ->setDescription('Show usage/help'), + + Option::create('u', 'user-id', \GetOpt\GetOpt::OPTIONAL_ARGUMENT) + ->setDescription('Which user to import the track(s) for (default: 1)') + ->setDefaultValue(1) + ->setValidation('is_numeric', '%s has to be an integer'), + + Option::create('e', 'import-existing-track') + ->setDescription('Import already existing tracks (based on track name)'), + + Option::create('l', 'skip-last-track') + ->setDescription('Skip the last track (for special use cases)'), +]); + +$getopt->addOperand( + Operand::create('gpx', \GetOpt\Operand::MULTIPLE + \GetOpt\Operand::REQUIRED) + ->setDescription('One or more GPX files to import') + ->setValidation('is_readable', '%s: %s is not readable') +); + +// process arguments and catch user errors +try { + $getopt->process(); +} catch (Exception $exception) { + // be nice if the user just asked for help + if (!$getopt->getOption('help')) { + exit('ERROR: '.$exception->getMessage().PHP_EOL); + } +} + +// show help and quit +if ($getopt->getOption('help')) { + exit($getopt->getHelpText()); +} + +// get all tracks for user id +$userId = $getopt->getOption('user-id'); +if (!$getopt->getOption('import-existing-track')) { + $tracksArr = uTrack::getAll($userId); +} + +// lets import some GPX tracks! +$gpxFiles = $getopt->getOperand('gpx'); +foreach ($gpxFiles as $i => $gpxFile) { + // skip last track? + if ($getopt->getOption('skip-last-track') && $i === count($gpxFiles) - 1) continue; + + $gpxName = basename($gpxFile); + + if (!$getopt->getOption('import-existing-track')) { + foreach ($tracksArr as $track) { + if ($track->name === $gpxName) { + print('WARNING: '.$gpxName.' already present, skipping...'.PHP_EOL); + continue 2; + } + } + } + + print('importing '.$gpxFile.'...'.PHP_EOL); + + $gpx = false; + libxml_use_internal_errors(true); + if ($gpxFile && file_exists($gpxFile)) { + $gpx = simplexml_load_file($gpxFile); + } + + if ($gpx === false) { + $message = $lang["iparsefailure"]; + $parserMessages = []; + foreach(libxml_get_errors() as $parseError) { + $parserMessages[] = $parseError->message; + } + $parserMessage = implode(", ", $parserMessages); + if (!empty($parserMessage)) { + $message .= ": $parserMessage"; + } + uUtils::exitWithError($message); + } + else if ($gpx->getName() != "gpx") { + uUtils::exitWithError($lang["iparsefailure"]); + } + else if (empty($gpx->trk)) { + uUtils::exitWithError($lang["idatafailure"]); + } + + $trackCnt = 0; + foreach ($gpx->trk as $trk) { + $trackName = empty($trk->name) ? $gpxName : (string) $trk->name; + $metaName = empty($gpx->metadata->name) ? NULL : (string) $gpx->metadata->name; + $trackId = uTrack::add($userId, $trackName, $metaName); + if ($trackId === false) { + uUtils::exitWithError($lang["servererror"]); + break; + } + $track = new uTrack($trackId); + $posCnt = 0; + + foreach($trk->trkseg as $segment) { + foreach($segment->trkpt as $point) { + if (!isset($point["lat"]) || !isset($point["lon"])) { + $track->delete(); + uUtils::exitWithError($lang["iparsefailure"]); + } + $time = isset($point->time) ? strtotime($point->time) : 0; + $altitude = isset($point->ele) ? (double) $point->ele : NULL; + $speed = NULL; + $bearing = NULL; + $accuracy = NULL; + $provider = "gps"; + if (!empty($point->extensions)) { + // parse ulogger extensions + $ext = $point->extensions->children('ulogger', TRUE); + if (count($ext->speed)) { $speed = (double) $ext->speed; } + if (count($ext->bearing)) { $bearing = (double) $ext->bearing; } + if (count($ext->accuracy)) { $accuracy = (int) $ext->accuracy; } + if (count($ext->provider)) { $provider = (string) $ext->provider; } + } + $ret = $track->addPosition($userId, + $time, (double) $point["lat"], (double) $point["lon"], $altitude, + $speed, $bearing, $accuracy, $provider, NULL, NULL); + if ($ret === false) { + $track->delete(); + uUtils::exitWithError($lang["servererror"]); + } + $posCnt++; + } + } + if ($posCnt) { + $trackCnt++; + } else { + $track->delete(); + } + } +} +?>