3 require_once 'Pman/Roo.php';
5 class Pman_Core_Import_Core_geoip extends Pman_Roo
7 static $cli_desc = "Insert the geoip database";
9 static $cli_opts = array();
11 var $id_mapping = array();
15 $ff = HTML_FlexyFramework::get();
19 HTML_FlexyFramework::ensureSingle(__FILE__, $this);
35 PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
37 $location = '/tmp/GeoLite2-City-Locations.csv';
38 $block = '/tmp/GeoLite2-City-Blocks.csv';
40 if(!file_exists($location) || !file_exists($block)){
41 $this->jerr('GeoLite2-City-Locations.csv OR GeoLite2-City-Blocks.csv does not exists?!');
44 $this->log("Insert location data start");
46 $this->insertLocation($location);
48 $this->log("Insert Block data start");
50 $this->insertBlock($block);
55 function insertLocation($csv)
57 ini_set("auto_detect_line_endings", true);
61 $fh = fopen($csv, 'r');
64 $this->jerr("invalid location file");
68 'GEONAME_ID', 'CONTINENT_CODE', 'CONTINENT_NAME',
69 'COUNTRY_ISO_CODE', 'COUNTRY_NAME', 'SUBDIVISION_ISO_CODE',
70 'SUBDIVISION_NAME', 'CITY_NAME', 'METRO_CODE',
77 $this->total = count(file($csv));
80 while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
81 if(!array_filter($n)){ // empty row
88 $cols[] = strtoupper(trim($k));
95 if (!in_array($r,$cols)) {
105 foreach($cols as $i=>$k) {
106 $row[$k] = trim($n[$i]);
109 $this->processLocation($row);
113 $this->processStatus();
118 function insertBlock($csv)
120 ini_set("auto_detect_line_endings", true);
122 $fh = fopen($csv, 'r');
124 $this->jerr("invalid location file");
128 'NETWORK_START_IP', 'NETWORK_MASK_LENGTH', 'GEONAME_ID',
129 'REGISTERED_COUNTRY_GEONAME_ID', 'REPRESENTED_COUNTRY_GEONAME_ID', 'POSTAL_CODE',
130 'LATITUDE', 'LONGITUDE', 'IS_ANONYMOUS_PROXY',
131 'IS_SATELLITE_PROVIDER'
136 $this->processed = 0;
137 $this->total = count(file($csv));
140 while(false !== ($n = fgetcsv($fh,10000, ',', '"'))) {
141 if(!array_filter($n)){ // empty row
148 $cols[] = strtoupper(trim($k));
154 foreach($req as $r) {
155 if (!in_array($r,$cols)) {
165 foreach($cols as $i=>$k) {
166 $row[$k] = trim($n[$i]);
169 $this->processBlock($row);
173 $this->processStatus();
181 function processLocation($row)
183 $continent = $this->processContinent($row['CONTINENT_CODE'], $row['CONTINENT_NAME']);
185 $country = $this->processCountry($row['COUNTRY_ISO_CODE'], $row['COUNTRY_NAME'], $continent);
187 $division = $this->processDivision($row['SUBDIVISION_ISO_CODE'], $row['SUBDIVISION_NAME']);
189 $city = $this->processCity($row['CITY_NAME'], $row['METRO_CODE'], $row['TIME_ZONE'], $country, $division);
191 if(!empty($city) && !empty($city->id)){
192 $this->id_mapping[$row['GEONAME_ID']] = $city->id;
196 function processContinent($code, $name)
202 $continent = DB_DataObject::factory('core_geoip_continent');
203 if(!$continent->get('code', $code)){
204 $continent->setFrom(array(
206 'name' => (!empty($name)) ? $name : $code
209 $continent->insert();
215 function processCountry($code, $name, $continent)
221 $country = DB_DataObject::factory('core_geoip_country');
222 if(!$country->get('code', $code)){
223 $country->setFrom(array(
225 'name' => (!empty($name)) ? $name : $code,
226 'continent_id' => (!empty($continent) && !empty($continent->id)) ? $continent->id : 0
235 function processDivision($code, $name)
241 $division = DB_DataObject::factory('core_geoip_division');
242 if(!$division->get('code', $code)){
243 $division->setFrom(array(
245 'name' => (!empty($name)) ? $name : $code
254 function processCity($name, $metro_code, $time_zone, $country, $division)
260 $city = DB_DataObject::factory('core_geoip_city');
262 if($city->get('name', $name)){
266 $city->setFrom(array(
268 'metro_code' => $metro_code,
269 'time_zone' => $time_zone,
270 'country_id' => (!empty($country) && !empty($country->id)) ? $country->id : 0,
271 'division_id' => (!empty($division) && !empty($division->id)) ? $division->id : 0
280 function processBlock($row)
282 if(empty($this->id_mapping[$row['GEONAME_ID']])){
283 $this->log("Missing mapping for {$row['GEONAME_ID']}");
284 $this->log("IP : {$row['NETWORK_START_IP']}");
288 $network_mapping = DB_DataObject::factory('core_geoip_network_mapping');
290 $start_ip = array_pop(explode(":", $row['NETWORK_START_IP']));
292 $network_mapping->setFrom(array(
293 'start_ip' => $start_ip,
294 'mask_length' => pow(2, (128 - $row['NETWORK_MASK_LENGTH'])),
295 'city_id' => $this->id_mapping[$row['GEONAME_ID']]
298 if(!$network_mapping->find(true)){
299 $network_mapping->insert();
302 $location = DB_DataObject::factory('core_geoip_location');
303 if(!$location->get('city_id', $network_mapping->city_id)){
304 $location->setFrom(array(
305 'latitude' => $row['LATITUDE'],
306 'longitude' => $row['LONGITUDE'],
307 'city_id' => $network_mapping->city_id
312 if(!empty($row['POSTAL_CODE'])){
313 $city = DB_DataObject::factory('core_geoip_city');
314 if($city->get($network_mapping->city_id)){
319 $city->postal_code = $row['POSTAL_CODE'];
326 function processStatus()
328 echo "\033[K"; // Erase to end of line:
330 if (strlen($this->echo)) {
331 echo "\033[".strlen($this->echo)."D"; // Move $length characters backward
334 $this->echo = str_pad(ROUND(($this->processed / $this->total),2) * 100, 3, ' ', STR_PAD_LEFT) .
335 " % (" . str_pad(($this->processed), strlen($this->total), ' ', STR_PAD_LEFT) .
336 " / {$this->total})";
341 if($this->processed == $this->total){