#!/usr/bin/env python # HLstatsX Community Edition - Real-time player and clan rankings and statistics # Copyleft (L) 2008-20XX Nicholas Hastings (nshastings@gmail.com) # http://www.hlxcommunity.com # HLstatsX Community Edition is a continuation of # ELstatsNEO - Real-time player and clan rankings and statistics # Copyleft (L) 2008-20XX Malte Bayer (steam@neo-soft.org) # http://ovrsized.neo-soft.org/ # ELstatsNEO is an very improved & enhanced - so called Ultra-Humongus Edition of HLstatsX # HLstatsX - Real-time player and clan rankings and statistics for Half-Life 2 # http://www.hlstatsx.com/ # Copyright (C) 2005-2007 Tobias Oetzel (Tobi@hlstatsx.com) # HLstatsX is an enhanced version of HLstats made by Simon Garner # HLstats - Real-time player and clan rankings and statistics for Half-Life # http://sourceforge.net/projects/hlstats/ # Copyright (C) 2001 Simon Garner # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # This program 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # For support and installation notes visit http://www.hlxcommunity.com import os,sys # version 1.0 alpha contributed to hlstatsx community by *XYZ*SaYnt DBHOST="localhost" DBNAME="your_hlstats_db" DBUSER="your_sql_username" DBPASS="your_sql_password" def system(cmd): """ executes a system call and returns the text as a string. Returns only the first line of output. """ print("EXECUTING: %s"%cmd) f = os.popen(cmd) output = f.readlines() f.close() if len(output) > 0: return output[0].replace("\n","") else: return "" def fetch_geodata(): """ Obtains the geoLiteCity raw data, resulting in geoLiteCity_Location.csv and geoLiteCity_Blocks.csv """ # database is updated on 1st every month, so download the file from the 1st of current month DAT = system("date +%Y%m01") FIL = "GeoLiteCity_%s"%DAT FILE = FIL + ".zip" system("rm *.csv > /dev/null") if not os.path.exists(FILE): system("wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity_CSV/" + FILE) system("unzip -o " + FILE) system("mv %s/GeoLiteCity-Blocks.csv geoLiteCity_Blocks.csv"%FIL) system("mv %s/GeoLiteCity-Location.csv geoLiteCity_Location.csv.temp"%FIL) system("rmdir " + FIL) system("iconv -f ISO-8859-1 -t UTF-8 geoLiteCity_Location.csv.temp > geoLiteCity_Location.csv") return def dump_sql(fname): """ Dump the new sql data into our database """ system("mysql -u %s -p%s -h %s %s < %s"%(DBUSER,DBPASS,DBHOST,DBNAME,fname)) def write_sql(fname): """ Write a file of sql commands so that our data can be imported into our database. """ try: fout = open(fname,"w") except: print("ERROR: unable to open "+fname) return 0 fout.write(""" DROP TABLE IF EXISTS `geoLiteCity_Blocks`; DROP TABLE IF EXISTS `geolitecity_blocks`; DROP TABLE IF EXISTS `geolitecity_location`; DROP TABLE IF EXISTS `geoLiteCity_Location`; CREATE TABLE `geoLiteCity_Blocks` (`startIpNum` bigint(11) unsigned NOT NULL default '0', `endIpNum` bigint(11) unsigned NOT NULL default '0', `locId` bigint(11) unsigned NOT NULL default '0' ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `geoLiteCity_Location` ( `locId` bigint(11) unsigned NOT NULL default '0', `country` varchar(2) NOT NULL, `region` varchar(50) default NULL, `city` varchar(50) default NULL, `postalCode` varchar(10) default NULL, `latitude` decimal(14,4) default NULL, `longitude` decimal(14,4) default NULL, PRIMARY KEY (`locId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; """) # read in the raw data f = open("geoLiteCity_Blocks.csv") raw = f.readlines() f.close() del raw[0:2] # chunk up the raw data chunksize = 1000 gblocks = [] chunks = len(raw)/chunksize + 1 for i in xrange(0,chunks): gblocks.append(raw[i*chunksize:(i+1)*chunksize]) print("SQL: %d data items, %d chunks"%(len(raw),chunks)) del raw for chunk in gblocks: if chunk: s = "insert into `geoLiteCity_Blocks`(`startIpNum`,`endIpNum`,`locId`) values" for l in chunk: vals = l.replace('"',"").replace('\n',"").split(',') s += "(%s,%s,%s),"%(vals[0],vals[1],vals[2]) s = s[0:-1] # chop the last comma fout.write(s + ";\n"); del gblocks f = open("geoLiteCity_Location.csv") raw = f.readlines() f.close() del raw[0:2] # chunk up the raw data gblocks = [] chunks = len(raw)/chunksize + 1 for i in xrange(0,chunks): gblocks.append(raw[i*chunksize:(i+1)*chunksize]) print("SQL: %d data items, %d chunks"%(len(raw),chunks)) del raw for chunk in gblocks: if chunk: s = "insert into `geoLiteCity_Location`(`locId`,`country`,`region`,`city`,`postalCode`,`latitude`,`longitude`) values" for l in chunk: vals = l.replace('"',"").replace('\n',"").split(',') for i,v in enumerate(vals): vals[i] = v.replace("'","\\'") s += "(%s,'%s','%s','%s','%s','%s','%s'),"%(vals[0],vals[1],vals[2],vals[3],vals[4],vals[5],vals[6]) s = s[0:-1] # chop the last comma fout.write(s + ";\n"); del gblocks return 1 def main(): sqlname = "geodata.sql" print("DOWNLOADING GEO DATA....") fetch_geodata() print("WRITING DATABASE FILE....") if write_sql(sqlname): print("IMPORTING DATABASE FILE....") dump_sql(sqlname) else: print("Fatal error; unable to finish.") # clean up. system("rm "+sqlname) print("DONE.") main()