loyal_ipinfo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ = LoyalIpinfo
2
+
3
+ get ip info
4
+
5
+ eg:
6
+
7
+ ```ruby
8
+ # config
9
+
10
+ LoyalIpinfo.configure do |config|
11
+ # config.default_adapter = :qqwry
12
+ # config.default_library_file_path = '' # library_file_path
13
+ end
14
+
15
+ # usage:
16
+
17
+ worker = ::LoyalIpinfo::Worker.new
18
+
19
+ result = worker.find('127.0.0.1')
20
+
21
+ result.city # '本机地址'
22
+ result.area # ''
23
+
24
+ ```
25
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalIpinfo
3
+ class ArrayUtil
4
+ def self.extract_options!(arr)
5
+ if arr.last.is_a?(Hash)
6
+ arr.pop
7
+ else
8
+ {}
9
+ end
10
+ end
11
+
12
+ def self.init args
13
+ args.is_a?(Array) ? args : (args.nil? ? [] : [args])
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalIpinfo
3
+ class << self
4
+ attr_writer :config
5
+
6
+ def config
7
+ @config ||= Config.new
8
+ end
9
+
10
+ def configure
11
+ yield self.config ||= Config.new
12
+ end
13
+ end
14
+
15
+ class Config
16
+ def default_adapter
17
+ @default_adapter ||= :qqwry # 纯真qq
18
+ end
19
+
20
+ def default_adapter= _adapter
21
+ @default_adapter ||= _adapter
22
+ end
23
+
24
+ def default_library_file_path
25
+ @default_library_file_path ||= "#{File.dirname(__FILE__)}/../../resources/qqwry.dat"
26
+ end
27
+
28
+ def default_library_file_path= path
29
+ @default_library_file_path ||= path
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module LoyalIpinfo
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,226 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'iconv' unless RUBY_VERSION.respond_to?(:encode)
3
+
4
+ module LoyalIpinfo
5
+
6
+ class Worker
7
+ attr_reader :adapter, :library_file_path
8
+
9
+ def initialize attrs={}
10
+ @adapter ||= (attrs[:adapter] || ::LoyalIpinfo.config.default_adapter)
11
+ @library_file_path ||= (attrs[:library_file_path] || ::LoyalIpinfo.config.default_library_file_path)
12
+
13
+ case self.adapter
14
+ when :qqwry
15
+ self.extend ::LoyalIpinfo::QQwryAdapter
16
+ end
17
+ end
18
+ end
19
+
20
+ module QQwryAdapter
21
+ def find *args, &block
22
+ options = ::LoyalIpinfo::ArrayUtil.extract_options!(args)
23
+
24
+ @qqwry_db ||= QQWry::QQWryFile.new(self.library_file_path)
25
+
26
+ result = args.inject({}) do |_result, ip|
27
+ _result[ip] = @qqwry_db.find(ip)
28
+ _result
29
+ end
30
+
31
+ if block_given?
32
+ block.call result
33
+ end
34
+
35
+ if args.any?
36
+ if args.one?
37
+ result[args.first]
38
+ else
39
+ result
40
+ end
41
+ else
42
+ nil
43
+ end
44
+ end
45
+ module QQWry
46
+ module QQWryIO
47
+ def get_le32
48
+ arr = read(4).unpack("C4")
49
+ arr[0] | arr[1]<<8 | arr[2]<<16 | arr[3]<<24
50
+ end
51
+
52
+ def get_le24
53
+ arr = read(3).unpack("C3")
54
+ arr[0] | arr[1]<<8 | arr[2]<<16
55
+ end
56
+
57
+ def get_string
58
+ str = ""
59
+ while ((ch = read(1).unpack("a")[0]) != "\x00")
60
+ str += ch
61
+ end
62
+ str
63
+ end
64
+
65
+ def get_u8
66
+ read(1).unpack("C")[0]
67
+ end
68
+ end
69
+
70
+ module QQWryIpStr
71
+ def ip_str
72
+ [@ip].pack("L").unpack("C4").reverse.join(".")
73
+ end
74
+ end
75
+
76
+ class QQWryHeader
77
+ def initialize(file)
78
+ file.seek(0)
79
+ @first = file.get_le32
80
+ @last = file.get_le32
81
+ end
82
+ attr_reader :first, :last
83
+ end
84
+
85
+ class QQWryRecord
86
+ include QQWryIpStr
87
+
88
+ attr_reader :city, :area
89
+
90
+ def initialize(file, pos)
91
+ file.seek(pos)
92
+ @ip = file.get_le32
93
+ case file.get_u8
94
+ when 0x1
95
+ file.seek(pos = file.get_le24)
96
+ case file.get_u8
97
+ when 0x2
98
+ file.seek(file.get_le24)
99
+ @city = file.get_string
100
+ file.seek(pos + 4)
101
+ else
102
+ file.seek(-1, IO::SEEK_CUR)
103
+ @city = file.get_string
104
+ end
105
+ parse_area(file)
106
+ when 0x2
107
+ pos = file.get_le24
108
+ parse_area(file)
109
+ file.seek(pos)
110
+ @city = file.get_string
111
+ else
112
+ file.seek(-1, IO::SEEK_CUR)
113
+ @city = file.get_string
114
+ parse_area(file)
115
+ end
116
+
117
+ iconv_city
118
+ end
119
+
120
+ attr_reader :ip
121
+
122
+ def _conv(str)
123
+ begin
124
+ if str.respond_to?(:encode)
125
+ str.force_encoding('GBK').encode('UTF-8')
126
+ else
127
+ Iconv::conv('UTF-8', 'GBK', str)
128
+ end
129
+ rescue
130
+ str = str[0, str.length - 1]
131
+ retry
132
+ end
133
+ end
134
+
135
+ def iconv_city
136
+ @city = _conv @city.to_s
137
+ @city = '' if @city=~ /\s*CZ88\.NET\s*/
138
+ end
139
+
140
+ def parse_area(file)
141
+ case file.get_u8
142
+ when 0x2
143
+ if ((pos = file.get_le24) != 0)
144
+ file.seek(pos)
145
+ @area = file.get_string
146
+ else
147
+ @area = ""
148
+ end
149
+ else
150
+ file.seek(-1, IO::SEEK_CUR)
151
+ @area = file.get_string
152
+ end
153
+
154
+ @area = _conv(@area.to_s)
155
+
156
+ @area = '' if @area =~ /\s*CZ88\.NET\s*/
157
+ end
158
+
159
+ private :parse_area
160
+ end
161
+
162
+ class QQWryIndex
163
+ include QQWryIpStr
164
+
165
+ def initialize(file, pos)
166
+ file.seek(pos)
167
+ @ip = file.get_le32
168
+ @pos = file.get_le24
169
+ end
170
+ attr_reader :ip, :pos
171
+ end
172
+
173
+ class QQWryFile
174
+ def initialize(filename = "qqwry.dat")
175
+ @filename = filename
176
+ end
177
+
178
+ def each
179
+ File.open(@filename) do |file|
180
+ file.extend QQWryIO
181
+ header = QQWryHeader.new(file)
182
+ pos = header.first
183
+ while pos <= header.last
184
+ index = QQWryIndex.new(file, pos)
185
+ record = QQWryRecord.new(file, index.pos)
186
+ if block_given?
187
+ yield index, record
188
+ else
189
+ puts "#{index.ip_str}-#{record.ip_str} #{record.city}" +
190
+ " #{record.area}"
191
+ end
192
+ pos += 7
193
+ end
194
+ end
195
+ end
196
+
197
+ def find(ip)
198
+ if ip.class == String
199
+ ip = ip.split(".").collect{|x| x.to_i}.pack("C4").unpack("N")[0]
200
+ end
201
+
202
+ File.open(@filename) do |file|
203
+ file.extend QQWryIO
204
+ header = QQWryHeader.new(file)
205
+ first = header.first
206
+ left = 0
207
+ right = (header.last - first) / 7
208
+ while left <= right
209
+ middle = (left + right) / 2
210
+ middle_index = QQWryIndex.new(file, first + middle * 7)
211
+ if (ip > middle_index.ip)
212
+ left = middle + 1
213
+ elsif (ip < middle_index.ip)
214
+ right = middle - 1
215
+ else
216
+ return QQWryRecord.new(file, middle_index.pos)
217
+ end
218
+ end
219
+ index = QQWryIndex.new(file, first + right * 7)
220
+ return QQWryRecord.new(file, index.pos)
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,9 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'loyal_ipinfo/version'
3
+ require 'loyal_ipinfo/config'
4
+ require 'loyal_ipinfo/array_util'
5
+ require 'loyal_ipinfo/worker'
6
+
7
+ module LoyalIpinfo
8
+
9
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :loyal_ipinfo do
3
+ # # Task goes here
4
+ # end
Binary file
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loyal_ipinfo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - happy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bindata
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Description of LoyalIpinfo.
31
+ email:
32
+ - andywang7259@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - resources/qqwry.dat
38
+ - lib/loyal_ipinfo/config.rb
39
+ - lib/loyal_ipinfo/version.rb
40
+ - lib/loyal_ipinfo/array_util.rb
41
+ - lib/loyal_ipinfo/worker.rb
42
+ - lib/loyal_ipinfo.rb
43
+ - lib/tasks/loyal_ipinfo_tasks.rake
44
+ - MIT-LICENSE
45
+ - Rakefile
46
+ - README.md
47
+ homepage: http://develop.xiuxian123.com/
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ segments:
60
+ - 0
61
+ hash: 1415171691332789189
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ segments:
69
+ - 0
70
+ hash: 1415171691332789189
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 1.8.25
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Summary of LoyalIpinfo.
77
+ test_files: []