Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/kinix/luajit/bin/luajit
- --[[
- 06 FEB 2018: karthik@houseofkodai
- ]]--
- local load_geolite2_city_locations_csv = function(fname, cc)
- --geoname_id,locale_code,continent_code,continent_name,country_iso_code,country_name,subdivision_1_iso_code,subdivision_1_name,subdivision_2_iso_code,subdivision_2_name,city_name,metro_code,time_zone
- --1252653,en,AS,Asia,IN,India,NL,Nagaland,,,Zunheboto,,Asia/Kolkata
- --need 1,7,8,11
- local stime = os.time()
- --print('START '..stime)
- local t = {}
- local n = 0
- for ln in io.lines(fname) do
- ln = ln..',' --append , so gmatch regex works
- local regex = '([^,]*),'
- local i = 0
- local id, scode, sname, city
- for w in ln:gmatch(regex) do
- i = i + 1
- if (1 == i) then
- id = w
- elseif ((5 == i) and (w ~= cc)) then
- break
- elseif (7 == i) then
- scode = w
- elseif (8 == i) then
- sname = w
- elseif (11 == i) then
- city = w
- end
- end
- if city then
- n = n + 1
- regex = '"?([^"]*)"?'
- t[id] = {scode, sname:match(regex), city:match(regex)}
- end
- end
- --print('END', (os.time()-stime), n)
- return t
- end
- local load_geolite2_city_blocks_ipv4_csv = function(fname, idtbl)
- --network,geoname_id,registered_country_geoname_id,represented_country_geoname_id,is_anonymous_proxy,is_satellite_provider,postal_code,latitude,longitude,accuracy_radius
- local stime = os.time()
- --print('START '..stime)
- local n = 0
- local t = {}
- for ln in io.lines(fname) do
- n = n + 1
- local id = ln:match('^[%d.]+/%d+,(%d+),.*$')
- local r = idtbl[id]
- if r and (r[1]:len() > 0)then
- local o1,o2,o3,o4,range,id,f1,f2,f3,f4,f5,lat,lng,acc = ln:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)/(%d+),(%d+),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),(%d+%.%d+),(%d+%.%d+),(%d+)$')
- local ipstart = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
- local ipend = ipstart + 2^(32-tonumber(range))
- --t[#t+1] = {tonumber(ipstart),tonumber(ipend),'"'..r[1]..'/'..r[3]..'"',lat,lng,acc}
- t[#t+1] = {tonumber(ipstart),tonumber(ipend),id,lat,lng,acc}
- end
- end
- --print('END', (os.time()-stime), n, #t)
- return t
- end
- local _load = function(locfname, ipv4fname, cc)
- --pndng deal with null-cc to load everything
- local citytbl = load_geolite2_city_locations_csv(locfname, cc)
- local iptbl = load_geolite2_city_blocks_ipv4_csv(ipv4fname, citytbl)
- return citytbl, iptbl
- end
- local _find = function(s, citytbl, iptbl)
- local o1,o2,o3,o4 = s:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$')
- if not o4 then return {} end
- local ip = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
- local iptbl = iptbl or {}
- local citytbl = citytbl or {}
- for _,r in ipairs(iptbl) do
- if ip >= r[1] and ip < r[2] then
- local v = citytbl[r[3]]
- if v then r[3] = v[1]..':'..v[3] end
- return r
- end
- end
- return {}
- end
- local _save = function(fname, citytbl, iptbl)
- local fh,err = io.open(fname, 'w')
- if not fh then
- return false,err
- end
- local t = {}
- for _,r in ipairs(iptbl) do
- if (r[3]:len() > 0) then
- t[#t+1] = '{'..table.concat(r, ',')..'}'
- end
- end
- local iptbl = table.concat(t, ',\n')
- t = {}
- for k,v in pairs(citytbl) do
- t[#t+1] = '['..k..']="'..v[1]..':'..v[3]..'"'
- end
- local citytbl = table.concat(t, ',\n')
- local flines = [=[
- return function(s)
- local o1,o2,o3,o4 = s:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$')
- if not o4 then return end
- local ip = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
- local citytbl = {
- ]=]..citytbl..[=[
- }
- local iptbl = {
- ]=]..iptbl..[=[
- }
- for _,r in ipairs(iptbl) do
- if ip >= r[1] and ip < r[2] then
- r[3] = citytbl[r[3]] or 'UNK'
- return r
- end
- end
- end
- ]=]
- fh:write(flines)
- fh:close()
- return true
- end
- local main = function()
- local locfname = 'GeoLite2-City-Locations-en.csv'
- local ipv4fname = 'GeoLite2-City-Blocks-IPv4.csv'
- if (#arg < 1) then
- print('usage: geolite2.lua <country-code> <ip-to-lookup> ['..locfname..'] ['..ipv4fname..']')
- os.exit(1)
- end
- local cc = arg[1]
- local ip = arg[2]
- if arg[3] then locfname = arg[3] end
- if arg[4] then ipv4fname = arg[4] end
- local citytbl, iptbl = _load(locfname, ipv4fname, cc)
- _save(cc..'.lua', citytbl, iptbl)
- if ip then
- local r = _find(ip, citytbl, iptbl)
- if r then print(table.concat(r,'/')) end
- end
- end
- if arg ~= nil then
- main()
- end
Add Comment
Please, Sign In to add comment