This is an automated email from the ASF dual-hosted git repository. jpirek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans-tools.git
The following commit(s) were added to refs/heads/master by this push: new b7d9ffb NetBeans Active Users statistics scripts new 0945026 Merge pull request #38 from jpirek/master b7d9ffb is described below commit b7d9ffba8e0b6b294220ef688620a11c1b2bf228 Author: Jan Pirek <jan.pi...@oracle.com> AuthorDate: Wed Nov 18 10:44:11 2020 +0100 NetBeans Active Users statistics scripts --- pp3/au/Db.php | 60 +++ pp3/au/Importer.php | 255 +++++++++++ pp3/au/Logger.php | 74 +++ pp3/au/Runner.php | 237 ++++++++++ pp3/au/build-dashboard_v2.php | 334 ++++++++++++++ pp3/au/config.php | 21 + pp3/au/db_connect.php.inc | 11 + pp3/au/jchalupa.sql.gz | Bin 0 -> 20268 bytes pp3/au/last-date-dlc | 1 + pp3/au/lib/GeoIP.dat | Bin 0 -> 1097170 bytes pp3/au/lib/Getopt.php | 970 ++++++++++++++++++++++++++++++++++++++++ pp3/au/lib/Getopt/Exception.php | 66 +++ pp3/au/lib/geoip.inc | 509 +++++++++++++++++++++ pp3/au/run-au-import.php | 48 ++ 14 files changed, 2586 insertions(+) diff --git a/pp3/au/Db.php b/pp3/au/Db.php new file mode 100755 index 0000000..85a803d --- /dev/null +++ b/pp3/au/Db.php @@ -0,0 +1,60 @@ +<?php + +/** + * Super simple mysql wrapper + * + */ +class Db { + public static $counter=0; + + private static $_isConnected = false; + private static $_insData=array(); + private static $_insCounter=0; + + private static function connect() { + $link = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD); + if (!$link) { + throw new Exception('Can\'t connect to DB: '.DB_USER.':*****@'.DB_HOST); + } + $db_selected = mysql_select_db(DB_NAME, $link); + if (!$db_selected) { + throw new Exception('Can\'t select DB: '.DB_USER.':*****@'.DB_HOST.'/'.DB_NAME); + } + self::$_isConnected = true; + } + + /** + * Simple mysql query wrapper which will log the SQL errors for us + * @param string $sql SQL statement to perform + * @return resource + */ + public static function query($sql) { + if (self::$_isConnected == false) { + self::connect(); + } + $result = mysql_query($sql); + if ($result != false) { + self::$counter++; + return $result; + } else { + // log error + Logger::write(Logger::DEBUG, 'SQL error for: '.$sql.'; ERR: '.mysql_error()); + return false; + } + } + + public static function deferredPingsInsert($data) { + self::$_insCounter++; + self::$_insData[]=$data; + if(0==(self::$_insCounter%1000)) { + $ret=self::query('INSERT INTO pings (ip_id, ts, path_id, distro_id, config_id, user_id, user2_id, response, size) VALUES '.implode(',', self::$_insData)); + self::$_insCounter=0; + self::$_insData=array(); + return $ret; + } + return true; + } + +} + +?> diff --git a/pp3/au/Importer.php b/pp3/au/Importer.php new file mode 100755 index 0000000..ffa4af1 --- /dev/null +++ b/pp3/au/Importer.php @@ -0,0 +1,255 @@ +<?php + +/** + * Importer takes parsed data and import it to DB + * + */ +class Importer { + + public static $ipCache; + public static $userCache; + public static $user2Cache; + public static $catalogCache; + public static $distroCache; + public static $configCache; + private static $_cacheLoaded = false; + private static $_source; + private static $_packs; + + public static function import($row, $source) { + //die(var_dump($row)); + self::$_source = $source; + // load up catalogs, distros, configs to cache + if (self::$_cacheLoaded == false) { + self::loadCache(); + } + // let's import that + $ip = $row['ip']; + $ts = $row['ts']; + $path = $row['path']; + $distro = $row['distro']; + $user_id = $row['user_id']; + $user2_id = $row['user2_id']; + $response = $row['response']; + $size = $row['size']; + + // resolve the catalog + if (!self::$catalogCache[$path]) { + Db::query("INSERT INTO catalogs (path, source) VALUES ('$path', '$source')"); + $catalogId = mysql_insert_id(); + self::$catalogCache[$path] = $catalogId; + } else { + $catalogId = self::$catalogCache[$path]; + } + + // resolve the distro + if (preg_match('/(NB[A-Z]*)?_?([_A-Z]+)?/', $distro, $match)) { + $distro_code = ""; + $config = ""; + $config_sig = 0; + if (isset($match[1])) { + $distro_code = $match[1]; + } + if (isset($match[2])) { + $config = $match[2]; + $config_parts = explode("_", $config); + foreach ($config_parts as $part) { + if (isset(self::$_packs[$part])) { + $config_sig += self::$_packs[$part]; + } else { + $warning_count++; + Logger::write(Logger::INFO, "Uknown pack ID: $part; $config; $distro_code"); + } + } + } + } + if (!self::$distroCache[$distro_code]) { + Db::query("INSERT INTO distros (distro) VALUES ('$distro_code')"); + $distroId = mysql_insert_id(); + self::$distroCache[$distro_code] = $distroId; + } else { + $distroId = self::$distroCache[$distro_code]; + } + + // resolve config + if (!self::$configCache[$config]) { + Db::query("INSERT INTO configs (config, signature) VALUES ('$config', $config_sig)"); + $configId = mysql_insert_id(); + self::$configCache[$config] = $configId; + } else { + $configId = self::$configCache[$config]; + } + + // resolve the IP address +// if (!self::$ipCache[$ip]) { +// // lookup db for it +// $res = Db::query('SELECT id FROM ips WHERE ip="' . $ip . '" LIMIT 1'); +// if ($res) { +// if (mysql_num_rows($res) > 0) { +// $row = mysql_fetch_assoc($res); +// $ipId = $row['id']; +// self::$ipCache[$ip] = $ipId; +// } else { +// Db::query("INSERT INTO ips (ip, country) VALUES ('$ip' ,'" . getCCByIP($ip) . "')"); +// $ipId = mysql_insert_id(); +// self::$ipCache[$ip] = $ipId; +// } +// } +// } else { +// $ipId = self::$ipCache[$ip]; +// } + $ipId=0; + + // resolve userId + $tsInt = strtotime($ts); + if (!self::$userCache[$user_id]) { + $res = Db::query('SELECT id, since, last_seen FROM users WHERE unique_id="' . $user_id . '"'); + if ($res) { + if (mysql_num_rows($res) > 0) { + $row = mysql_fetch_assoc($res); + $userId = $row['id']; + // if this ping is newer then one in DB, save it as last seen and calc delay + if ($tsInt > $row['last_seen']) { + // calc the delay since last ping + $delay = round(($tsInt - $row['last_seen']) / (60 * 60 * 24)); + // update last seen and delay + if($delay>0) { + Db::query("UPDATE users SET last_seen=$tsInt, catalog_id=$catalogId, delay=$delay WHERE id=" . $userId); + } + } + self::$userCache[$user_id] = array('id' => $userId, 'since' => $row['since'], 'last_seen' => $tsInt, 'catalog_id' => $catalogId, 'delay' => $delay); + } else { + Db::query("INSERT INTO users (unique_id, since, last_seen, catalog_id, delay) VALUES ('$user_id', '$ts', $tsInt, $catalogId, 9999)"); + $userId = mysql_insert_id(); + self::$userCache[$user_id] = array('id' => $userId, 'since' => $ts, 'last_seen' => $tsInt, 'catalog_id' => $catalogId, 'delay' => 9999); + } + } + } else { + $userId=self::$userCache[$user_id]['id']; + // check if the hit from cache has newer timestamp, if so, mark user for update her timestamp + if (self::$userCache[$user_id]['since'] > $ts) { + $updateUsers = array('id' => self::$userCache[$user_id]['id'], 'since' => $ts); + } + } + + // resolve userId + if (!self::$user2Cache[$user2_id]) { + $res = Db::query('SELECT id, since, last_seen FROM users2 WHERE unique_id="' . $user2_id . '"'); + if ($res) { + if (mysql_num_rows($res) > 0) { + $row = mysql_fetch_assoc($res); + $user2Id = $row['id']; + // if this ping is newer then one in DB, save it as last seen and calc delay + if ($tsInt > $row['last_seen']) { + // calc the delay since last ping + $delay = round(($tsInt - $row['last_seen']) / (60 * 60 * 24)); + // update last seen and delay + if($delay>0) { + Db::query("UPDATE users2 SET last_seen=$tsInt, delay=$delay WHERE id=" . $user2Id); + } + } + self::$user2Cache[$user2_id] = array('id' => $user2Id, 'since' => $row['since'], 'last_seen' => $tsInt, 'delay' => $delay); + } else { + Db::query("INSERT INTO users2 (unique_id, since, last_seen, delay) VALUES ('$user2_id', '$ts', $tsInt,9999)"); + $user2Id = mysql_insert_id(); + self::$user2Cache[$user2_id] = array('id' => $user2Id, 'since' => $ts, 'last_seen' => $tsInt, 'delay' => 9999); + } + } + } else { + $user2Id=self::$user2Cache[$user2_id]['id']; + // check if the hit from cache has newer timestamp, if so, mark user for update her timestamp + if (self::$user2Cache[$user2_id]['since'] > $ts) { + $updateUsers2 = array('id' => self::$user2Cache[$user2_id]['id'], 'since' => $ts); + } + } + + + // now save it to hits table finally + $res = Db::query("INSERT INTO pings (ip_id, ts, path_id, distro_id, config_id, user_id, user2_id, response, size) VALUES ($ipId, '$ts', $catalogId, $distroId, $configId, $userId, $user2Id, $response, $size)"); + if ($res) { + $ret = true; + } else { + $ret = false; + } + + // now update users since timestamps (might be case if we back import older logs) + if (!empty($updateUsers)) { + foreach ($updateUsers as $u) { + Db::query("UPDATE users SET since='" . $u['since'] . "' WHERE id=" . $u['id']); + } + } + if (!empty($updateUsers2)) { + foreach ($updateUsers2 as $u) { + Db::query("UPDATE users2 SET since='" . $u['since'] . "' WHERE id=" . $u['id']); + } + } + return $ret; + } + + private function loadCache() { + $memBeforeCache = memory_get_usage(); + $res = Db::query('SELECT id, path FROM catalogs WHERE source="' . self::$_source . '"'); + if ($res) { + while ($r = mysql_fetch_assoc($res)) { + self::$catalogCache[$r['path']] = $r['id']; + } + } + $res = Db::query('SELECT id, config FROM configs'); + if ($res) { + while ($r = mysql_fetch_assoc($res)) { + self::$configCache[$r['config']] = $r['id']; + } + } + $res = Db::query('SELECT id, distro FROM distros'); + if ($res) { + while ($r = mysql_fetch_assoc($res)) { + self::$distroCache[$r['distro']] = $r['id']; + } + } + + // log some stats on the memory usage so we know how is the cache expensive + Logger::write(Logger::INFO, 'Caching distros, catalogs, configs took ' . round((memory_get_usage() - $memBeforeCache) / 1024000, 1) . 'MB'); + + self::$_packs = array( + 'CND' => 0x0001, + 'CRE' => 0x0002, + 'ENT' => 0x0004, + 'MOB' => 0x0008, + 'PROF' => 0x0010, + 'CDC' => 0x0020, + 'CLDC' => 0x0040, + 'JAVA' => 0x0080, + 'JAVASE' => 0x0100, + 'JAVAEE' => 0x0200, + 'JAVAME' => 0x0400, + 'WEBEE' => 0x0800, + 'PROFILER' => 0x1000, + 'PHP' => 0x2000, + 'RUBY' => 0x4000, + 'MOBILITY' => 0x8000, + 'UML' => 0x10000, + 'SOA' => 0x20000, + 'GLASSFISH' => 0x40000, + 'SJSAS' => 0x80000, + 'TOMCAT' => 0x100000, + 'VISUALWEB' => 0x200000, + 'JDK' => 0x400000, + 'MYSQL' => 0x800000, + 'GROOVY' => 0x1000000, + 'GFMOD' => 0x2000000, + 'JAVAFX' => 0x4000000, + 'WEBCOMMON' => 0x8000000, + 'FX' => 0x10000000, + 'PY' => 0x20000000, + 'JC' => 0x40000000, + 'WEBLOGIC' => 0x80000000, + 'JAVAFXSDK' => 0x100000000, + 'NB' => 0x200000000, + 'EXTIDE' => 0x400000000 + ); +self::$_cacheLoaded = true; +} + +} + +?> diff --git a/pp3/au/Logger.php b/pp3/au/Logger.php new file mode 100755 index 0000000..52a59a5 --- /dev/null +++ b/pp3/au/Logger.php @@ -0,0 +1,74 @@ +<?php + +/** + * Simple logger class + * + */ +class Logger { + + const INFO='INFO'; + const ERROR='ERROR'; + const DEBUG='DEBUG'; + const FINE='FINE'; + + /** + * Sigleton instance + * @var Logger + */ + private static $instance; + + /** + * Info log file handle + * @var file handle + */ + private $_logFileHandler; + + /** + * Log info level message and echo it as well + * @param string $message + */ + public static function write($level, $message) { + if (self::$instance) { + fwrite(self::$instance->_logFileHandler, date('Y-m-d H:i:s') . ' - [' . strtoupper($level) . '] - ' . $message . "\n"); + } + if ($level!= self::DEBUG && $level!=self::FINE) { + // write out only info+error + echo date('Y-m-d H:i:s') . ' - [' . strtoupper($level) . '] - ' . $message . "\n"; + } + } + + private function __construct($logFile) { + $this->_logFileHandler = fopen($logFile, 'w'); + if ($this->_logFileHandler == false) { + throw new Exception('Unable to create the info logfile ' . $logFile); + } + } + + public function __destruct() { + // close file handlers when the object is going down + fclose($this->_logFileHandler); + } + + /** + * Singleton init method + * @param string $logFile Path of the logfile + * @return Logger + */ + public static function init($logFile) { + if (!isset(self::$instance)) { + self::$instance = new Logger($logFile); + } + return self::$instance; + } + + public function __clone() { + trigger_error('Clone is not allowed.', E_USER_ERROR); + } + + public function __wakeup() { + trigger_error('Unserializing is not allowed.', E_USER_ERROR); + } + +} + +?> diff --git a/pp3/au/Runner.php b/pp3/au/Runner.php new file mode 100755 index 0000000..6fbcf5a --- /dev/null +++ b/pp3/au/Runner.php @@ -0,0 +1,237 @@ +<?php + +/** + * Main Runner which handles triggering individual tasks based on + * the cmdline params specifying what to run for what day + * + */ +class Runner { + + static $currentDate; + static $grabbedLogFile; + static $product; + + + /** + * Run + * @param string $source Resource to run + * @return void + */ + public static function run($source) { + $availaleSources = array('dlc', 'nb', 'vvm'); + // prepare the queue of products to run for + if ($source == 'all') { + $runSources = $availaleSources; + } else { + if (in_array($source, $availaleSources)) { + $runSources = array($source); + } else { + //unknown product + throw new Exception('Unknown source specified ' . $source); + } + } + self::lock(); + foreach ($runSources as $p) { + self::procesSource($p); + } + self::unlock(); + } + + private function procesSource($source) { + Logger::write(Logger::INFO, 'Starting processing soucre: ' . $source); + if (self::grabSourceLogfile($source) == true) { + // reset Db counter + Db::$counter = 0; + self::parseLogfile($source); + self::removeLogfile(); + self::incrementRunDate($source); + } + } + + //dsd + + private function parseLogfile($source) { + $importCounter = 0; + Logger::write(Logger::INFO, 'Starting parsing of the ' . $source . ' logfile ' . self::$grabbedLogFile); + $months = array( + 'Jan' => '01', + 'Feb' => '02', + 'Mar' => '03', + 'Apr' => '04', + 'May' => '05', + 'Jun' => '06', + 'Jul' => '07', + 'Aug' => '08', + 'Sep' => '09', + 'Oct' => '10', + 'Nov' => '11', + 'Dec' => '12' + ); + $handle = fopen(self::$grabbedLogFile, 'r'); + if ($handle) { + $nl = $nok = 0; + while (($line = fgets($handle)) !== false) { + $hit = false; + // only interested in requests that include the 'unique' identifier as they represent the AU pings + if (!strstr($line, '?unique=') || strstr($line, '/hotfixes/') || strstr($line, '/thirdparty/')) { + $nl++; + continue; + } + switch ($source) { + case 'dlc': + $line=str_replace('<%JSON:httpd_access%> ','', $line); + $jsonLog = json_decode($line, true); + $preg='/^(.+?)\?unique=(unique%3D)?([_A-Z-]+)?(0)?([a-f0-9-]+)(_[a-f0-9-]+)?(.*)?/'; + $m = array(); + $hit = preg_match($preg, $jsonLog['request'], $match); + if($hit) { + $ip = $jsonLog['clientip']; + $date = date('Y-m-d', strtotime($jsonLog['time'])); + $time = date('H:i:s', strtotime($jsonLog['time'])); + //$timestamp = $match[1].' '.$match[2]; + $path = $jsonLog['uri']; + $product_id = $match[3]; + $user_id = $match[5]; + if (isset($match[6]) && substr($match[6], 0, 1) == '_') { + $super_id = substr($match[6], 1); + } else { + $super_id = ""; + } + $response = $jsonLog['status']; + $bytes = $jsonLog['bytes']; + } + break; + + } + // let's parse it and fill these: $ip,$date $time,$path,$product_id,$user_id,$super_id,$response,$bytes + if($hit) { + + // check the unique ID format + // prior to NB 5.5.1, the ID was just a timestamp (current time in millis), + // since NB 5.5.1, the ID is a standard UUID: 01234567-89ab-cdef-0123-456789abcdef + if (!preg_match('/^(([0-9]{5,12})|([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}))/', $user_id, $match)) { + Logger::write(Logger::DEBUG, self::$grabbedLogFile . ": suspicious user ID '$user_id' in line: $nl - $line"); + } else { + // in 6.5, a truly unique user ID (super ID) has been added, + // check the validity of this ID in UUID format, if available + if (strlen($super_id) > 0 && !preg_match('/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/', $super_id, $match)) { + Logger::write(Logger::DEBUG, self::$grabbedLogFile . ": suspicious super ID '$super_id' in line: $nl - $line"); + // log a warning, but don't stop here, if the super ID is invalid, + // just ignore it + $super_id = ""; + } + // return data found, ignore invalid requests (404) + if (strcmp($response, "404")) { + try { + // import it to DB + if (Importer::import(array('ip' => $ip, 'ts' => $date . " " . $time, 'path' => $path, 'distro' => $product_id, 'user_id' => $user_id, 'user2_id' => $super_id, 'response' => $response, 'size' => $bytes), $source) == true) { + $importCounter++; + } + } catch (Exception $e) { + Logger::write(Logger::ERROR, 'Error happened during log entry import: ' . $e->getMessage()); + } + $nok++; + } + } + + } + $nl++; + } + Logger::write(Logger::INFO, 'Parsed ' . $nl . ' lines of the log, used ' . $nok . ' for importing'); + Logger::write(Logger::INFO, 'Really inported into DB were ' . $importCounter . ' AU hits (needed ' . Db::$counter . ' queries)'); + } else { + throw new Exception('Unable to open decompressed logfile for parsing ' . self::$grabbedLogFile); + } + return true; + } + + private function grabSourceLogfile($source) { + // get the current date + $currentDate = strtotime('+1 day', self::getLastRunDate($source)); + Logger::write(Logger::INFO, 'Current date set to ' . date('Y-m-d', $currentDate)); + // put together the path to the source logfile + switch ($source) { + case 'nb': // CONSTANT to avoid typo! + $filename = 'access_' . date('Ymd', $currentDate); + $url = URL_PREFIX_NB . date('Y_m', $currentDate) . '/' . $filename . '.gz'; + break; + case 'vvm': + $next_date = mktime(0, 0, 0, date("m", $currentDate), date("d", $currentDate) + 1, date("Y", $currentDate)); + $filename = date('Ymd', $currentDate) . "-" . date('Ymd', $next_date) . ".log"; + $url = URL_PREFIX_VVM . $filename . ".gz"; + break; + case 'dlc': + $filename = 'netbeans-vm.apache.org_access.log_' . date('Ymd', $currentDate); + $url = URL_PREFIX_DLC . date('Y_m', $currentDate) . '/' . $filename . '.gz'; + break; + default: + throw new Exception('Unknown source: ' . $source); + } + self::$grabbedLogFile = $filename; + self::$currentDate = $currentDate; + Logger::write(Logger::INFO, 'Going to download the source logfile: ' . $url); + // grab it using wget + system("wget --quiet $url", $returnVal); + if ($returnVal === 0) { + Logger::write(Logger::INFO, 'Source logfile downloaded'); + // decompress it + system("gzip -fd $filename.gz", $returnVal); + if ($returnVal === 0) { + Logger::write(Logger::INFO, 'Source logfile decompressed'); + return true; + } + } else { + Logger::write(Logger::INFO, 'Source logfile not available'); + return false; + } + } + + private function getLastRunDate($source) { + $ld = file(LAST_DATE_FILE_PREFIX . $source); + if ($ld) { + Logger::write(Logger::INFO, 'Last run date identified as ' . trim($ld[0], "\n")); + return strtotime(trim($ld[0], "\n")); + } else { + throw new Exception('Unable to get the last run date from ' . LAST_DATE_FILE_PREFIX . $source); + } + } + + private function incrementRunDate($source) { + if (file_put_contents(LAST_DATE_FILE_PREFIX . $source, date('Y-m-d', self::$currentDate)) != false) { + Logger::write(Logger::INFO, 'Setting the last run date to ' . date('Y-m-d', self::$currentDate)); + } else { + throw new Exception('Unable to set the last run date into ' . LAST_DATE_FILE_PREFIX . $source); + } + } + + private function lock() { + if (file_exists(LOCKFILE)) { + throw new Exception('Previous run still runnig, lockfile ' . LOCKFILE . ' from ' . date("F d Y H:i:s.", filemtime(LOCKFILE)) . ". Remove lockfile first\n"); + } + system('touch ' . LOCKFILE, $retval); + if ($retval === 0) { + Logger::write(Logger::INFO, 'Lockfile created'); + } else { + throw new Exception('Can\'t create lockfile ' . LOCKFILE . "\n"); + } + } + + private function unlock() { + if (unlink(LOCKFILE) == true) { + Logger::write(Logger::INFO, 'Lockfile removed'); + } else { + throw new Exception('Not possible to remove lockfile ' . LOCKFILE); + } + } + + private function removeLogfile() { + if (unlink(self::$grabbedLogFile) == true) { + Logger::write(Logger::INFO, 'Source logfile removed'); + } else { + throw new Exception('Not possible to remove source logfile ' . self::$grabbedLogFile); + } + } + +} + +?> diff --git a/pp3/au/build-dashboard_v2.php b/pp3/au/build-dashboard_v2.php new file mode 100644 index 0000000..3328d45 --- /dev/null +++ b/pp3/au/build-dashboard_v2.php @@ -0,0 +1,334 @@ +#!/usr/bin/php +<?php +/** + * Script for calculation of AU dashboard numbers from pings, users... tables + * + * Some background: dlc+nb logfiles are parsed for IDE callbacks to catalog.xml + * and those pings are analyzed and inserted into DB, tables pings, users, catalogs, releases... + * There is enourmous number of these records - hundrets of millions. + * This script then calculates basic stats from these numbers and saves result + * to DB again so we can use them on dashboard later on. + * + * CLI options: + * --month=yyyy-mm month for which generate numbers + * --debug + * --help + * + */ +// Connection config, edit to match your env +$connection = array( + 'driver' => 'mysqli', + 'host' => 'localhost', + 'username' => 'jchalupa', + 'password' => 'root', + 'database' => 'root', + 'profiler' => TRUE, +); + +// manual delay in days for counting data +$delay = 2; + +// debug flag +$debug = false; + +// lockfile +$lockfile = '/tmp/run.lck'; + +/* + * == DO NOT EDIT BELOW THIS LINE UNLESS YOU ARE SURE YOU KNOW WHAT YOU ARE DOING == + */ +// read params from cli +require_once './lib/Getopt.php'; +try { + $opts = new Zend_Console_Getopt(array('help|h' => 'Show help', + 'month|m=s' => 'Month for which generate stats, format yyyy-mm', + 'debug|d' => 'Show debug output', + 'product|p=s' => 'Product - netbeans, vvm', + 'stat|s=s' => 'Statistic to run - au, au2, countries, distros, packs, stickiness')); + $opts->parse(); + $month = $opts->getOption('month'); + $debug = $opts->getOption('debug'); + $help = $opts->getOption('help'); + $product = $opts->getOption('product'); + $stat = ($opts->getOption('stat')) ? $opts->getOption('stat') : 'all'; + if ($help) { + echo $opts->getUsageMessage(); + exit(0); + } +} catch (Zend_Console_Exception $e) { + echo $opts->getUsageMessage(); + exit(1); +} + +if (!file_exists($lockfile)) { + // lock the run + exec('touch ' . $lockfile); + echo "Lockfile created\n"; + // use delayed value from today if it's not defined from cli + if (empty($month)) + $month = date('Y-m', strtotime('-' . $delay . ' day')); + if (empty($product)) + $product = 'netbeans'; + + // let's use DIBI for db abstraction, Uff there is PHP version check failure on nina.cz.oracle.com + //require_once(dirname(__FILE__) . "/include/dibi.min.php"); + try { + //dibi::connect($connection); + require_once './db_connect.php.inc'; + // setup stats params like dates and offsets + switch ($product) { + case 'netbeans': + $activityOffset = 7; + $monthStart = $month; // users counted monthly + break; + case 'vvm': + $activityOffset = 7; + $monthStart = date('Y-m', strtotime('-1 year', strtotime($month . '-01'))); // users counted yearly + break; + default: + $activityOffset = 7; + $monthStart = $month; + break; + } + // now put together statistics, query DB and insert results + if ($stat == 'all') { + au($month, $product, $activityOffset, $monthStart); + au2($month, $product, $activityOffset, $monthStart); + //countries($month, $product, $activityOffset, $monthStart); + //distros($month, $product, $activityOffset, $monthStart); + //packs($month, $product, $activityOffset, $monthStart); + //stickiness($month, $product); + } else { + $stat($month, $product, $activityOffset, $monthStart); + } + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + unlock(); + exit(1); + } + unlock(); + exit(0); +} else { + echo "Previous run of the script seems to be still running, lockfile found: " . $lockfile . " from " . date('F d Y H:i:s', filemtime($lockfile)) . "\nRemove lockfile first!\n"; +} + +function unlock() { + global $lockfile; + unlink($lockfile); + echo "\nLockfile removed\n"; +} + +/* + * Active Users for selected month, by releases + */ + +function au($month, $product, $activityOffset, $monthStart) { + global $dbc, $debug; + $qr = 'SELECT COUNT(DISTINCT p.user_id) AS count, r.id AS release_id, r.version AS release_version, r.lang + FROM pings p + INNER JOIN users u + ON (p.user_id=u.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN catalogs c + ON (p.path_id=c.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN releases r + ON (r.catalog_id=c.id AND r.product="' . $product . '") + WHERE IF(r.delay="Y", DATEDIFF(p.ts,u.since)>=' . $activityOffset . ', TRUE) + GROUP BY r.id'; + try { + echo "Number of $product Active Users by release version for month $month\n"; + if ($debug) + echo "Debug: " . $qr . "\n\n"; + $res = mysqli_query($dbc, $qr); + echo "Found " . mysqli_num_rows($res) . " items\n"; + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // we have some data, let's insert into db + echo "\t" . $r['release_version'] . " " . $r['lang'] . " : " . $r['count'] . " users\n"; + $qr = 'REPLACE INTO results_counts SET month="' . $month . '", release_id=' . $r['release_id'] . ', results_index_id=1, value="' . $r['count'] . '", product="' . $product . '", pack_signature=0, distro_id=0, country_id=0'; + $res2 = mysqli_query($dbc, $qr); + if (!$res2) { + echo "ERR: " . mysqli_error() . $qr . "\n"; + } + } + } catch (Exception $e) { + echo 'Failed Query: ' . $e->getMessage(); + } +} + +function au2($month, $product, $activityOffset, $monthStart) { + global $dbc, $debug; + $qr = 'SELECT COUNT(DISTINCT p.user2_id) AS count, r.id AS release_id, r.version AS release_version, r.lang + FROM pings p + INNER JOIN users2 u + ON (p.user2_id=u.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN catalogs c + ON (p.path_id=c.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN releases r + ON (r.catalog_id=c.id AND r.product="' . $product . '") + WHERE IF(r.delay="Y", DATEDIFF(p.ts,u.since)>=' . $activityOffset . ', TRUE) + GROUP BY r.id'; + try { + echo "Number of $product UNIQUE Active Users by release version for month $month\n"; + if ($debug) + echo "Debug: " . $qr . "\n\n"; + $res = mysqli_query($dbc, $qr); + echo "Found " . mysqli_num_rows($res) . " items\n"; + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // we have some data, let's insert into db + echo "\t" . $r['release_version'] . " " . $r['lang'] . " : " . $r['count'] . " users\n"; + $qr = 'REPLACE INTO results_counts SET month="' . $month . '", release_id=' . $r['release_id'] . ', results_index_id=3, value="' . $r['count'] . '", product="' . $product . '", country_id=0, pack_signature=0, distro_id=0'; + $res2 = mysqli_query($dbc, $qr); + if (!$res2) { + echo "ERR: " . mysqli_error() . $qr . "\n"; + } + } + } catch (Exception $e) { + echo 'Failed Query: ' . $e->getMessage(); + } +} + +/** + * Active users for selected month by countries + */ +function countries($month, $product, $activityOffset, $monthStart) { + global $dbc, $debug; + $qr = 'SELECT COUNT(DISTINCT p.user_id) AS count, ctr.name AS country_name, ctr.id as country_id + FROM pings p + INNER JOIN users u + ON (p.user_id=u.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN catalogs c + ON (p.path_id=c.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN releases r + ON (r.catalog_id=c.id AND r.product="' . $product . '") + INNER JOIN ips i + ON p.ip_id=i.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59" + INNER JOIN countries ctr + ON ctr.code=i.country + WHERE IF(r.delay="Y", DATEDIFF(p.ts,u.since)>=' . $activityOffset . ', TRUE) + GROUP BY i.country ORDER BY count DESC'; + try { + echo "\n\nNumber of $product Active users by countries for month $month\n"; + if ($debug) + echo "Debug: " . $qr . "\n\n"; + $res = mysqli_query($dbc, $qr); + echo "Found " . count($res) . " items\n"; + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // we have some data, let's insert into db + echo "\t" . $r['country_name'] . ": " . $r['count'] . " users\n"; + $qr = 'REPLACE INTO results_counts SET month="' . $month . '", country_id=' . $r['country_id'] . ', results_index_id=2, value="' . $r['count'] . '", product="' . $product . '", release_id=0, distro_id=0, pack_signature=0'; + $res2 = mysqli_query($dbc, $qr); + if (!$res2) { + echo "ERR: " . mysqli_error() . $qr . "\n"; + } + } + } catch (Exception $e) { + echo 'Failed Query: ' . $e->getMessage(); + } +} + +function distros($month, $product, $activityOffset, $monthStart) { + global $dbc, $debug; + $qr = 'SELECT COUNT(DISTINCT p.user2_id) AS count, d.id AS distro_id, d.distro + FROM pings p + INNER JOIN users2 u + ON (p.user2_id=u.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN catalogs c + ON (p.path_id=c.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN releases r + ON (r.catalog_id=c.id AND r.product="' . $product . '") + INNER JOIN distros d ON (d.id=p.distro_id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + WHERE IF(r.delay="Y", DATEDIFF(p.ts,u.since)>=' . $activityOffset . ', TRUE) + GROUP BY d.id'; + try { + echo "Number of $product Active Users by distribution for month $month\n"; + if ($debug) + echo "Debug: " . $qr . "\n\n"; + $res = mysqli_query($dbc, $qr); + echo "Found " . mysqli_num_rows($res) . " items\n"; + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // we have some data, let's insert into db + echo "\t" . $r['distro'] . " : " . $r['count'] . " users\n"; + $qr = 'REPLACE INTO results_counts SET month="' . $month . '", distro_id=' . $r['distro_id'] . ', results_index_id=4, value="' . $r['count'] . '", product="' . $product . '", release_id=0, pack_signature=0, country_id=0'; + $res2 = mysqli_query($dbc, $qr); + if (!$res2) { + echo "ERR: " . mysqli_error() . $qr . "\n"; + } + } + } catch (Exception $e) { + echo 'Failed Query: ' . $e->getMessage(); + } +} + +function packs($month, $product, $activityOffset, $monthStart) { + global $dbc, $debug; + $signatures = array('CND', 'CRE', 'ENT', 'MOB', 'PROF', 'CDC', 'CLDC', 'JAVA', 'JAVASE', 'JAVAEE', 'JAVAME', 'WEBEE', 'PROFILER', + 'PHP', 'RUBY', 'MOBILITY', 'UML', 'SOA', 'GLASSFISH', 'SJSAS', 'TOMCAT', 'VISUALWEB', 'JDK', 'MYSQL', + 'GROOVY', 'GFMOD', 'JAVAFX', 'WEBCOMMON', 'FX', 'PY', 'JC', 'WEBLOGIC'); + $qr = 'SELECT COUNT(DISTINCT p.user2_id) AS count, cf.id AS config_id, cf.signature + FROM pings p + INNER JOIN users2 u + ON (p.user2_id=u.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN catalogs c + ON (p.path_id=c.id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + INNER JOIN releases r + ON (r.catalog_id=c.id AND r.product="' . $product . '") + INNER JOIN configs cf ON (cf.id=p.config_id AND p.ts BETWEEN "' . $monthStart . '-01" AND "' . $month . '-31 23:59:59") + WHERE IF(r.delay="Y", DATEDIFF(p.ts,u.since)>=' . $activityOffset . ', TRUE) + GROUP BY cf.id'; + try { + echo "Number of $product Active Users by packs for month $month\n"; + if ($debug) + echo "Debug: " . $qr . "\n\n"; + $res = mysqli_query($dbc, $qr); + echo "Found " . mysqli_num_rows($res) . " items\n"; + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + // we have some data, let's count - parse the signature for packs and increment each pack according to it + $packs = explode(',', $r['signature']); + foreach ($packs as $pack) { + @$packsHits[$pack]+=$r['count']; + } + } + foreach ($packsHits as $pack => $hits) { + $qr = 'REPLACE INTO results_counts SET pack_signature="' . $pack . '", month="' . $month . '", results_index_id=5, value="' . $hits . '", product="' . $product . '", distro_id=0, release_id=0, country_id=0'; + $res2 = mysqli_query($dbc, $qr); + echo "\t" . $pack . " : " . $hits . " users\n"; + if (!$res2) { + echo "ERR: " . mysqli_error() . $qr . "\n"; + } + } + } catch (Exception $e) { + echo 'Failed Query: ' . $e->getMessage(); + } +} + +function stickiness($month, $product) { + global $dbc, $debug; + // find all final releases and for each get the stickiness distribution + $releases = array(); + $qr = 'SELECT * FROM releases WHERE product="' . $product . '" AND stable="Y"'; + $res = mysqli_query($dbc, $qr); + while ($r = mysqli_fetch_array($res, MYSQLI_ASSOC)) { + $releases[$r['version']][$r['id']] = $r['catalog_id']; + } + //die(var_dump($releases)); + if (!empty($releases)) { + echo "Found " . count($releases) . " stable releases\n"; + foreach ($releases as $version => $catalogs) { + // now query for for stickiness distribution + $qr = 'SELECT delay, count(id) as users FROM users WHERE catalog_id in (' . implode(',', $catalogs) . ') AND delay<90 and last_seen>='.strtotime('-90 days').' GROUP BY delay ORDER BY delay'; + $res2 = mysqli_query($dbc, $qr); + $data = array(); + while ($r2 = mysqli_fetch_array($res2, MYSQLI_ASSOC)) { + $data[$r2['delay']] = $r2['users']; + } + if(!empty($data)) { + // store it + echo 'Storing results for release '.$version."\n"; + $qr = 'REPLACE INTO results_counts SET month="' . $month . '", results_index_id=6, value="' . addslashes(serialize($data)) . '", product="' . $product . '", distro_id=0, release_id='. key($catalogs).', country_id=0, pack_signature="0"'; + $res2 = mysqli_query($dbc, $qr); + } + } + } else { + echo "No stable releases found\n"; + } +} +?> diff --git a/pp3/au/config.php b/pp3/au/config.php new file mode 100755 index 0000000..bc225c0 --- /dev/null +++ b/pp3/au/config.php @@ -0,0 +1,21 @@ +<?php + +/** + * Config variables + */ +DEFINE('LOGFILE_PATH', '/tmp'); +DEFINE('ADMIN_EMAIL', 'jan.pi...@oracle.com'); +DEFINE('LOCKFILE', '/tmp/run.lck'); + +// last dates file prefix +DEFINE('LAST_DATE_FILE_PREFIX', '/home/honza/checkout/web-content~au-statistics/apache-netbeans/last-date-'); + +// DB connection +DEFINE('DB_USER', 'root'); +DEFINE('DB_PASSWORD', 'root'); +DEFINE('DB_HOST', 'localhost'); +DEFINE('DB_NAME', 'jchalupa'); + +// Path to logfiles served by local web server +DEFINE('URL_PREFIX_DLC', 'http://localhost/work/oracle/au/logs/'); +?> diff --git a/pp3/au/db_connect.php.inc b/pp3/au/db_connect.php.inc new file mode 100755 index 0000000..b60f421 --- /dev/null +++ b/pp3/au/db_connect.php.inc @@ -0,0 +1,11 @@ +<?php + +DEFINE('DB_USER', 'root'); +DEFINE('DB_PASSWORD', 'root'); +DEFINE('DB_HOST', 'localhost'); +DEFINE('DB_NAME', 'jchalupa'); + +$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME) + or die ('Could not connect: ' . mysqli_connect_error()); +?> + diff --git a/pp3/au/jchalupa.sql.gz b/pp3/au/jchalupa.sql.gz new file mode 100644 index 0000000..5dd05b0 Binary files /dev/null and b/pp3/au/jchalupa.sql.gz differ diff --git a/pp3/au/last-date-dlc b/pp3/au/last-date-dlc new file mode 100755 index 0000000..a5b8a01 --- /dev/null +++ b/pp3/au/last-date-dlc @@ -0,0 +1 @@ +2020-10-31 \ No newline at end of file diff --git a/pp3/au/lib/GeoIP.dat b/pp3/au/lib/GeoIP.dat new file mode 100755 index 0000000..35bfeed Binary files /dev/null and b/pp3/au/lib/GeoIP.dat differ diff --git a/pp3/au/lib/Getopt.php b/pp3/au/lib/Getopt.php new file mode 100755 index 0000000..d603566 --- /dev/null +++ b/pp3/au/lib/Getopt.php @@ -0,0 +1,970 @@ +<?php +/** + * Zend_Console_Getopt is a class to parse options for command-line + * applications. + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to lice...@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Console_Getopt + * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Getopt.php 23775 2011-03-01 17:25:24Z ralph $ + */ + +/** + * Zend_Console_Getopt is a class to parse options for command-line + * applications. + * + * Terminology: + * Argument: an element of the argv array. This may be part of an option, + * or it may be a non-option command-line argument. + * Flag: the letter or word set off by a '-' or '--'. Example: in '--output filename', + * '--output' is the flag. + * Parameter: the additional argument that is associated with the option. + * Example: in '--output filename', the 'filename' is the parameter. + * Option: the combination of a flag and its parameter, if any. + * Example: in '--output filename', the whole thing is the option. + * + * The following features are supported: + * + * - Short flags like '-a'. Short flags are preceded by a single + * dash. Short flags may be clustered e.g. '-abc', which is the + * same as '-a' '-b' '-c'. + * - Long flags like '--verbose'. Long flags are preceded by a + * double dash. Long flags may not be clustered. + * - Options may have a parameter, e.g. '--output filename'. + * - Parameters for long flags may also be set off with an equals sign, + * e.g. '--output=filename'. + * - Parameters for long flags may be checked as string, word, or integer. + * - Automatic generation of a helpful usage message. + * - Signal end of options with '--'; subsequent arguments are treated + * as non-option arguments, even if they begin with '-'. + * - Raise exception Zend_Console_Getopt_Exception in several cases + * when invalid flags or parameters are given. Usage message is + * returned in the exception object. + * + * The format for specifying options uses a PHP associative array. + * The key is has the format of a list of pipe-separated flag names, + * followed by an optional '=' to indicate a required parameter or + * '-' to indicate an optional parameter. Following that, the type + * of parameter may be specified as 's' for string, 'w' for word, + * or 'i' for integer. + * + * Examples: + * - 'user|username|u=s' this means '--user' or '--username' or '-u' + * are synonyms, and the option requires a string parameter. + * - 'p=i' this means '-p' requires an integer parameter. No synonyms. + * - 'verbose|v-i' this means '--verbose' or '-v' are synonyms, and + * they take an optional integer parameter. + * - 'help|h' this means '--help' or '-h' are synonyms, and + * they take no parameter. + * + * The values in the associative array are strings that are used as + * brief descriptions of the options when printing a usage message. + * + * The simpler format for specifying options used by PHP's getopt() + * function is also supported. This is similar to GNU getopt and shell + * getopt format. + * + * Example: 'abc:' means options '-a', '-b', and '-c' + * are legal, and the latter requires a string parameter. + * + * @category Zend + * @package Zend_Console_Getopt + * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version Release: @package_version@ + * @since Class available since Release 0.6.0 + * + * @todo Handle params with multiple values, e.g. --colors=red,green,blue + * Set value of parameter to the array of values. Allow user to specify + * the separator with Zend_Console_Getopt::CONFIG_PARAMETER_SEPARATOR. + * If this config value is null or empty string, do not split values + * into arrays. Default separator is comma (','). + * + * @todo Handle params with multiple values specified with separate options + * e.g. --colors red --colors green --colors blue should give one + * option with an array(red, green, blue). + * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_PARAMETERS. + * Default is that subsequent options overwrite the parameter value. + * + * @todo Handle flags occurring multiple times, e.g. -v -v -v + * Set value of the option's parameter to the integer count of instances + * instead of a boolean. + * Enable with Zend_Console_Getopt::CONFIG_CUMULATIVE_FLAGS. + * Default is that the value is simply boolean true regardless of + * how many instances of the flag appear. + * + * @todo Handle flags that implicitly print usage message, e.g. --help + * + * @todo Handle freeform options, e.g. --set-variable + * Enable with Zend_Console_Getopt::CONFIG_FREEFORM_FLAGS + * All flag-like syntax is recognized, no flag generates an exception. + * + * @todo Handle numeric options, e.g. -1, -2, -3, -1000 + * Enable with Zend_Console_Getopt::CONFIG_NUMERIC_FLAGS + * The rule must specify a named flag and the '#' symbol as the + * parameter type. e.g., 'lines=#' + * + * @todo Enable user to specify header and footer content in the help message. + * + * @todo Feature request to handle option interdependencies. + * e.g. if -b is specified, -a must be specified or else the + * usage is invalid. + * + * @todo Feature request to implement callbacks. + * e.g. if -a is specified, run function 'handleOptionA'(). + */ +class Zend_Console_Getopt +{ + + /** + * The options for a given application can be in multiple formats. + * modeGnu is for traditional 'ab:c:' style getopt format. + * modeZend is for a more structured format. + */ + const MODE_ZEND = 'zend'; + const MODE_GNU = 'gnu'; + + /** + * Constant tokens for various symbols used in the mode_zend + * rule format. + */ + const PARAM_REQUIRED = '='; + const PARAM_OPTIONAL = '-'; + const TYPE_STRING = 's'; + const TYPE_WORD = 'w'; + const TYPE_INTEGER = 'i'; + + /** + * These are constants for optional behavior of this class. + * ruleMode is either 'zend' or 'gnu' or a user-defined mode. + * dashDash is true if '--' signifies the end of command-line options. + * ignoreCase is true if '--opt' and '--OPT' are implicitly synonyms. + * parseAll is true if all options on the command line should be parsed, regardless of + * whether an argument appears before them. + */ + const CONFIG_RULEMODE = 'ruleMode'; + const CONFIG_DASHDASH = 'dashDash'; + const CONFIG_IGNORECASE = 'ignoreCase'; + const CONFIG_PARSEALL = 'parseAll'; + + /** + * Defaults for getopt configuration are: + * ruleMode is 'zend' format, + * dashDash (--) token is enabled, + * ignoreCase is not enabled, + * parseAll is enabled. + */ + protected $_getoptConfig = array( + self::CONFIG_RULEMODE => self::MODE_ZEND, + self::CONFIG_DASHDASH => true, + self::CONFIG_IGNORECASE => false, + self::CONFIG_PARSEALL => true, + ); + + /** + * Stores the command-line arguments for the calling applicaion. + * + * @var array + */ + protected $_argv = array(); + + /** + * Stores the name of the calling applicaion. + * + * @var string + */ + protected $_progname = ''; + + /** + * Stores the list of legal options for this application. + * + * @var array + */ + protected $_rules = array(); + + /** + * Stores alternate spellings of legal options. + * + * @var array + */ + protected $_ruleMap = array(); + + /** + * Stores options given by the user in the current invocation + * of the application, as well as parameters given in options. + * + * @var array + */ + protected $_options = array(); + + /** + * Stores the command-line arguments other than options. + * + * @var array + */ + protected $_remainingArgs = array(); + + /** + * State of the options: parsed or not yet parsed? + * + * @var boolean + */ + protected $_parsed = false; + + /** + * The constructor takes one to three parameters. + * + * The first parameter is $rules, which may be a string for + * gnu-style format, or a structured array for Zend-style format. + * + * The second parameter is $argv, and it is optional. If not + * specified, $argv is inferred from the global argv. + * + * The third parameter is an array of configuration parameters + * to control the behavior of this instance of Getopt; it is optional. + * + * @param array $rules + * @param array $argv + * @param array $getoptConfig + * @return void + */ + public function __construct($rules, $argv = null, $getoptConfig = array()) + { + if (!isset($_SERVER['argv'])) { + require_once 'Zend/Console/Getopt/Exception.php'; + if (ini_get('register_argc_argv') == false) { + throw new Zend_Console_Getopt_Exception( + "argv is not available, because ini option 'register_argc_argv' is set Off" + ); + } else { + throw new Zend_Console_Getopt_Exception( + '$_SERVER["argv"] is not set, but Zend_Console_Getopt cannot work without this information.' + ); + } + } + + $this->_progname = $_SERVER['argv'][0]; + $this->setOptions($getoptConfig); + $this->addRules($rules); + if (!is_array($argv)) { + $argv = array_slice($_SERVER['argv'], 1); + } + if (isset($argv)) { + $this->addArguments((array)$argv); + } + } + + /** + * Return the state of the option seen on the command line of the + * current application invocation. This function returns true, or the + * parameter to the option, if any. If the option was not given, + * this function returns null. + * + * The magic __get method works in the context of naming the option + * as a virtual member of this class. + * + * @param string $key + * @return string + */ + public function __get($key) + { + return $this->getOption($key); + } + + /** + * Test whether a given option has been seen. + * + * @param string $key + * @return boolean + */ + public function __isset($key) + { + $this->parse(); + if (isset($this->_ruleMap[$key])) { + $key = $this->_ruleMap[$key]; + return isset($this->_options[$key]); + } + return false; + } + + /** + * Set the value for a given option. + * + * @param string $key + * @param string $value + * @return void + */ + public function __set($key, $value) + { + $this->parse(); + if (isset($this->_ruleMap[$key])) { + $key = $this->_ruleMap[$key]; + $this->_options[$key] = $value; + } + } + + /** + * Return the current set of options and parameters seen as a string. + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Unset an option. + * + * @param string $key + * @return void + */ + public function __unset($key) + { + $this->parse(); + if (isset($this->_ruleMap[$key])) { + $key = $this->_ruleMap[$key]; + unset($this->_options[$key]); + } + } + + /** + * Define additional command-line arguments. + * These are appended to those defined when the constructor was called. + * + * @param array $argv + * @throws Zend_Console_Getopt_Exception When not given an array as parameter + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function addArguments($argv) + { + if(!is_array($argv)) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Parameter #1 to addArguments should be an array"); + } + $this->_argv = array_merge($this->_argv, $argv); + $this->_parsed = false; + return $this; + } + + /** + * Define full set of command-line arguments. + * These replace any currently defined. + * + * @param array $argv + * @throws Zend_Console_Getopt_Exception When not given an array as parameter + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function setArguments($argv) + { + if(!is_array($argv)) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Parameter #1 to setArguments should be an array"); + } + $this->_argv = $argv; + $this->_parsed = false; + return $this; + } + + /** + * Define multiple configuration options from an associative array. + * These are not program options, but properties to configure + * the behavior of Zend_Console_Getopt. + * + * @param array $getoptConfig + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function setOptions($getoptConfig) + { + if (isset($getoptConfig)) { + foreach ($getoptConfig as $key => $value) { + $this->setOption($key, $value); + } + } + return $this; + } + + /** + * Define one configuration option as a key/value pair. + * These are not program options, but properties to configure + * the behavior of Zend_Console_Getopt. + * + * @param string $configKey + * @param string $configValue + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function setOption($configKey, $configValue) + { + if ($configKey !== null) { + $this->_getoptConfig[$configKey] = $configValue; + } + return $this; + } + + /** + * Define additional option rules. + * These are appended to the rules defined when the constructor was called. + * + * @param array $rules + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function addRules($rules) + { + $ruleMode = $this->_getoptConfig['ruleMode']; + switch ($this->_getoptConfig['ruleMode']) { + case self::MODE_ZEND: + if (is_array($rules)) { + $this->_addRulesModeZend($rules); + break; + } + // intentional fallthrough + case self::MODE_GNU: + $this->_addRulesModeGnu($rules); + break; + default: + /** + * Call addRulesModeFoo() for ruleMode 'foo'. + * The developer should subclass Getopt and + * provide this method. + */ + $method = '_addRulesMode' . ucfirst($ruleMode); + $this->$method($rules); + } + $this->_parsed = false; + return $this; + } + + /** + * Return the current set of options and parameters seen as a string. + * + * @return string + */ + public function toString() + { + $this->parse(); + $s = array(); + foreach ($this->_options as $flag => $value) { + $s[] = $flag . '=' . ($value === true ? 'true' : $value); + } + return implode(' ', $s); + } + + /** + * Return the current set of options and parameters seen + * as an array of canonical options and parameters. + * + * Clusters have been expanded, and option aliases + * have been mapped to their primary option names. + * + * @return array + */ + public function toArray() + { + $this->parse(); + $s = array(); + foreach ($this->_options as $flag => $value) { + $s[] = $flag; + if ($value !== true) { + $s[] = $value; + } + } + return $s; + } + + /** + * Return the current set of options and parameters seen in Json format. + * + * @return string + */ + public function toJson() + { + $this->parse(); + $j = array(); + foreach ($this->_options as $flag => $value) { + $j['options'][] = array( + 'option' => array( + 'flag' => $flag, + 'parameter' => $value + ) + ); + } + + /** + * @see Zend_Json + */ + require_once 'Zend/Json.php'; + $json = Zend_Json::encode($j); + + return $json; + } + + /** + * Return the current set of options and parameters seen in XML format. + * + * @return string + */ + public function toXml() + { + $this->parse(); + $doc = new DomDocument('1.0', 'utf-8'); + $optionsNode = $doc->createElement('options'); + $doc->appendChild($optionsNode); + foreach ($this->_options as $flag => $value) { + $optionNode = $doc->createElement('option'); + $optionNode->setAttribute('flag', utf8_encode($flag)); + if ($value !== true) { + $optionNode->setAttribute('parameter', utf8_encode($value)); + } + $optionsNode->appendChild($optionNode); + } + $xml = $doc->saveXML(); + return $xml; + } + + /** + * Return a list of options that have been seen in the current argv. + * + * @return array + */ + public function getOptions() + { + $this->parse(); + return array_keys($this->_options); + } + + /** + * Return the state of the option seen on the command line of the + * current application invocation. + * + * This function returns true, or the parameter value to the option, if any. + * If the option was not given, this function returns false. + * + * @param string $flag + * @return mixed + */ + public function getOption($flag) + { + $this->parse(); + if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { + $flag = strtolower($flag); + } + if (isset($this->_ruleMap[$flag])) { + $flag = $this->_ruleMap[$flag]; + if (isset($this->_options[$flag])) { + return $this->_options[$flag]; + } + } + return null; + } + + /** + * Return the arguments from the command-line following all options found. + * + * @return array + */ + public function getRemainingArgs() + { + $this->parse(); + return $this->_remainingArgs; + } + + /** + * Return a useful option reference, formatted for display in an + * error message. + * + * Note that this usage information is provided in most Exceptions + * generated by this class. + * + * @return string + */ + public function getUsageMessage() + { + $usage = "Usage: {$this->_progname} [ options ]\n"; + $maxLen = 20; + $lines = array(); + foreach ($this->_rules as $rule) { + $flags = array(); + if (is_array($rule['alias'])) { + foreach ($rule['alias'] as $flag) { + $flags[] = (strlen($flag) == 1 ? '-' : '--') . $flag; + } + } + $linepart['name'] = implode('|', $flags); + if (isset($rule['param']) && $rule['param'] != 'none') { + $linepart['name'] .= ' '; + switch ($rule['param']) { + case 'optional': + $linepart['name'] .= "[ <{$rule['paramType']}> ]"; + break; + case 'required': + $linepart['name'] .= "<{$rule['paramType']}>"; + break; + } + } + if (strlen($linepart['name']) > $maxLen) { + $maxLen = strlen($linepart['name']); + } + $linepart['help'] = ''; + if (isset($rule['help'])) { + $linepart['help'] .= $rule['help']; + } + $lines[] = $linepart; + } + foreach ($lines as $linepart) { + $usage .= sprintf("%s %s\n", + str_pad($linepart['name'], $maxLen), + $linepart['help']); + } + return $usage; + } + + /** + * Define aliases for options. + * + * The parameter $aliasMap is an associative array + * mapping option name (short or long) to an alias. + * + * @param array $aliasMap + * @throws Zend_Console_Getopt_Exception + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function setAliases($aliasMap) + { + foreach ($aliasMap as $flag => $alias) + { + if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { + $flag = strtolower($flag); + $alias = strtolower($alias); + } + if (!isset($this->_ruleMap[$flag])) { + continue; + } + $flag = $this->_ruleMap[$flag]; + if (isset($this->_rules[$alias]) || isset($this->_ruleMap[$alias])) { + $o = (strlen($alias) == 1 ? '-' : '--') . $alias; + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"$o\" is being defined more than once."); + } + $this->_rules[$flag]['alias'][] = $alias; + $this->_ruleMap[$alias] = $flag; + } + return $this; + } + + /** + * Define help messages for options. + * + * The parameter $help_map is an associative array + * mapping option name (short or long) to the help string. + * + * @param array $helpMap + * @return Zend_Console_Getopt Provides a fluent interface + */ + public function setHelp($helpMap) + { + foreach ($helpMap as $flag => $help) + { + if (!isset($this->_ruleMap[$flag])) { + continue; + } + $flag = $this->_ruleMap[$flag]; + $this->_rules[$flag]['help'] = $help; + } + return $this; + } + + /** + * Parse command-line arguments and find both long and short + * options. + * + * Also find option parameters, and remaining arguments after + * all options have been parsed. + * + * @return Zend_Console_Getopt|null Provides a fluent interface + */ + public function parse() + { + if ($this->_parsed === true) { + return; + } + $argv = $this->_argv; + $this->_options = array(); + $this->_remainingArgs = array(); + while (count($argv) > 0) { + if ($argv[0] == '--') { + array_shift($argv); + if ($this->_getoptConfig[self::CONFIG_DASHDASH]) { + $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); + break; + } + } + if (substr($argv[0], 0, 2) == '--') { + $this->_parseLongOption($argv); + } else if (substr($argv[0], 0, 1) == '-' && ('-' != $argv[0] || count($argv) >1)) { + $this->_parseShortOptionCluster($argv); + } else if($this->_getoptConfig[self::CONFIG_PARSEALL]) { + $this->_remainingArgs[] = array_shift($argv); + } else { + /* + * We should put all other arguments in _remainingArgs and stop parsing + * since CONFIG_PARSEALL is false. + */ + $this->_remainingArgs = array_merge($this->_remainingArgs, $argv); + break; + } + } + $this->_parsed = true; + return $this; + } + + /** + * Parse command-line arguments for a single long option. + * A long option is preceded by a double '--' character. + * Long options may not be clustered. + * + * @param mixed &$argv + * @return void + */ + protected function _parseLongOption(&$argv) + { + $optionWithParam = ltrim(array_shift($argv), '-'); + $l = explode('=', $optionWithParam, 2); + $flag = array_shift($l); + $param = array_shift($l); + if (isset($param)) { + array_unshift($argv, $param); + } + $this->_parseSingleOption($flag, $argv); + } + + /** + * Parse command-line arguments for short options. + * Short options are those preceded by a single '-' character. + * Short options may be clustered. + * + * @param mixed &$argv + * @return void + */ + protected function _parseShortOptionCluster(&$argv) + { + $flagCluster = ltrim(array_shift($argv), '-'); + foreach (str_split($flagCluster) as $flag) { + $this->_parseSingleOption($flag, $argv); + } + } + + /** + * Parse command-line arguments for a single option. + * + * @param string $flag + * @param mixed $argv + * @throws Zend_Console_Getopt_Exception + * @return void + */ + protected function _parseSingleOption($flag, &$argv) + { + if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { + $flag = strtolower($flag); + } + if (!isset($this->_ruleMap[$flag])) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"$flag\" is not recognized.", + $this->getUsageMessage()); + } + $realFlag = $this->_ruleMap[$flag]; + switch ($this->_rules[$realFlag]['param']) { + case 'required': + if (count($argv) > 0) { + $param = array_shift($argv); + $this->_checkParameterType($realFlag, $param); + } else { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"$flag\" requires a parameter.", + $this->getUsageMessage()); + } + break; + case 'optional': + if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') { + $param = array_shift($argv); + $this->_checkParameterType($realFlag, $param); + } else { + $param = true; + } + break; + default: + $param = true; + } + $this->_options[$realFlag] = $param; + } + + /** + * Return true if the parameter is in a valid format for + * the option $flag. + * Throw an exception in most other cases. + * + * @param string $flag + * @param string $param + * @throws Zend_Console_Getopt_Exception + * @return bool + */ + protected function _checkParameterType($flag, $param) + { + $type = 'string'; + if (isset($this->_rules[$flag]['paramType'])) { + $type = $this->_rules[$flag]['paramType']; + } + switch ($type) { + case 'word': + if (preg_match('/\W/', $param)) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"$flag\" requires a single-word parameter, but was given \"$param\".", + $this->getUsageMessage()); + } + break; + case 'integer': + if (preg_match('/\D/', $param)) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"$flag\" requires an integer parameter, but was given \"$param\".", + $this->getUsageMessage()); + } + break; + case 'string': + default: + break; + } + return true; + } + + /** + * Define legal options using the gnu-style format. + * + * @param string $rules + * @return void + */ + protected function _addRulesModeGnu($rules) + { + $ruleArray = array(); + + /** + * Options may be single alphanumeric characters. + * Options may have a ':' which indicates a required string parameter. + * No long options or option aliases are supported in GNU style. + */ + preg_match_all('/([a-zA-Z0-9]:?)/', $rules, $ruleArray); + foreach ($ruleArray[1] as $rule) { + $r = array(); + $flag = substr($rule, 0, 1); + if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { + $flag = strtolower($flag); + } + $r['alias'][] = $flag; + if (substr($rule, 1, 1) == ':') { + $r['param'] = 'required'; + $r['paramType'] = 'string'; + } else { + $r['param'] = 'none'; + } + $this->_rules[$flag] = $r; + $this->_ruleMap[$flag] = $flag; + } + } + + /** + * Define legal options using the Zend-style format. + * + * @param array $rules + * @throws Zend_Console_Getopt_Exception + * @return void + */ + protected function _addRulesModeZend($rules) + { + foreach ($rules as $ruleCode => $helpMessage) + { + // this may have to translate the long parm type if there + // are any complaints that =string will not work (even though that use + // case is not documented) + if (in_array(substr($ruleCode, -2, 1), array('-', '='))) { + $flagList = substr($ruleCode, 0, -2); + $delimiter = substr($ruleCode, -2, 1); + $paramType = substr($ruleCode, -1); + } else { + $flagList = $ruleCode; + $delimiter = $paramType = null; + } + if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) { + $flagList = strtolower($flagList); + } + $flags = explode('|', $flagList); + $rule = array(); + $mainFlag = $flags[0]; + foreach ($flags as $flag) { + if (empty($flag)) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Blank flag not allowed in rule \"$ruleCode\"."); + } + if (strlen($flag) == 1) { + if (isset($this->_ruleMap[$flag])) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"-$flag\" is being defined more than once."); + } + $this->_ruleMap[$flag] = $mainFlag; + $rule['alias'][] = $flag; + } else { + if (isset($this->_rules[$flag]) || isset($this->_ruleMap[$flag])) { + require_once 'Zend/Console/Getopt/Exception.php'; + throw new Zend_Console_Getopt_Exception( + "Option \"--$flag\" is being defined more than once."); + } + $this->_ruleMap[$flag] = $mainFlag; + $rule['alias'][] = $flag; + } + } + if (isset($delimiter)) { + switch ($delimiter) { + case self::PARAM_REQUIRED: + $rule['param'] = 'required'; + break; + case self::PARAM_OPTIONAL: + default: + $rule['param'] = 'optional'; + } + switch (substr($paramType, 0, 1)) { + case self::TYPE_WORD: + $rule['paramType'] = 'word'; + break; + case self::TYPE_INTEGER: + $rule['paramType'] = 'integer'; + break; + case self::TYPE_STRING: + default: + $rule['paramType'] = 'string'; + } + } else { + $rule['param'] = 'none'; + } + $rule['help'] = $helpMessage; + $this->_rules[$mainFlag] = $rule; + } + } + +} diff --git a/pp3/au/lib/Getopt/Exception.php b/pp3/au/lib/Getopt/Exception.php new file mode 100755 index 0000000..cabb406 --- /dev/null +++ b/pp3/au/lib/Getopt/Exception.php @@ -0,0 +1,66 @@ +<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to lice...@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Console_Getopt + * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $ + */ + + +/** + * @see Zend_Console_Getopt_Exception + */ +require_once 'Zend/Exception.php'; + + +/** + * @category Zend + * @package Zend_Console_Getopt + * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Console_Getopt_Exception extends Zend_Exception +{ + /** + * Usage + * + * @var string + */ + protected $usage = ''; + + /** + * Constructor + * + * @param string $message + * @param string $usage + * @return void + */ + public function __construct($message, $usage = '') + { + $this->usage = $usage; + parent::__construct($message); + } + + /** + * Returns the usage + * + * @return string + */ + public function getUsageMessage() + { + return $this->usage; + } +} diff --git a/pp3/au/lib/geoip.inc b/pp3/au/lib/geoip.inc new file mode 100755 index 0000000..4e367d2 --- /dev/null +++ b/pp3/au/lib/geoip.inc @@ -0,0 +1,509 @@ +<?php + +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* geoip.inc + * + * Copyright (C) 2007 MaxMind LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +define("GEOIP_COUNTRY_BEGIN", 16776960); +define("GEOIP_STATE_BEGIN_REV0", 16700000); +define("GEOIP_STATE_BEGIN_REV1", 16000000); +define("GEOIP_STANDARD", 0); +define("GEOIP_MEMORY_CACHE", 1); +define("GEOIP_SHARED_MEMORY", 2); +define("STRUCTURE_INFO_MAX_SIZE", 20); +define("DATABASE_INFO_MAX_SIZE", 100); +define("GEOIP_COUNTRY_EDITION", 106); +define("GEOIP_PROXY_EDITION", 8); +define("GEOIP_ASNUM_EDITION", 9); +define("GEOIP_NETSPEED_EDITION", 10); +define("GEOIP_REGION_EDITION_REV0", 112); +define("GEOIP_REGION_EDITION_REV1", 3); +define("GEOIP_CITY_EDITION_REV0", 111); +define("GEOIP_CITY_EDITION_REV1", 2); +define("GEOIP_ORG_EDITION", 110); +define("GEOIP_ISP_EDITION", 4); +define("SEGMENT_RECORD_LENGTH", 3); +define("STANDARD_RECORD_LENGTH", 3); +define("ORG_RECORD_LENGTH", 4); +define("MAX_RECORD_LENGTH", 4); +define("MAX_ORG_RECORD_LENGTH", 300); +define("GEOIP_SHM_KEY", 0x4f415401); +define("US_OFFSET", 1); +define("CANADA_OFFSET", 677); +define("WORLD_OFFSET", 1353); +define("FIPS_RANGE", 360); +define("GEOIP_UNKNOWN_SPEED", 0); +define("GEOIP_DIALUP_SPEED", 1); +define("GEOIP_CABLEDSL_SPEED", 2); +define("GEOIP_CORPORATE_SPEED", 3); + +class GeoIP { + var $flags; + var $filehandle; + var $memory_buffer; + var $databaseType; + var $databaseSegments; + var $record_length; + var $shmid; + var $GEOIP_COUNTRY_CODE_TO_NUMBER = array( +"" => 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5, +"AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "AN" => 10, "AO" => 11, +"AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17, +"AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23, +"BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29, +"BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35, +"BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41, +"CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47, +"CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53, +"CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59, +"DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65, +"ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71, +"FM" => 72, "FO" => 73, "FR" => 74, "FX" => 75, "GA" => 76, "GB" => 77, +"GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83, +"GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89, +"GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95, +"HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101, +"IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107, +"IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113, +"KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119, +"KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125, +"LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131, +"LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137, +"MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143, +"MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149, +"MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155, +"NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161, +"NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167, +"PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173, +"PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179, +"PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185, +"RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191, +"SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197, +"SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203, +"SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209, +"TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215, +"TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221, +"UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227, +"VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233, +"VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239, +"ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245, +"O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250 +); + var $GEOIP_COUNTRY_CODES = array( +"", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", +"AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", +"BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", +"CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", +"CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", +"EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", +"GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", +"GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", +"IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", +"KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", +"LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", +"MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", +"NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", +"PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", +"QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", +"SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", +"TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", +"TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", +"VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", +"AX", "GG", "IM", "JE" +); + var $GEOIP_COUNTRY_CODES3 = array( +"","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG", +"ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI", +"BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC", +"COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV", +"CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH", +"ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD", +"GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM", +"GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO", +"IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA", +"PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", +"LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC", +"MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL", +"NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER", +"PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT", +"REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM", +"SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF", +"TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA", +"UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT", +"WLF","WSM","YEM","YT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1", +"ALA","GGY","IMN","JEY" + ); + var $GEOIP_COUNTRY_NAMES = array( +"", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", +"Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", +"Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", +"Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", +"Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", +"Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", +"Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", +"Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", +"Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook +Islands", "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape +Verde", "Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti", +"Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", +"Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", +"Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe +Islands", "France", "France, Metropolitan", "Gabon", "United Kingdom", +"Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", +"Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia +and the South Sandwich Islands", "Guatemala", "Guam", "Guinea-Bissau", +"Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", +"Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", +"British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", +"Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", +"Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic +People's Republic of", "Korea, Republic of", "Kuwait", "Cayman Islands", +"Kazakstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", +"Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", +"Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic +of", "Madagascar", "Marshall Islands", "Macedonia", +"Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", +"Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", +"Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia", +"Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", +"Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French +Polynesia", "Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint +Pierre and Miquelon", "Pitcairn Islands", "Puerto Rico", "Palestinian Territory", +"Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania", +"Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", +"Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia", +"Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", +"Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab +Republic", "Swaziland", "Turks and Caicos Islands", "Chad", "French Southern +Territories", "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", +"Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu", +"Taiwan", "Tanzania, United Republic of", "Ukraine", +"Uganda", "United States Minor Outlying Islands", "United States", "Uruguay", +"Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the +Grenadines", "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", +"Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", +"Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe", +"Anonymous Proxy","Satellite Provider","Other", +"Aland Islands","Guernsey","Isle of Man","Jersey" +); +} +function geoip_load_shared_mem ($file) { + + $fp = fopen($file, "rb"); + if (!$fp) { + print "error opening $file: $php_errormsg\n"; + exit; + } + $s_array = fstat($fp); + $size = $s_array['size']; + if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) { + shmop_delete ($shmid); + shmop_close ($shmid); + } + $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size); + shmop_write ($shmid, fread($fp, $size), 0); + shmop_close ($shmid); +} + +function _setup_segments($gi){ + $gi->databaseType = GEOIP_COUNTRY_EDITION; + $gi->record_length = STANDARD_RECORD_LENGTH; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $offset = @shmop_size ($gi->shmid) - 3; + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = @shmop_read ($gi->shmid, $offset, 3); + $offset += 3; + if ($delim == (chr(255).chr(255).chr(255))) { + $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1)); + $offset++; + + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)|| + ($gi->databaseType == GEOIP_CITY_EDITION_REV1) + || ($gi->databaseType == GEOIP_ORG_EDITION) + || ($gi->databaseType == GEOIP_ISP_EDITION) + || ($gi->databaseType == GEOIP_ASNUM_EDITION)){ + $gi->databaseSegments = 0; + $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if (($gi->databaseType == GEOIP_ORG_EDITION)|| + ($gi->databaseType == GEOIP_ISP_EDITION)) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + $offset -= 4; + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + } else { + $filepos = ftell($gi->filehandle); + fseek($gi->filehandle, -3, SEEK_END); + for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { + $delim = fread($gi->filehandle,3); + if ($delim == (chr(255).chr(255).chr(255))){ + $gi->databaseType = ord(fread($gi->filehandle,1)); + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; + } + else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ + $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; + } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0) || + ($gi->databaseType == GEOIP_CITY_EDITION_REV1) || + ($gi->databaseType == GEOIP_ORG_EDITION) || + ($gi->databaseType == GEOIP_ISP_EDITION) || + ($gi->databaseType == GEOIP_ASNUM_EDITION)){ + $gi->databaseSegments = 0; + $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH); + for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ + $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); + } + if ($gi->databaseType == GEOIP_ORG_EDITION) { + $gi->record_length = ORG_RECORD_LENGTH; + } + } + break; + } else { + fseek($gi->filehandle, -4, SEEK_CUR); + } + } + if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| + ($gi->databaseType == GEOIP_PROXY_EDITION)|| + ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ + $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; + } + fseek($gi->filehandle,$filepos,SEEK_SET); + } + return $gi; +} + +function geoip_open($filename, $flags) { + $gi = new GeoIP; + $gi->flags = $flags; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0); + } else { + $gi->filehandle = fopen($filename,"rb"); + if ($gi->flags & GEOIP_MEMORY_CACHE) { + $s_array = fstat($gi->filehandle); + $gi->memory_buffer = fread($gi->filehandle, $s_array[size]); + } + } + + $gi = _setup_segments($gi); + return $gi; +} + +function geoip_close($gi) { + if ($gi->flags & GEOIP_SHARED_MEMORY) { + return true; + } + + return fclose($gi->filehandle); +} + +function geoip_country_id_by_name($gi, $name) { + $addr = gethostbyname($name); + if (!$addr || $addr == $name) { + return false; + } + return geoip_country_id_by_addr($gi, $addr); +} + +function geoip_country_code_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + return false; +} + +function geoip_country_name_by_name($gi, $name) { + $country_id = geoip_country_id_by_name($gi,$name); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + return false; +} + +function geoip_country_id_by_addr($gi, $addr) { + $ipnum = ip2long($addr); + return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN; +} + +function geoip_country_code_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + return $record->country_code; + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_CODES[$country_id]; + } + } + return false; +} + +function geoip_country_name_by_addr($gi, $addr) { + if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { + $record = geoip_record_by_addr($gi,$addr); + return $record->country_name; + } else { + $country_id = geoip_country_id_by_addr($gi,$addr); + if ($country_id !== false) { + return $gi->GEOIP_COUNTRY_NAMES[$country_id]; + } + } + return false; +} + +function _geoip_seek_country($gi, $ipnum) { + $offset = 0; + for ($depth = 31; $depth >= 0; --$depth) { + if ($gi->flags & GEOIP_MEMORY_CACHE) { + $buf = substr($gi->memory_buffer, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length); + } elseif ($gi->flags & GEOIP_SHARED_MEMORY) { + $buf = @shmop_read ($gi->shmid, + 2 * $gi->record_length * $offset, + 2 * $gi->record_length ); + } else { + fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0 + or die("fseek failed"); + $buf = fread($gi->filehandle, 2 * $gi->record_length); + } + $x = array(0,0); + for ($i = 0; $i < 2; ++$i) { + for ($j = 0; $j < $gi->record_length; ++$j) { + $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8); + } + } + if ($ipnum & (1 << $depth)) { + if ($x[1] >= $gi->databaseSegments) { + return $x[1]; + } + $offset = $x[1]; + } else { + if ($x[0] >= $gi->databaseSegments) { + return $x[0]; + } + $offset = $x[0]; + } + } + trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); + return false; +} + +function _get_org($gi,$ipnum){ + $seek_org = _geoip_seek_country($gi,$ipnum); + if ($seek_org == $gi->databaseSegments) { + return NULL; + } + $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments; + if ($gi->flags & GEOIP_SHARED_MEMORY) { + $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH); + } else { + fseek($gi->filehandle, $record_pointer, SEEK_SET); + $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH); + } + $org_buf = substr($org_buf, 0, strpos($org_buf, 0)); + return $org_buf; +} + +function geoip_org_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_org($gi, $ipnum); +} + +function _get_region($gi,$ipnum){ + if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0; + if ($seek_region >= 1000){ + $country_code = "US"; + $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region]; + $region = ""; + } + return array ($country_code,$region); + } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) { + $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1; + //print $seek_region; + if ($seek_region < US_OFFSET){ + $country_code = ""; + $region = ""; + } else if ($seek_region < CANADA_OFFSET) { + $country_code = "US"; + $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65); + } else if ($seek_region < WORLD_OFFSET) { + $country_code = "CA"; + $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65); + } else { + $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE]; + $region = ""; + } + return array ($country_code,$region); + } +} + +function geoip_region_by_addr ($gi,$addr) { + if ($addr == NULL) { + return 0; + } + $ipnum = ip2long($addr); + return _get_region($gi, $ipnum); +} + +function getdnsattributes ($l,$ip){ + $r = new Net_DNS_Resolver(); + $r->nameservers = array("ws1.maxmind.com"); + $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN"); + $str = is_object($p->answer[0])?$p->answer[0]->string():''; + ereg("\"(.*)\"",$str,$regs); + $str = $regs[1]; + return $str; +} + +function getCCByIP($ip) { + + // path to file needs to be absolute, as fopen() is used to read it + $gi = geoip_open(dirname(__FILE__) . "/GeoIP.dat", GEOIP_STANDARD); + + // get the country code for $ip + $cc = geoip_country_code_by_addr($gi, $ip); + geoip_close($gi); + + return $cc; +} + +?> diff --git a/pp3/au/run-au-import.php b/pp3/au/run-au-import.php new file mode 100755 index 0000000..fe40175 --- /dev/null +++ b/pp3/au/run-au-import.php @@ -0,0 +1,48 @@ +#!/usr/bin/php +<?php +ini_set('memory_limit', '560M'); + +require_once 'config.php'; +require_once 'lib/Getopt.php'; +require_once 'lib/geoip.inc'; +require_once 'Logger.php'; +require_once 'Db.php'; +require_once 'Runner.php'; +require_once 'Importer.php'; + +// start logger, use it's static methods ::info($msg), ::error($msg) anywhere to log status +Logger::init(LOGFILE_PATH . '/au-import-info-' . date('Ymd') . '.log'); + +// parse cmdline for product which AU log we want to import: netbeans|dlc|vvm .. default to all +$opts = new Zend_Console_Getopt(array( + 'help|h' => 'Show help', + 'source|s=s' => 'Which AU log to import, possible valules: dlc, nb, vvm')); +try { + $opts->parse(); + $source = ($opts->getOption('source')) ? $opts->getOption('source') : 'all'; + $help = $opts->getOption('help'); + if ($help) { + echo $opts->getUsageMessage(); + exit(0); + } +} catch (Exception $e) { + // some illegal option specified, show help and exit + echo $opts->getUsageMessage(); + exit(1); +} + +// here it happens +try { + // invoke runner + Logger::write(Logger::INFO, 'Starting import, log specified: ' . $source); + Runner::run($source); + Logger::write(Logger::INFO, 'Import finished'); + exit(0); +} catch (Exception $e) { + // if any exception is thrown, send it in email to the system owner + mail(ADMIN_EMAIL, 'AU-IMPORT - exception occured', "Hello,\nthis is to inform you about exception during the AU-IMPORT procedure.\n\n" . date('Y-m-d H:i:s') . "\n\nException:\n" . $e->getMessage() . "\n\n" . $e->getTraceAsString()); + // also print it + echo $e->getMessage(); + exit(1); +} +?> --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists