loyal_ipinfo 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/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: []