Что делает
Консольная тулза на PHP, обновляет локальную базу всех .dgdat файлов с сервера 2ГИС. Не знаю, увидят ли этот пост разработчики из 2Гис, но я считаю очень неудобным обновлять карты из msi пакетов. Сделайте хотя бы так, чтобы они не засирали локальный кэш в папке windows/Installer/ и не записывались в Uninstall, честно, я как увидел, заколебался анинсталлить 92 пакета.
Для кого предназначена
— для тех, кто как я устал пользоваться штатным 2Гис апдейтером, который постоянно глючит и обрывает связь — нормально обновить все файлы — нереально;
— для тех, кому надо быстро скачать всю базу;
— для тех, кто потрошит и конвертирует dgdat в другие форматы (xls,mysql).
Минусы программы
— обновляет dgdat файлы, скачивая их целиком с сервера 2gis, штатный апдейтер скачивает дельты (не проверял :));
— не пингует адреса s1..s6.update.2gis.com на время отклика, выбирая самый быстрый сервер.
Логика работы
В локальном файле json-формата по каждому региону хранится issue (номер выпуска базы) и issue_date (дата выпуска базы). Программа скачивает список актуальных баз с сервера и сравнивает версии с локальными данными. Если файл нужно обновить, то скачиваем зипованный msiz файл с сервера 2gis, распаковываем его, с помощью 7zip выдираем из него dgdat, и обновляем информацию в локальном файле о версиях базы.
Код сырой, но рабочий, писал для себя, срочно надо было, поэтому прошу на ошибки реагировать адекватно. Вчера скачал и обновил всю базу dgdat, быстро и без гемора.
Код небольшой, поэтому и без комментов в нем все понятно.
Дополнительно нужен 7zip с модулем cab.dll в папке Formats.
Повторяю, прогу писал для себя, то есть она обновляет именно все пакеты с картами, которые есть на серваке 2Гис, так как мне нужны все карты, если вы хотите чтобы обновлялось только карты, которые есть в вашей папке локально — переделка скрипта займет несколько строчек.
Надеюсь кому-нибудь пригодится.
Минусуйте :)
static $last_len = 0;
if(file_exists("stat.json"))
$bases_info = json_decode(file_get_contents("stat.json"), 1);
$ch = curl_init('http://s1.update.2gis.com/ver3/infolist?platform=win32&include_infofiles');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
$pakages = new SimpleXmlElement($data);
foreach($pakages->package As $package)
{
$data = base64_decode($package);
$n = strpos($data, "<package_info");
$pak = substr($data, $n);
$pakxml = new SimpleXmlElement($pak);
$msifilename = $pakxml->file_name;
$dgdatfilename = str_ireplace(array(".msi","2gis"),"",$msifilename);
list($dgdatfilename,) = explode("-",$dgdatfilename);
$dgdatfilename .= ".dgdat";
$filenamez = $pakxml->file_name."z";
$msiz_size = $pakxml->data_size;
$title = (string)$pakxml->title;
$issue = (string)$bases_info[$title][issue];
if(stripos($pakxml->file_name,"2gisdata")===false)
continue;
if($issue!=$pakxml->issue || !file_exists($dgdatfilename))
{
if(!file_exists($msifilename) ||
(file_exists($msifilename) && filesize($msifilename)!=$pakxml->plain_size))
{
if(file_exists($filenamez) && filesize($filenamez)!=$msiz_size)
unlink($filenamez);
if(!file_exists($filenamez))
{
$last_len = 0;
echo "Download ".$filenamez."... ";
$fp = fopen($filenamez, 'w');
$url = "http://s1.update.2gis.com/ver3/download/".$filenamez;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progress');
curl_setopt($ch, CURLOPT_NOPROGRESS, false); // needed to make progress function work
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
echo "n";
}
if(file_exists($filenamez))
{
$data = file_get_contents($filenamez);
$decoded = gzdecode($data);
if($decoded===FALSE)
die("Stop: ungzip error.n");
file_put_contents($msifilename,$decoded);
if($pakxml->plain_size!=filesize($msifilename))
die("Stop: plain_size mismatch.n");
unlink($filenamez);
}
}
$cmd = "7z l -slt ".$msifilename;
exec($cmd, $output, $return_value);
$found = 0;
foreach($output As $line) {
if(stristr($line, "dgdat")==TRUE) {
$tofile = str_replace("Path = ","", $line);
$found = 1;
}
}
if($found == 0)
die("!!!n");
$cmd = "7z x "$msifilename" ".$tofile;
exec($cmd, $output, $return_value);
rename($tofile,$dgdatfilename);
unlink($msifilename);
}
$bases_info[$title]["issue"] = (string)$pakxml->issue;
$bases_info[$title]["issue_date"] = (string)$pakxml->issue_date;
file_put_contents("stat.json", json_encode($bases_info,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
}
function progress($download_size, $downloaded, $upload_size, $uploaded)
{
global $last_len;
if($download_size > 0) {
echo str_repeat(Chr(8), $last_len);
$str = number_format(($downloaded / $download_size * 100), 1)."%";
$last_len = strlen($str);
echo $str;
}
ob_flush();
flush();
}
Автор: mbrx