sxgeo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/sxgeo.rb +279 -0
- data/lib/sxgeo/SxGeoCity.dat +0 -0
- data/lib/sxgeo/version.rb +3 -0
- data/sxgeo.gemspec +18 -0
- metadata +53 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Leonid
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Sxgeo
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'sxgeo'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install sxgeo
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/sxgeo.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
require "sxgeo/version"
|
2
|
+
|
3
|
+
class SxGeo
|
4
|
+
|
5
|
+
SXGEO_FILE = 0
|
6
|
+
SXGEO_MEMORY = 1
|
7
|
+
SXGEO_BATCH = 2
|
8
|
+
|
9
|
+
def initialize (db_file = File.dirname(__FILE__) + "/sxgeo/SxGeoCity.dat", type = SXGEO_FILE)
|
10
|
+
@cc2iso = [
|
11
|
+
'', 'AP', 'EU', 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ',
|
12
|
+
'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH',
|
13
|
+
'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA',
|
14
|
+
'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU',
|
15
|
+
'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG',
|
16
|
+
'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'FX', 'GA', 'GB',
|
17
|
+
'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT',
|
18
|
+
'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN',
|
19
|
+
'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM',
|
20
|
+
'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS',
|
21
|
+
'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN',
|
22
|
+
'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA',
|
23
|
+
'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA',
|
24
|
+
'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY',
|
25
|
+
'QA', 'RE', 'RO', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI',
|
26
|
+
'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD',
|
27
|
+
'TF', 'TG', 'TH', 'TJ', 'TK', 'TM', 'TN', 'TO', 'TL', 'TR', 'TT', 'TV', 'TW',
|
28
|
+
'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN',
|
29
|
+
'VU', 'WF', 'WS', 'YE', 'YT', 'RS', 'ZA', 'ZM', 'ME', 'ZW', 'A1', 'A2', 'O1',
|
30
|
+
'AX', 'GG', 'IM', 'JE', 'BL', 'MF'
|
31
|
+
]
|
32
|
+
|
33
|
+
@batch_mode = false
|
34
|
+
@memory_mode = false
|
35
|
+
@debug_mode = false
|
36
|
+
|
37
|
+
@fh = File.open(db_file, 'rb')
|
38
|
+
# Сначала убеждаемся, что есть файл базы данных
|
39
|
+
header = @fh.read 32
|
40
|
+
raise "Can't open #{db_file}" if header[0, 3] != 'SxG'
|
41
|
+
# 'Cver/Ntime/Ctype/Ccharset/Cb_idx_len/nm_idx_len/nrange/Ndb_items/Cid_len/nmax_region/nmax_city/Nregion_size/Ncity_size'
|
42
|
+
@ver, @time, @type, @charset, @b_idx_len, @m_idx_len, @range, @db_items, @id_len,
|
43
|
+
@max_region, @max_city, @region_size, @city_size = header[3, 32].unpack('CNCCCnnNCnnNN')
|
44
|
+
raise "Wrong file format #{db_file}" if @b_idx_len * @m_idx_len * @range * @db_items * @time * @id_len == 0
|
45
|
+
@b_idx_str = @fh.read @b_idx_len * 4
|
46
|
+
@m_idx_str = @fh.read @m_idx_len * 4
|
47
|
+
@block_len = 3 + @id_len;
|
48
|
+
@batch_mode = type & SXGEO_BATCH
|
49
|
+
@memory_mode = type & SXGEO_MEMORY
|
50
|
+
@db_begin = @fh.tell
|
51
|
+
if (@batch_mode)
|
52
|
+
@b_idx_arr = @b_idx_str.unpack("N*")
|
53
|
+
@m_idx_arr = @m_idx_str.scan(/.{1,4}/)
|
54
|
+
end
|
55
|
+
if (@memory_mode)
|
56
|
+
@db = @fh.read @db_items * @block_len
|
57
|
+
@regions_db = @fh.read @region_size
|
58
|
+
@cities_db = @fh.read @city_size
|
59
|
+
end
|
60
|
+
@regions_begin = @db_begin + @db_items * @block_len;
|
61
|
+
@cities_begin = @regions_begin + @region_size
|
62
|
+
end
|
63
|
+
|
64
|
+
def search_idx(ipn, min, max)
|
65
|
+
puts "search_idx ===> #{ipn}, #{min}, #{max}, batch_mode: #{@batch_mode}" if @debug_mode
|
66
|
+
if @batch_mode != 0
|
67
|
+
while (max - min) > 8
|
68
|
+
offset = (min + max) >> 1
|
69
|
+
if ipn > @m_idx_arr[offset]
|
70
|
+
min = offset
|
71
|
+
else
|
72
|
+
max = offset
|
73
|
+
end
|
74
|
+
end
|
75
|
+
while ipn > @m_idx_arr[min] && min < max
|
76
|
+
min+=1
|
77
|
+
end
|
78
|
+
else
|
79
|
+
while (max - min) > 8
|
80
|
+
offset = (min + max) >> 1
|
81
|
+
if ipn > @m_idx_str[offset*4, offset*4 + 4]
|
82
|
+
min = offset
|
83
|
+
else
|
84
|
+
max = offset
|
85
|
+
end
|
86
|
+
end
|
87
|
+
puts "max: #{max} min: #{min}" if @debug_mode
|
88
|
+
while (ipn > @m_idx_str[min*4, min*4+4]) && (min < max)
|
89
|
+
min+=1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return min
|
93
|
+
end
|
94
|
+
|
95
|
+
def search_db(str, ipn, min, max)
|
96
|
+
if (max - min) > 0
|
97
|
+
ipn = ipn[1, ipn.length]
|
98
|
+
while (max - min) > 8
|
99
|
+
offset = (min + max) >> 1;
|
100
|
+
if ipn > str[offset * @block_len, 3]
|
101
|
+
min = offset
|
102
|
+
else
|
103
|
+
max = offset
|
104
|
+
end
|
105
|
+
end
|
106
|
+
while (ipn >= str[min * @block_len, 3]) && (min < max)
|
107
|
+
min+=1
|
108
|
+
end
|
109
|
+
else
|
110
|
+
return str[min * @block_len + 3 , 3].unpack('H*').first.hex
|
111
|
+
end
|
112
|
+
return str[min * @block_len - @id_len, @id_len].unpack('H*').first.hex
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_num(ip)
|
116
|
+
ip1n = ip.split('.').first.to_i #(int)ip; // Первый байт
|
117
|
+
# binding.pry
|
118
|
+
ipn = ip2long(ip)
|
119
|
+
puts "ipn: #{ipn}" if @debug_mode
|
120
|
+
# TODO
|
121
|
+
# if ip1n == 0 || ip1n == 10 || ip1n == 127 || ip1n >= @b_idx_len || false === (ipn = ip2long(ip)) # TODO
|
122
|
+
# return false
|
123
|
+
# end
|
124
|
+
# binding.pry
|
125
|
+
ipn = [ipn].pack 'N'
|
126
|
+
@ip1c = ip1n.chr
|
127
|
+
# Находим блок данных индексе первых байт
|
128
|
+
blocks = {}
|
129
|
+
if @batch_mode
|
130
|
+
blocks = {'min' => @b_idx_arr[ip1n.to_i-1], 'max' => @b_idx_arr[ip1n.to_i]}
|
131
|
+
else
|
132
|
+
blocks['min'], blocks['max'] = @b_idx_str[(ip1n - 1) * 4, (ip1n - 1) * 4+8].unpack 'NN'
|
133
|
+
end
|
134
|
+
puts blocks if @debug_mode
|
135
|
+
# Ищем блок в основном индексе
|
136
|
+
part = search_idx(ipn, (blocks['min'] / @range).floor, (blocks['max'] / @range).floor-1)
|
137
|
+
puts "PART #{part}" if @debug_mode
|
138
|
+
# Нашли номер блока в котором нужно искать IP, теперь находим нужный блок в БД
|
139
|
+
min = part > 0 ? part * @range : 0
|
140
|
+
max = part > @m_idx_len ? @db_items : (part+1) * @range
|
141
|
+
# Нужно проверить чтобы блок не выходил за пределы блока первого байта
|
142
|
+
min = blocks['min'] if min < blocks['min']
|
143
|
+
max = blocks['max'] if max > blocks['max']
|
144
|
+
len = max - min
|
145
|
+
# Находим нужный диапазон в БД
|
146
|
+
if @memory_mode
|
147
|
+
# binding.pry
|
148
|
+
puts "#{ipn}, #{min}, #{max}" if @debug_mode
|
149
|
+
return search_db(@db, ipn, min, max)
|
150
|
+
else
|
151
|
+
@fh.pos = @db_begin + min * @block_len
|
152
|
+
return search_db(@fh.read(len * @block_len), ipn, 0, len-1)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def ip2long(ip)
|
157
|
+
long = 0
|
158
|
+
ip.split('.').each_with_index do |b, i|
|
159
|
+
long += b.to_i << ( 8*(3-i) )
|
160
|
+
end
|
161
|
+
long
|
162
|
+
end
|
163
|
+
|
164
|
+
# def long2ip(long)
|
165
|
+
# ip = []
|
166
|
+
# 4.times do |i|
|
167
|
+
# ip.push(long.to_i & 255)
|
168
|
+
# long = long.to_i >> 8
|
169
|
+
# end
|
170
|
+
# ip.join(".")
|
171
|
+
# end
|
172
|
+
|
173
|
+
def parseCity(seek)
|
174
|
+
if @memory_mode
|
175
|
+
raw = @cities_db[seek, @max_city]
|
176
|
+
else
|
177
|
+
@fh.pos = @cities_begin + seek
|
178
|
+
raw = @fh.read @max_city
|
179
|
+
end
|
180
|
+
@city = {}
|
181
|
+
@city['regid'], @city['cc'],
|
182
|
+
@city['2fips'], @city['lat'], @city['lon'] = raw.unpack 'NCaNN'
|
183
|
+
@city['country'] = @cc2iso[@city['cc']];
|
184
|
+
@city['lat'] /= 1000000;
|
185
|
+
@city['lon'] /= 1000000;
|
186
|
+
@city['city'] = raw[15,raw.length].split("\0").first
|
187
|
+
return @city;
|
188
|
+
end
|
189
|
+
|
190
|
+
def parseRegion(region_seek)
|
191
|
+
tz = [ '', 'Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 'Africa/Bamako', 'Africa/Banjul',
|
192
|
+
'Africa/Blantyre', 'Africa/Brazzaville', 'Africa/Bujumbura', 'Africa/Cairo', 'Africa/Casablanca', 'Africa/Ceuta',
|
193
|
+
'Africa/Conakry', 'Africa/Dakar', 'Africa/Dar_es_Salaam', 'Africa/Douala', 'Africa/Freetown', 'Africa/Gaborone',
|
194
|
+
'Africa/Harare', 'Africa/Johannesburg', 'Africa/Kampala', 'Africa/Khartoum', 'Africa/Kigali', 'Africa/Kinshasa',
|
195
|
+
'Africa/Lagos', 'Africa/Libreville', 'Africa/Luanda', 'Africa/Lubumbashi', 'Africa/Lusaka', 'Africa/Malabo',
|
196
|
+
'Africa/Maputo', 'Africa/Maseru', 'Africa/Mbabane', 'Africa/Mogadishu', 'Africa/Monrovia', 'Africa/Nairobi',
|
197
|
+
'Africa/Ndjamena', 'Africa/Niamey', 'Africa/Nouakchott', 'Africa/Ouagadougou', 'Africa/Porto-Novo', 'Africa/Tripoli',
|
198
|
+
'Africa/Tunis', 'Africa/Windhoek', 'America/Anchorage', 'America/Anguilla', 'America/Antigua', 'America/Araguaina',
|
199
|
+
'America/Argentina/Buenos_Aires', 'America/Argentina/Catamarca', 'America/Argentina/Cordoba', 'America/Argentina/Jujuy',
|
200
|
+
'America/Argentina/La_Rioja', 'America/Argentina/Mendoza', 'America/Argentina/Rio_Gallegos', 'America/Argentina/Salta',
|
201
|
+
'America/Argentina/San_Juan', 'America/Argentina/San_Luis', 'America/Argentina/Tucuman', 'America/Argentina/Ushuaia',
|
202
|
+
'America/Asuncion', 'America/Bahia', 'America/Bahia_Banderas', 'America/Barbados', 'America/Belem', 'America/Belize',
|
203
|
+
'America/Boa_Vista', 'America/Bogota', 'America/Campo_Grande', 'America/Cancun', 'America/Caracas', 'America/Chicago',
|
204
|
+
'America/Chihuahua', 'America/Costa_Rica', 'America/Cuiaba', 'America/Denver', 'America/Dominica', 'America/Edmonton',
|
205
|
+
'America/El_Salvador', 'America/Fortaleza', 'America/Godthab', 'America/Grenada', 'America/Guatemala', 'America/Guayaquil',
|
206
|
+
'America/Guyana', 'America/Halifax', 'America/Havana', 'America/Hermosillo', 'America/Indianapolis', 'America/Iqaluit',
|
207
|
+
'America/Jamaica', 'America/La_Paz', 'America/Lima', 'America/Los_Angeles', 'America/Maceio', 'America/Managua',
|
208
|
+
'America/Manaus', 'America/Matamoros', 'America/Mazatlan', 'America/Merida', 'America/Mexico_City', 'America/Moncton',
|
209
|
+
'America/Monterrey', 'America/Montevideo', 'America/Montreal', 'America/Nassau', 'America/New_York', 'America/Ojinaga',
|
210
|
+
'America/Panama', 'America/Paramaribo', 'America/Phoenix', 'America/Port_of_Spain', 'America/Port-au-Prince',
|
211
|
+
'America/Porto_Velho', 'America/Recife', 'America/Regina', 'America/Rio_Branco', 'America/Santo_Domingo',
|
212
|
+
'America/Sao_Paulo', 'America/St_Johns', 'America/St_Kitts', 'America/St_Lucia', 'America/St_Vincent',
|
213
|
+
'America/Tegucigalpa', 'America/Thule', 'America/Tijuana', 'America/Vancouver', 'America/Whitehorse', 'America/Winnipeg',
|
214
|
+
'America/Yellowknife', 'Asia/Aden', 'Asia/Almaty', 'Asia/Amman', 'Asia/Anadyr', 'Asia/Aqtau', 'Asia/Aqtobe', 'Asia/Baghdad',
|
215
|
+
'Asia/Bahrain', 'Asia/Baku', 'Asia/Bangkok', 'Asia/Beirut', 'Asia/Bishkek', 'Asia/Choibalsan', 'Asia/Chongqing',
|
216
|
+
'Asia/Colombo', 'Asia/Damascus', 'Asia/Dhaka', 'Asia/Dubai', 'Asia/Dushanbe', 'Asia/Harbin', 'Asia/Ho_Chi_Minh',
|
217
|
+
'Asia/Hong_Kong', 'Asia/Hovd', 'Asia/Irkutsk', 'Asia/Jakarta', 'Asia/Jayapura', 'Asia/Jerusalem', 'Asia/Kabul',
|
218
|
+
'Asia/Kamchatka', 'Asia/Karachi', 'Asia/Kashgar', 'Asia/Kolkata', 'Asia/Krasnoyarsk', 'Asia/Kuala_Lumpur', 'Asia/Kuching',
|
219
|
+
'Asia/Kuwait', 'Asia/Macau', 'Asia/Magadan', 'Asia/Makassar', 'Asia/Manila', 'Asia/Muscat', 'Asia/Nicosia', 'Asia/Novokuznetsk',
|
220
|
+
'Asia/Novosibirsk', 'Asia/Omsk', 'Asia/Oral', 'Asia/Phnom_Penh', 'Asia/Pontianak', 'Asia/Qatar', 'Asia/Qyzylorda', 'Asia/Riyadh',
|
221
|
+
'Asia/Sakhalin', 'Asia/Seoul', 'Asia/Shanghai', 'Asia/Singapore', 'Asia/Taipei', 'Asia/Tashkent', 'Asia/Tbilisi', 'Asia/Tehran',
|
222
|
+
'Asia/Thimphu', 'Asia/Tokyo', 'Asia/Ulaanbaatar', 'Asia/Urumqi', 'Asia/Vientiane', 'Asia/Vladivostok', 'Asia/Yakutsk',
|
223
|
+
'Asia/Yekaterinburg', 'Asia/Yerevan', 'Atlantic/Azores', 'Atlantic/Bermuda', 'Atlantic/Canary', 'Atlantic/Cape_Verde',
|
224
|
+
'Atlantic/Madeira', 'Atlantic/Reykjavik', 'Australia/Adelaide', 'Australia/Brisbane', 'Australia/Darwin', 'Australia/Hobart',
|
225
|
+
'Australia/Melbourne', 'Australia/Perth', 'Australia/Sydney', 'Chile/Santiago', 'Europe/Amsterdam', 'Europe/Andorra',
|
226
|
+
'Europe/Athens', 'Europe/Belgrade', 'Europe/Berlin', 'Europe/Bratislava', 'Europe/Brussels', 'Europe/Bucharest', 'Europe/Budapest',
|
227
|
+
'Europe/Chisinau', 'Europe/Copenhagen', 'Europe/Dublin', 'Europe/Gibraltar', 'Europe/Helsinki', 'Europe/Istanbul',
|
228
|
+
'Europe/Kaliningrad', 'Europe/Kiev', 'Europe/Lisbon', 'Europe/Ljubljana', 'Europe/London', 'Europe/Luxembourg', 'Europe/Madrid',
|
229
|
+
'Europe/Malta', 'Europe/Mariehamn', 'Europe/Minsk', 'Europe/Monaco', 'Europe/Moscow', 'Europe/Oslo', 'Europe/Paris',
|
230
|
+
'Europe/Prague', 'Europe/Riga', 'Europe/Rome', 'Europe/Samara', 'Europe/San_Marino', 'Europe/Sarajevo', 'Europe/Simferopol',
|
231
|
+
'Europe/Skopje', 'Europe/Sofia', 'Europe/Stockholm', 'Europe/Tallinn', 'Europe/Tirane', 'Europe/Uzhgorod', 'Europe/Vaduz',
|
232
|
+
'Europe/Vatican', 'Europe/Vienna', 'Europe/Vilnius', 'Europe/Volgograd', 'Europe/Warsaw', 'Europe/Yekaterinburg', 'Europe/Zagreb',
|
233
|
+
'Europe/Zaporozhye', 'Europe/Zurich', 'Indian/Antananarivo', 'Indian/Comoro', 'Indian/Mahe', 'Indian/Maldives', 'Indian/Mauritius',
|
234
|
+
'Pacific/Auckland', 'Pacific/Chatham', 'Pacific/Efate', 'Pacific/Fiji', 'Pacific/Galapagos', 'Pacific/Guadalcanal', 'Pacific/Honolulu',
|
235
|
+
'Pacific/Port_Moresby' ]
|
236
|
+
if region_seek > 0
|
237
|
+
if @memory_mode
|
238
|
+
region = @regions_db[region_seek, @max_region].split "\0"
|
239
|
+
else
|
240
|
+
@fh.pos = @info['regions_begin'] + region_seek
|
241
|
+
region = @fh.read(@max_region).split "\0"
|
242
|
+
end
|
243
|
+
@city['region_name'] = region[0]
|
244
|
+
@city['timezone'] = tz[region[1]]
|
245
|
+
else
|
246
|
+
@city['region_name'] = ''
|
247
|
+
@city['timezone'] = ''
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def get(ip)
|
252
|
+
@max_city ? getCity(ip) : getCountry(ip)
|
253
|
+
end
|
254
|
+
|
255
|
+
def getCountry(ip)
|
256
|
+
@cc2iso[get_num(ip)]
|
257
|
+
end
|
258
|
+
|
259
|
+
def getCountryId(ip)
|
260
|
+
get_num(ip)
|
261
|
+
end
|
262
|
+
|
263
|
+
def getCity(ip)
|
264
|
+
seek = get_num(ip)
|
265
|
+
seek > 0 ? parseCity(seek) : false
|
266
|
+
end
|
267
|
+
|
268
|
+
def getCityFull(ip)
|
269
|
+
seek = get_num(ip)
|
270
|
+
if seek > 0
|
271
|
+
parseCity(seek)
|
272
|
+
parseRegion(@city['regid'])
|
273
|
+
@city
|
274
|
+
else
|
275
|
+
false
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
Binary file
|
data/sxgeo.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sxgeo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "sxgeo"
|
8
|
+
gem.version = Sxgeo::VERSION
|
9
|
+
gem.authors = ["nleo"]
|
10
|
+
gem.description = %q{Sypex Geo port}
|
11
|
+
gem.summary = gem.description
|
12
|
+
gem.homepage = "https://github.com/nleo/sxgeo"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/)
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sxgeo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- nleo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Sypex Geo port
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- .gitignore
|
21
|
+
- Gemfile
|
22
|
+
- LICENSE.txt
|
23
|
+
- README.md
|
24
|
+
- Rakefile
|
25
|
+
- lib/sxgeo.rb
|
26
|
+
- lib/sxgeo/SxGeoCity.dat
|
27
|
+
- lib/sxgeo/version.rb
|
28
|
+
- sxgeo.gemspec
|
29
|
+
homepage: https://github.com/nleo/sxgeo
|
30
|
+
licenses: []
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.24
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: Sypex Geo port
|
53
|
+
test_files: []
|