ip_library 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/doc/ip_libraries.txt +5 -0
- data/ip_library.gemspec +64 -0
- data/lib/ip_library.rb +3 -0
- data/lib/ip_library/base.rb +90 -0
- data/lib/ip_library/data.rb +162 -0
- data/lib/ip_library/integer.rb +6 -0
- data/lib/ip_library/ip2integer.rb +25 -0
- data/lib/ip_library/string.rb +6 -0
- data/lib/ip_library/version.rb +3 -0
- metadata +135 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 tumayun
|
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
|
+
# IPLibrary
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'ip_library'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install ip_library
|
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 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/ip_library.gemspec
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/ip_library/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["tumayun"]
|
6
|
+
gem.email = ["tumayun.2010@gmail.com"]
|
7
|
+
gem.description = <<-DESCRIPT
|
8
|
+
IPLibrary
|
9
|
+
=========
|
10
|
+
|
11
|
+
顾名思义,这是一个ip库
|
12
|
+
|
13
|
+
Example
|
14
|
+
=======
|
15
|
+
|
16
|
+
本gem中已经带有ip库,默认是gem目录下doc/ip_libraries.txt
|
17
|
+
默认ip库的格式以IPLibrary::Configuration.separator分组
|
18
|
+
各组第一行为ip头(192.168.1.1的ip头为192),其他行各列以英文逗号隔开
|
19
|
+
各列分别是:起始ip, 结束ip, 省份, 城市, 县区, 行政划分最小字段的拼音(如果有县区则为县区的拼音)
|
20
|
+
|
21
|
+
当然,您也可以有自己的ip库
|
22
|
+
设置ip库的path: IPLibrary::Configuration.file_path = '/home/doc/ip_libraries.txt'
|
23
|
+
而且,您也可以设置ip库中的列的含义,start_ip、end_ip两列必须有,且必须依次为1、2列
|
24
|
+
设置其他列:IPLibrary::Configuration.optional_columns = [:province, :city, :district, :pinyin]
|
25
|
+
除了1、2列,其他列一次为province、city、district、pinyin
|
26
|
+
然后会动态生成方法:
|
27
|
+
IPLibrary::Base#ip2province
|
28
|
+
IPLibrary::Base#ip2city
|
29
|
+
IPLibrary::Base#ip2district
|
30
|
+
IPLibrary::Base#ip2pinyin
|
31
|
+
|
32
|
+
=============================================
|
33
|
+
|
34
|
+
IPLibrary::Base 的方法有:
|
35
|
+
|
36
|
+
IPLibrary::Base.ip2province('123.132.254.134')
|
37
|
+
IPLibrary::Base.ip2province(2072313478)
|
38
|
+
#=> "山东"
|
39
|
+
|
40
|
+
IPLibrary::Base.ip2city('123.132.254.134')
|
41
|
+
IPLibrary::Base.ip2city(2072313478)
|
42
|
+
#=> "临沂"
|
43
|
+
|
44
|
+
IPLibrary::Base.ip2district('123.132.254.134')
|
45
|
+
IPLibrary::Base.ip2district(2072313478)
|
46
|
+
# => ""
|
47
|
+
|
48
|
+
IPLibrary::Base.ip2pinyin('123.132.254.134')
|
49
|
+
IPLibrary::Base.ip2pinyin(2072313478)
|
50
|
+
#=> "linyi"
|
51
|
+
DESCRIPT
|
52
|
+
gem.summary = %q{IPLibrary是一个ip库的gem,它能通过类似ip2city等方法得到ip所在城市}
|
53
|
+
gem.homepage = 'https://github.com/tumayun/ip_library'
|
54
|
+
|
55
|
+
#gem.files = `git ls-files`.split($\)
|
56
|
+
gem.files = %w(Gemfile ip_library.gemspec LICENSE Rakefile README.md)
|
57
|
+
gem.files += Dir.glob("lib/**/*")
|
58
|
+
gem.files += Dir.glob("doc/**/*")
|
59
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
60
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
61
|
+
gem.name = "ip_library"
|
62
|
+
gem.require_paths = ["lib"]
|
63
|
+
gem.version = IPLibrary::VERSION
|
64
|
+
end
|
data/lib/ip_library.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
module IPLibrary
|
3
|
+
|
4
|
+
class Configuration
|
5
|
+
cattr_accessor :file_path, :optional_columns, :separator, :except_regexp, :instance_writer => false
|
6
|
+
cattr_reader :non_optional_columns, :columns
|
7
|
+
|
8
|
+
@@file_path = File.join(File.dirname(__FILE__), '..', '..', 'doc', 'ip_libraries.txt') #"#{File.dirname(__FILE__)}/../../doc/ip_libraries.txt"
|
9
|
+
@@optional_columns = [:province, :city, :district]
|
10
|
+
@@non_optional_columns = [:start_ip, :end_ip]
|
11
|
+
@@columns = @@non_optional_columns + @@optional_columns
|
12
|
+
@@except_regexp = /[a-zA-Z0-9]?(全国|中国|全省各市|\(.*\))?/
|
13
|
+
@@separator = "========================\n"
|
14
|
+
|
15
|
+
def self.optional_columns=(other)
|
16
|
+
Base.undef_class_methods(@@optional_columns)
|
17
|
+
@@optional_columns = other
|
18
|
+
@@columns = @@non_optional_columns + @@optional_columns
|
19
|
+
Base.defined_class_methods
|
20
|
+
@@optional_columns
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Base
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def ip_cities(force_reload = false)
|
28
|
+
return @@ip_cities if !force_reload && defined?(@@ip_cities) && @@ip_cities.present?
|
29
|
+
|
30
|
+
@@ip_cities = {}
|
31
|
+
File.open(Configuration.file_path, 'r') do |file|
|
32
|
+
datas = file.to_a.split(Configuration.separator)
|
33
|
+
datas.each do |data|
|
34
|
+
header = data.delete_at(0).chomp
|
35
|
+
data.each do |row|
|
36
|
+
ip_city = row.chomp.split(',')
|
37
|
+
@@ip_cities[header] ||= []
|
38
|
+
@@ip_cities[header] << ip_city
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@@ip_cities
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_by_ip(ip)
|
46
|
+
header, ip = get_header_and_ip(ip)
|
47
|
+
ip_cities = Base.ip_cities[header]
|
48
|
+
return nil if ip_cities.blank?
|
49
|
+
|
50
|
+
ip_cities = ip_cities.select { |ip_city| ip_city[0].to_i <= ip && ip_city[1].to_i >= ip }
|
51
|
+
ip_cities.sort_by { |ip_city| ip_city[1].to_i - ip_city[0].to_i }.first if ip_cities.present?
|
52
|
+
end
|
53
|
+
|
54
|
+
def defined_class_methods
|
55
|
+
Configuration.columns.each_with_index do |col, index|
|
56
|
+
next if Configuration.non_optional_columns.include?(col)
|
57
|
+
instance_eval(<<-METHOD, __FILE__, __LINE__ + 1)
|
58
|
+
def ip2#{col.to_s}(ip)
|
59
|
+
find_by_ip(ip).try(:[], #{index})
|
60
|
+
end
|
61
|
+
METHOD
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def undef_class_methods(symbols)
|
66
|
+
symbols.each do |symbol|
|
67
|
+
singleton.send :undef_method, "ip2#{symbol.to_s}".to_sym
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def singleton
|
72
|
+
class << Base; self; end
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
def get_header_and_ip(ip)
|
77
|
+
case ip
|
78
|
+
when Integer
|
79
|
+
[ip.to_ip.split('.').first, ip]
|
80
|
+
when String
|
81
|
+
[ip.split('.').first, ip.to_s.to_int_ip]
|
82
|
+
else
|
83
|
+
raise ArgumentError, 'Parameters can only be Integer and String'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
IPLibrary::Base.defined_class_methods
|
@@ -0,0 +1,162 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require 'csv'
|
3
|
+
module IPLibrary
|
4
|
+
|
5
|
+
class Data
|
6
|
+
TITLES = %w(start_ip end_ip province city district area_name_py start_ip1 end_ip1)
|
7
|
+
MUNICIPALITIES = %w(北京 上海 天津 重庆)
|
8
|
+
DISTRICT_REGEXP = /(自治县|自治旗|特区|林区|县|区|旗)$/
|
9
|
+
CITY_REGEXP = /(自治州|地区|市|州|盟)$/
|
10
|
+
PROVINCE_REGEXP = /(省|自治区|特别行政区)$/
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def generate_txt(infile_path, outfile_path = nil)
|
15
|
+
outfile_path ||= "#{Rails.root}/doc/#{Time.now.strftime('%y%m%d%H%M%S')}_ip_libraries.txt"
|
16
|
+
raise ArgumentError, '请出入正确的文件路径!' unless File.file?(infile_path) || File.extname(infile_path) != '.txt'
|
17
|
+
|
18
|
+
puts '正在生成txt文件'
|
19
|
+
File.open(outfile_path, 'w') do |file|
|
20
|
+
ip_cities = load_csv(infile_path).sort_by { |row| row[TITLES.index('start_ip')].to_i }
|
21
|
+
ip_cities = ip_cities.group_by { |row| row[TITLES.index('start_ip1')].split('.').first }
|
22
|
+
length = ip_cities.keys.size
|
23
|
+
index = 0
|
24
|
+
ip_cities.each do |key, value|
|
25
|
+
index += 1
|
26
|
+
file.write("#{key}\n")
|
27
|
+
value.each do |v|
|
28
|
+
file.write("#{v[0..4].join(',')}\n")
|
29
|
+
end
|
30
|
+
file.write("#{Configuration.separator}") if length != index
|
31
|
+
end
|
32
|
+
end
|
33
|
+
puts "已经生成txt文件:#{outfile_path}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_custom_ip_library(areas, outfile_path = nil, infile_path = nil)
|
37
|
+
infile_path ||= Configuration.file_path
|
38
|
+
outfile_path ||= File.join(Rails.root, 'doc', 'custom_ip_libraries.txt')
|
39
|
+
ip_city_ids = get_ip_city_ids(areas)
|
40
|
+
|
41
|
+
writer = []
|
42
|
+
File.open(infile_path, 'r') do |file|
|
43
|
+
file.each_line do |line|
|
44
|
+
if (cols = line.split(',')).size == 5 && ip_city_ids[cols[2]].present? && (city_id = (ip_city_ids[cols[2]][cols[3]] || ip_city_ids[cols[2]][cols[4]])).present?
|
45
|
+
writer << "#{cols[0]},#{cols[1]},#{city_id}\n"
|
46
|
+
elsif cols.size != 5
|
47
|
+
writer << cols.join(',')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
puts "正在生成#{outfile_path}"
|
53
|
+
File.open(outfile_path, 'w') do |file|
|
54
|
+
writer.each do |line|
|
55
|
+
file.write line
|
56
|
+
end
|
57
|
+
end
|
58
|
+
puts '生成完毕'
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def get_ip_city_ids(areas)
|
63
|
+
ip_city_ids = {}
|
64
|
+
ip_datas = Base.ip_cities.values.flatten(1).select { |t| t[2].present? && (t[3].present? || t[4].present?) }
|
65
|
+
|
66
|
+
size = ip_datas.size
|
67
|
+
ip_datas.each_with_index do |ip_city, index|
|
68
|
+
pp "------------------#{index + 1}/#{size}--------------------"
|
69
|
+
if ip_city[2].present?
|
70
|
+
ip_city_ids[ip_city[2]] ||= {}
|
71
|
+
|
72
|
+
if ip_city_ids[ip_city[2]][ip_city[3]].blank? && ip_city[3].present?
|
73
|
+
areas.each do |t|
|
74
|
+
if t['province'] =~ %r{#{ip_city[2]}} && t['city'] =~ %r{#{ip_city[3]}}
|
75
|
+
ip_city_ids[ip_city[2]][ip_city[3]] = t['city_id'] and break
|
76
|
+
end
|
77
|
+
end
|
78
|
+
unless ip_city_ids[ip_city[2]][ip_city[3]].present?
|
79
|
+
areas.each do |t|
|
80
|
+
if t['province'] =~ %r{#{ip_city[2]}} && t['district'] =~ %r{#{ip_city[3]}}
|
81
|
+
ip_city_ids[ip_city[2]][ip_city[3]] = t['city_id'] and break
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
elsif ip_city_ids[ip_city[2]][ip_city[4]].blank? && ip_city[3].blank? && ip_city[4].present?
|
86
|
+
areas.each do |t|
|
87
|
+
if t['province'] =~ %r{#{ip_city[2]}} && t['district'] =~ %r{#{ip_city[4]}}
|
88
|
+
ip_city_ids[ip_city[2]][ip_city[4]] = t['city_id'] and break
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
ip_city_ids
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_areas(province, city)
|
99
|
+
if province =~ /北京|上海|天津|重庆/
|
100
|
+
province.sub!(CITY_REGEXP, '')
|
101
|
+
if city.blank?
|
102
|
+
[nil, province, nil]
|
103
|
+
elsif city =~ DISTRICT_REGEXP
|
104
|
+
[nil, province, city]
|
105
|
+
end
|
106
|
+
elsif city.blank?
|
107
|
+
province.sub!(PROVINCE_REGEXP, '')
|
108
|
+
[province, nil, nil]
|
109
|
+
elsif city =~ CITY_REGEXP
|
110
|
+
province.sub!(PROVINCE_REGEXP, '')
|
111
|
+
city.sub!(CITY_REGEXP, '')
|
112
|
+
[province, city, nil]
|
113
|
+
elsif city =~ DISTRICT_REGEXP
|
114
|
+
province.sub!(PROVINCE_REGEXP, '')
|
115
|
+
[province, nil, city]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def get_areas_array(province, city)
|
120
|
+
if province =~ /\//
|
121
|
+
province.split('/').inject([]) do |result, p|
|
122
|
+
result << get_areas(p, city)
|
123
|
+
end
|
124
|
+
elsif city =~ /\//
|
125
|
+
city.split('/').inject([]) do |result, c|
|
126
|
+
result << get_areas(province, c)
|
127
|
+
end
|
128
|
+
else
|
129
|
+
[get_areas(province, city)]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def load_csv(path)
|
134
|
+
raise ArgumentError, '请出入正确的文件路径!' unless File.file?(path) || File.extname(path) != '.csv'
|
135
|
+
|
136
|
+
index = -1
|
137
|
+
col_index = {}
|
138
|
+
writer = []
|
139
|
+
|
140
|
+
CSV.foreach(path) do |row|
|
141
|
+
index += 1
|
142
|
+
GC.start if index % 100 == 0
|
143
|
+
if index == 0
|
144
|
+
(TITLES - ['district', 'area_name_py']).each do |col|
|
145
|
+
col_index[col.to_sym] = row.index(col)
|
146
|
+
end
|
147
|
+
raise "csv文件内容格式不正确,必须有#{(TITLES - ['district', 'area_name_py']).join(', ')}等字段" if col_index.values.include?(nil)
|
148
|
+
next
|
149
|
+
end
|
150
|
+
|
151
|
+
province = row[col_index[:province]].to_s.gsub(Configuration.except_regexp, '')
|
152
|
+
city = row[col_index[:city]].to_s.gsub(Configuration.except_regexp, '')
|
153
|
+
get_areas_array(province, city).each do |area|
|
154
|
+
puts [row[col_index[:start_ip]], row[col_index[:end_ip]], area].flatten and next if area.blank?
|
155
|
+
writer << [row[col_index[:start_ip]], row[col_index[:end_ip]], area, row[col_index[:start_ip1]], row[col_index[:end_ip1]]].flatten
|
156
|
+
end
|
157
|
+
end
|
158
|
+
writer
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module IPLibrary
|
2
|
+
|
3
|
+
module IP2integer
|
4
|
+
|
5
|
+
IP_REGEXP = /^(?:(?:2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(?:2[0-4]\d|25[0-5]|[01]?\d\d?)$/
|
6
|
+
IP_PERFIX_REGEXP = /^(?:(?:2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}$/
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Converts an IP string to integer
|
11
|
+
def ip2int(ip)
|
12
|
+
return 0 unless ip =~ IP_REGEXP
|
13
|
+
ip_segments = []
|
14
|
+
ip.split('.').each_with_index { |ip_seg, i| ip_segments << (ip_seg.to_i << 8*(3 - i)) }
|
15
|
+
ip_segments.inject(0) { |sum, ip_segment| sum = sum|ip_segment }
|
16
|
+
end
|
17
|
+
|
18
|
+
#Converts an INTEGER to IP string
|
19
|
+
def int2ip(intip)
|
20
|
+
ip_segments = [3, 2, 1, 0].map { |i| (intip & (255 << i*8)) >> i*8 }
|
21
|
+
(ip_str= ip_segments.join('.')) =~ IP_REGEXP ? ip_str : ''
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ip_library
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- tumayun
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-06 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'IPLibrary
|
15
|
+
|
16
|
+
=========
|
17
|
+
|
18
|
+
|
19
|
+
顾名思义,这是一个ip库
|
20
|
+
|
21
|
+
|
22
|
+
Example
|
23
|
+
|
24
|
+
=======
|
25
|
+
|
26
|
+
|
27
|
+
本gem中已经带有ip库,默认是gem目录下doc/ip_libraries.txt
|
28
|
+
|
29
|
+
默认ip库的格式以IPLibrary::Configuration.separator分组
|
30
|
+
|
31
|
+
各组第一行为ip头(192.168.1.1的ip头为192),其他行各列以英文逗号隔开
|
32
|
+
|
33
|
+
各列分别是:起始ip, 结束ip, 省份, 城市, 县区, 行政划分最小字段的拼音(如果有县区则为县区的拼音)
|
34
|
+
|
35
|
+
|
36
|
+
当然,您也可以有自己的ip库
|
37
|
+
|
38
|
+
设置ip库的path: IPLibrary::Configuration.file_path = ''/home/doc/ip_libraries.txt''
|
39
|
+
|
40
|
+
而且,您也可以设置ip库中的列的含义,start_ip、end_ip两列必须有,且必须依次为1、2列
|
41
|
+
|
42
|
+
设置其他列:IPLibrary::Configuration.optional_columns = [:province, :city, :district,
|
43
|
+
:pinyin]
|
44
|
+
|
45
|
+
除了1、2列,其他列一次为province、city、district、pinyin
|
46
|
+
|
47
|
+
然后会动态生成方法:
|
48
|
+
|
49
|
+
IPLibrary::Base#ip2province
|
50
|
+
|
51
|
+
IPLibrary::Base#ip2city
|
52
|
+
|
53
|
+
IPLibrary::Base#ip2district
|
54
|
+
|
55
|
+
IPLibrary::Base#ip2pinyin
|
56
|
+
|
57
|
+
|
58
|
+
=============================================
|
59
|
+
|
60
|
+
|
61
|
+
IPLibrary::Base 的方法有:
|
62
|
+
|
63
|
+
|
64
|
+
IPLibrary::Base.ip2province(''123.132.254.134'')
|
65
|
+
|
66
|
+
IPLibrary::Base.ip2province(2072313478)
|
67
|
+
|
68
|
+
#=> "山东"
|
69
|
+
|
70
|
+
|
71
|
+
IPLibrary::Base.ip2city(''123.132.254.134'')
|
72
|
+
|
73
|
+
IPLibrary::Base.ip2city(2072313478)
|
74
|
+
|
75
|
+
#=> "临沂"
|
76
|
+
|
77
|
+
|
78
|
+
IPLibrary::Base.ip2district(''123.132.254.134'')
|
79
|
+
|
80
|
+
IPLibrary::Base.ip2district(2072313478)
|
81
|
+
|
82
|
+
# => ""
|
83
|
+
|
84
|
+
|
85
|
+
IPLibrary::Base.ip2pinyin(''123.132.254.134'')
|
86
|
+
|
87
|
+
IPLibrary::Base.ip2pinyin(2072313478)
|
88
|
+
|
89
|
+
#=> "linyi"
|
90
|
+
|
91
|
+
'
|
92
|
+
email:
|
93
|
+
- tumayun.2010@gmail.com
|
94
|
+
executables: []
|
95
|
+
extensions: []
|
96
|
+
extra_rdoc_files: []
|
97
|
+
files:
|
98
|
+
- Gemfile
|
99
|
+
- ip_library.gemspec
|
100
|
+
- LICENSE
|
101
|
+
- Rakefile
|
102
|
+
- README.md
|
103
|
+
- lib/ip_library.rb
|
104
|
+
- lib/ip_library/version.rb
|
105
|
+
- lib/ip_library/base.rb
|
106
|
+
- lib/ip_library/data.rb
|
107
|
+
- lib/ip_library/integer.rb
|
108
|
+
- lib/ip_library/ip2integer.rb
|
109
|
+
- lib/ip_library/string.rb
|
110
|
+
- doc/ip_libraries.txt
|
111
|
+
homepage: https://github.com/tumayun/ip_library
|
112
|
+
licenses: []
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 1.8.24
|
132
|
+
signing_key:
|
133
|
+
specification_version: 3
|
134
|
+
summary: IPLibrary是一个ip库的gem,它能通过类似ip2city等方法得到ip所在城市
|
135
|
+
test_files: []
|