1<?php
2ini_set('display_errors', 1);
3ini_set('display_startup_errors', 1);
4error_reporting(E_ALL);
5
6if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) .'/../../../../') . '/');
7if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
8define ('MMDB', DOKU_PLUGIN .'quickstats/GEOIP/vendor/GeoLite2-City/GeoLite2-City.mmdb');
9require_once(DOKU_INC.'inc/init.php');
10require_once(DOKU_INC.'inc/io.php');
11if(!defined('NOSESSION')) define('NOSESSION',true);
12
13class qs_geoliteCity {
14    private $tempdir;
15	private $helper;
16    private $testgLCity2 = false;
17    function __construct () {
18            global $conf,$argv;
19           $this->helper = plugin_load('helper', 'quickstats');
20
21            if(!empty($argv[1]) || $_REQUEST['test'] == 'test')  {
22                if($argv && $argv[0]) {
23                     echo 'argv = ' . $argv[0]  . "\n";
24                }
25                else echo print_r($_REQUEST,1);
26               $this->testgLCity2 = true;
27           }
28
29            $this->tempdir = $conf['tmpdir'];
30            if(!file_exists($this->tempdir . '/tmp')) {
31                echo "creating tmp directory: " . $this->tempdir . '/tmp' . "\n";
32                mkdir($this->tempdir . '/tmp');
33            }
34            else {
35                  echo "Checking for clean working directory\n";
36                  $this->process_gcity(true);
37                  $this->cleanup(true);
38            }
39
40    }
41
42    function get_GeoLiteCity() {
43        @set_time_limit(120);
44
45         $url = "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=J7if1Q83hu4tiUVS&suffix=tar.gz";
46		 // "https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz";
47                 if($this->testgLCity2) {
48            $url = "http://epicurus.bz/GeoLite2-City.tar.gz";
49         //   $url = "https://mturner.org/userfiles/GeoLite2-City.tar.gz";
50           $this->qs_say("testing  %s", $url);
51        }
52         else $this->qs_say("GeoLiteCity url:  %s", $url);
53        $gzfile = $this->tempdir  .  '/GeoLite2-City.tar.gz';
54
55        $http = new DokuHTTPClient();
56        $http->max_bodysize = 36777216;
57        $http->timeout = 120;
58        $http->keep_alive = false;
59
60        $data = $http->get($url);
61        if(!$data) {
62            $this->qs_say($this->helper->getLang('download_fail'),  $gzfile);
63            return;
64          }
65
66         $fp = @fopen($gzfile,'wb');
67          if($fp === false) {
68               $this->qs_say($this->helper->getLang('write_fail'),  $gzfile);
69               return;
70          }
71          if(!fwrite($fp,$data)) {
72             $this->qs_say($this->helper->getLang('write_fail'),  $gzfile);
73             return;
74          }
75          fclose($fp);
76         $this->qs_say($this->helper->getLang('file_saved'),  $gzfile);
77    }
78
79
80
81     function qs_unpack() {
82        $ro = ini_get('phar.readonly');
83        if($ro) ini_set('phar.readonly','0');
84        $files = scandir($this->tempdir);
85
86        foreach ($files as $file) {
87            if(preg_match("#GeoLite2-City.tar.gz#", $file,$matches)) {
88               $file = $this->tempdir."/$file";
89               $p = new PharData($file);
90			   $tar = str_replace('.gz', "", $file);
91			   $this->qs_say($this->helper->getLang('tar_extracted'),  $tar);
92			   if(file_exists($tar)){
93				 $this->qs_say($this->helper->getLang('file_exists'),"\n$file\n$tar\n");
94				 exit;
95			   }
96               $p->decompress(); // creates /path/to/my.tar
97
98
99                try {
100                     $phar = new PharData($tar);
101                     $phar->extractTo($this->tempdir.'/tmp'); // extract all files
102                } catch (Exception $e) {
103                    echo $e->getMessage() . "\n";
104                }
105            }
106       }
107    }
108
109  function process_gcity($ini = null) {
110   $tmpdir_files = scandir($this->tempdir . '/' . 'tmp');
111    foreach ($tmpdir_files as $tmpfile) {
112         $current_file = $this->tempdir . '/' . "tmp/${tmpfile}";
113          if(preg_match("#(?i)GeoLite2-City_\d+#",$tmpfile) ) {
114              if(is_dir($this->tempdir . '/' . 'tmp/'. $tmpfile)) {
115                  $geo_dir_name =  $this->tempdir . '/' . 'tmp/'. $tmpfile;
116                  $geo_dir = scandir($this->tempdir . '/' . 'tmp/'. $tmpfile);
117                   foreach($geo_dir as $gfile) {
118                      if(!is_dir($this->tempdir . '/' . 'tmp/'. $gfile)) {
119                          if(preg_match("/\.mmdb$/",$gfile) && !$ini) {
120                            $this->qs_say($this->helper->getLang('installing_mmdb'),  MMDB);
121                              rename($geo_dir_name. "/$gfile",MMDB);
122                             continue;
123                          }
124                           $discard = "$geo_dir_name/$gfile";
125                           if($ini) {
126                               echo "Unlinking $discard\n";
127                           }
128                         if(is_writable($discard))
129                           unlink ($discard);
130                      }
131                  }
132              }
133              else {
134                  echo $this->tempdir . '/' . 'tmp/'. $tmpfile . " is not a directory\n";
135              }
136          }
137      }
138
139       if(file_exists($geo_dir_name )) {
140           rmdir($geo_dir_name);
141        }
142    }
143
144    function cleanup() {
145        $to_cleanup = scandir($this->tempdir);
146
147        foreach($to_cleanup as $file) {
148            $del = $this->tempdir . '/' . $file;
149            if(!is_dir($del) && preg_match("/GeoLite2-City/i",$file)) {
150              unlink($del);
151            }
152            else if($file == 'tmp') {
153                rmdir($this->tempdir . '/' .'tmp');
154            }
155        }
156    }
157
158    function  qs_say(){
159            $args = func_get_args();
160            echo vsprintf(array_shift($args)."\n",$args);
161            ob_flush();
162        }
163}
164
165$geoLite = new qs_geoliteCity();
166$geoLite->get_GeoLiteCity();
167$geoLite->qs_unpack() ;
168$geoLite->process_gcity();
169$geoLite->cleanup(true);
170
171