rfetion 0.5.0 → 0.5.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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 0.5.1
@@ -86,7 +86,7 @@ begin
86
86
 
87
87
  raise FetionException.new('You must input your mobile number or fetion sid, password and content') unless (options[:mobile_no] or options[:sid]) and options[:password] and options[:content]
88
88
  if options[:time]
89
- Fetion.schedule_sms(options)
89
+ Fetion.set_schedule_sms(options)
90
90
  else
91
91
  Fetion.send_sms(options)
92
92
  end
@@ -20,9 +20,7 @@ class Fetion
20
20
  DOMAIN = "fetion.com.cn"
21
21
 
22
22
  def initialize
23
- @call = 0
24
- @alive = 0
25
- @seq = 0
23
+ @call = @alive = @seq = 0
26
24
  @buddies = []
27
25
  @contacts = []
28
26
  @logger = Logger.new(STDOUT)
@@ -146,6 +144,8 @@ class Fetion
146
144
  end
147
145
 
148
146
  def login
147
+ @logger.info "fetion login"
148
+
149
149
  if @mobile_no
150
150
  url = FETION_LOGIN_URL.sub('%mobileno%', @mobile_no).sub('sid=%sid%', '')
151
151
  else
@@ -157,74 +157,82 @@ class Fetion
157
157
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
158
158
  headers = {'User-Agent' => USER_AGENT}
159
159
  response = http.request_get(uri.request_uri, headers)
160
+ parse_ssic(response)
160
161
 
161
- raise FetionException.new('Fetion Error: Login failed.') unless response.is_a? Net::HTTPSuccess
162
-
163
- parse_login_response(response)
162
+ @logger.info "fetion login success"
164
163
  end
165
164
 
166
165
  def register
166
+ @logger.info "fetion register"
167
+
167
168
  call = next_call
168
169
  register_first
169
170
  register_second
170
171
  call = next_call
172
+
173
+ @logger.info "fetion register success"
171
174
  end
172
175
 
173
176
  def register_first
177
+ @logger.debug "fetion register first"
178
+
174
179
  curl_exec(SIPP, next_url('i'))
175
180
  curl_exec(SipcMessage.register_first(self))
176
181
  response = pulse
177
- raise Fetion::NoNonceException.new("Fetion Error: no nonce found") unless response.body =~ /nonce="(.*?)",key="(.*?)",signature="(.*?)"/
178
-
179
- @nonce = $1
180
- @key = $2
181
- @signature = $3
182
- @response = calc_response
182
+ parse_nonce(response)
183
183
 
184
- @logger.debug "nonce: #{@nonce}"
185
- @logger.debug "key: #{@key}"
186
- @logger.debug "signature: #{@signature}"
187
- @logger.debug "response: #{@response}"
184
+ @logger.debug "fetion register first success"
188
185
  end
189
186
 
190
187
  def register_second
188
+ @logger.debug "fetion register second"
189
+
191
190
  body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{@mobile_no}" user-id="#{@user_id}"><personal version="0" attributes="v4default" /><custom-config version="0" /><contact-list version="0" buddy-attributes="v4default" /></user-info><credentials domains="fetion.com.cn;m161.com.cn;www.ikuwa.cn;games.fetion.com.cn" /><presence><basic value="400" desc="" /></presence></args>|
192
191
  curl_exec(SipcMessage.register_second(self))
193
192
  response = pulse
193
+ parse_info(response)
194
194
 
195
- raise FetionException.new('Fetion Error: Register failed.') unless response.is_a? Net::HTTPSuccess
196
-
197
- parse_info(response.body)
198
- parse_buddies(response.body)
195
+ @logger.debug "fetion register second success"
199
196
  end
200
197
 
201
198
  def get_contacts
199
+ @logger.info "fetion get contacts"
200
+
202
201
  curl_exec(SipcMessage.get_group_list(self))
203
202
 
204
203
  response = curl_exec(SipcMessage.presence(self))
205
204
  response = curl_exec(SipcMessage.get_group_topic(self))
206
- raise FetionException.new('Fetion Error: get contacts failed.') unless response.is_a? Net::HTTPSuccess
207
- parse_contacts(response.body)
205
+ parse_contacts(response)
208
206
 
209
207
  curl_exec(SipcMessage.get_address_list(self))
210
208
  pulse
209
+
210
+ @logger.info "fetion get contacts success"
211
211
  end
212
212
 
213
213
  def send_msg(receiver, content)
214
- @logger.info "fetion send msg to #{receiver}"
215
- curl_exec(SipcMessage.send_msg(self, receiver, content))
214
+ @logger.info "fetion send cat msg to #{receiver}"
215
+
216
+ curl_exec(SipcMessage.send_cat_msg(self, receiver, content))
216
217
  response = pulse
217
218
 
218
- raise SendMsgException.new("Fetion Error: Send sms error") unless response.is_a? Net::HTTPSuccess
219
- @logger.info "fetion send msg to #{receiver} success"
219
+ raise FetionException.new("Fetion Error: Send cat msg error") unless Net::HTTPSuccess === response
220
+ sipc_message = SipcMessage.sipc_response(response.body)
221
+ raise Fetion::SendMsgException.new("Fetion Error: Send cat msg error with #{sipc_message}") unless SipcMessage::OK === sipc_message
222
+
223
+ @logger.info "fetion send cat msg to #{receiver} success"
220
224
  end
221
225
 
222
226
  def send_sms(receiver, content)
223
227
  @logger.info "fetion send cat sms to #{receiver}"
228
+
224
229
  curl_exec(SipcMessage.send_cat_sms(self, receiver, content))
225
230
  response = pulse
226
231
 
227
- raise SendSmsException.new("Fetion Error: Send cat sms error") unless response.is_a? Net::HTTPSuccess
232
+ raise FetionException.new("Fetion Error: Send cat sms error") unless Net::HTTPSuccess === response
233
+ sipc_message = SipcMessage.sipc_response(response.body)
234
+ raise Fetion::SendSmsException.new("Fetion Error: Send cat sms error with #{sipc_message}") unless SipcMessage::Send === sipc_message
235
+
228
236
  @logger.info "fetion send cat sms to #{receiver} success"
229
237
  end
230
238
 
@@ -240,7 +248,10 @@ class Fetion
240
248
  curl_exec(SipcMessage.set_schedule_sms(self, receivers, content, time.strftime('%Y-%m-%d %H:%M:%S')))
241
249
  response = pulse
242
250
 
243
- raise SetScheduleSmsException.new("Fetion Error: Set schedule sms error") unless response.is_a? Net::HTTPSuccess
251
+ raise FetionException.new("Fetion Error: Set schedule sms error") unless Net::HTTPSuccess === response
252
+ sipc_message = SipcMessage.sipc_response(response.body)
253
+ raise Fetion::SetScheduleSmsException.new("Fetion Error: Set schedule sms error with #{sipc_message}") unless SipcMessage::OK === sipc_message
254
+
244
255
  @logger.info "fetion schedule send sms to #{receivers.join(', ')} success"
245
256
  end
246
257
 
@@ -253,7 +264,9 @@ class Fetion
253
264
  @logger.info "fetion send request to add #{uri} as friend"
254
265
  curl_exec(SipcMessage.add_buddy(self, options))
255
266
  response = pulse
256
- raise AddBuddyException.new("Fetion Error: Add buddy error") unless response.is_a? Net::HTTPSuccess
267
+ raise FetionException.new("Fetion Error: Add buddy error") unless Net::HTTPSuccess === response
268
+ sipc_message = SipcMessage.sipc_response(response.body)
269
+ raise Fetion::AddBuddyException.new("Fetion Error: Add buddy error with #{sipc_message}") unless SipcMessage::OK === sipc_message
257
270
 
258
271
  @logger.info "fetion send request to add #{uri} as friend success"
259
272
  end
@@ -265,23 +278,28 @@ class Fetion
265
278
  uri = options[:mobile_no] ? "tel:#{options[:mobile_no]}" : "sip:#{options[:sip]}"
266
279
 
267
280
  @logger.info "fetion get contact info of #{uri}"
268
- curl_exec(SipcMessage.get_contact_info(self, options))
281
+ curl_exec(SipcMessage.get_contact_info(self, uri))
269
282
  response = pulse
270
283
 
284
+ raise FetionException.new("Fetion Error: get contact info error") unless Net::HTTPSuccess === response
271
285
  sipc_response = SipcMessage.sipc_response(response.body)
272
- raise Fetion::NoUserException.new("Fetion Error: get contact info #{uri} with #{sipc_response.to_s}") unless SipcMessage::OK === sipc_response
286
+ raise Fetion::NoUserException.new("Fetion Error: get contact info #{uri} with #{sipc_response}") unless SipcMessage::OK === sipc_response
273
287
 
274
288
  @logger.info "fetion get contact info of #{uri} success"
275
289
  end
276
290
 
277
291
  def logout
292
+ @logger.info "fetion logout"
293
+
278
294
  curl_exec(SipcMessage.logout(self))
279
295
  response = pulse
280
296
 
281
297
  # raise FetionException.new("Fetion Error: Logout error") unless response.is_a? Net::HTTPSuccess
298
+ @logger.info "fetion logout success"
282
299
  end
283
300
 
284
- def parse_login_response(response)
301
+ def parse_ssic(response)
302
+ raise Fetion::LoginException.new('Fetion Error: Login failed.') unless Net::HTTPSuccess === response
285
303
  raise Fetion::LoginException.new('Fetion Error: No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
286
304
 
287
305
  @ssic = $1
@@ -306,34 +324,54 @@ class Fetion
306
324
  @logger.debug "user_id: " + @user_id
307
325
  @logger.debug "sid: " + @sid
308
326
  end
327
+
328
+ def parse_nonce(response)
329
+ raise FetionException.new("Fetion Error: Register first error.") unless Net::HTTPSuccess === response
330
+ sipc_response = SipcMessage.sipc_response(response.body)
331
+ raise Fetion::RegisterException.new("Fetion Error: Register first should get unauthorized response with #{sipc_response}.") unless SipcMessage::Unauthoried === sipc_response
332
+ raise Fetion::NoNonceException.new("Fetion Error: No nonce found") unless response.body =~ /nonce="(.*?)",key="(.*?)",signature="(.*?)"/
333
+
334
+ @nonce = $1
335
+ @key = $2
336
+ @signature = $3
337
+ @response = calc_response
338
+
339
+ @logger.debug "nonce: #{@nonce}"
340
+ @logger.debug "key: #{@key}"
341
+ @logger.debug "signature: #{@signature}"
342
+ @logger.debug "response: #{@response}"
343
+ end
309
344
 
310
- def parse_info(response_body)
311
- response_body.scan(%r{<results>.*?</results>}).each do |results|
345
+ def parse_info(response)
346
+ raise Fetion::FetionException.new("Fetion Error: Register second error.") unless Net::HTTPSuccess === response
347
+ sipc_response = SipcMessage.sipc_response(response.body)
348
+ raise Fetion::RegisterException.new("Fetion Error: Register second error with #{sipc_response}.") unless SipcMessage::OK === sipc_response
349
+
350
+ response.body.scan(%r{<results>.*?</results>}).each do |results|
312
351
  doc = Nokogiri::XML(results)
313
352
  personal = doc.root.xpath("/results/user-info/personal").first
314
353
  @nickname = personal['nickname']
315
- end
316
-
317
- @logger.debug "nickname: #@nickname"
318
- end
319
-
320
- def parse_buddies(response_body)
321
- response_body.scan(%r{<results>.*?</results>}).each do |results|
322
- doc = Nokogiri::XML(results)
323
354
  doc.root.xpath("/results//buddies/b").each do |buddy|
324
355
  @buddies << {:uri => buddy["u"]}
325
356
  end
326
357
  end
358
+
359
+ @logger.debug "nickname: #@nickname"
327
360
  @logger.debug "buddies: #{@buddies.inspect}"
328
361
  end
329
362
 
330
- def parse_contacts(response_body)
331
- response_body.scan(%r{<events>.*?</events>}).each do |results|
363
+ def parse_contacts(response)
364
+ raise FetionException.new('Fetion Error: get contacts error.') unless Net::HTTPSuccess === response
365
+ sipc_response = SipcMessage.sipc_response(response.body)
366
+ raise Fetion::GetContactsException.new("Fetion Error: get contacts failed with #{sipc_response}.") unless Net::HTTPSuccess === response and SipcMessage::OK === sipc_response
367
+
368
+ response.body.scan(%r{<events>.*?</events>}).each do |results|
332
369
  doc = Nokogiri::XML(results)
333
370
  doc.root.xpath("/events//c/p").each do |person|
334
371
  @contacts << Contact.new(person) if person['sid']
335
372
  end
336
373
  end
374
+
337
375
  @logger.debug "contacts: #{@contacts.inspect}"
338
376
  end
339
377
 
@@ -388,30 +426,6 @@ class Fetion
388
426
  def self?(mobile_or_sid)
389
427
  mobile_or_sid == @mobile_no or mobile_or_sid == @sid
390
428
  end
391
-
392
- [:login, :register, :get_contacts, :logout].each do |method|
393
- class_eval <<-EOF
394
- alias_method :origin_#{method}, :#{method}
395
-
396
- def #{method}
397
- @logger.info "fetion #{method.to_s.gsub(/_/, ' ')}"
398
- origin_#{method}
399
- @logger.info "fetion #{method.to_s.gsub(/_/, ' ')} success"
400
- end
401
- EOF
402
- end
403
-
404
- [:register_first, :register_second].each do |method|
405
- class_eval <<-EOF
406
- alias_method :origin_#{method}, :#{method}
407
-
408
- def #{method}
409
- @logger.debug "fetion #{method.to_s.gsub(/_/, ' ')}"
410
- origin_#{method}
411
- @logger.debug "fetion #{method.to_s.gsub(/_/, ' ')} success"
412
- end
413
- EOF
414
- end
415
429
  end
416
430
 
417
431
  class FetionException < Exception; end
@@ -422,4 +436,5 @@ class Fetion::SendSmsException < FetionException; end
422
436
  class Fetion::SendMsgException < FetionException; end
423
437
  class Fetion::SetScheduleSmsException < FetionException; end
424
438
  class Fetion::AddBuddyException < FetionException; end
439
+ class Fetion::GetContactsException < FetionException; end
425
440
  class Fetion::NoUserException < FetionException; end
@@ -34,8 +34,8 @@ class SipcMessage
34
34
  sipc_create(:command => 'M', :F => fetion.sid, :I => fetion.next_call, :Q => '1 M', :T => receiver, :N => 'SendCatSMS', :body => content)
35
35
  end
36
36
 
37
- def self.send_msg(fetion, receiver, content)
38
- sipc_create(:command => 'M', :F => fetion.sid, :I => fetion.next_call, :Q => '3 M', :T => receiver, :K => 'SaveHistory', :body => content)
37
+ def self.send_cat_msg(fetion, receiver, content)
38
+ sipc_create(:command => 'M', :F => fetion.sid, :I => fetion.next_call, :Q => '2 M', :T => receiver, :K => 'SaveHistory', :N => 'CatMsg', :body => content)
39
39
  end
40
40
 
41
41
  def self.set_schedule_sms(fetion, receivers, content, time)
@@ -49,8 +49,8 @@ class SipcMessage
49
49
  sipc_create(:command => 'S', :F => fetion.sid, :I => fetion.next_call, :Q => '1 S', :N => 'AddBuddyV4', :body => body)
50
50
  end
51
51
 
52
- def self.get_contact_info(fetion, mobile_no)
53
- body = %Q|<args><contact uri="tel:#{mobile_no}" /></args>|
52
+ def self.get_contact_info(fetion, uri)
53
+ body = %Q|<args><contact uri="#{uri}" /></args>|
54
54
  sipc_create(:command => 'S', :F => fetion.sid, :I => fetion.next_call, :Q => '1 S', :N => 'GetContactInfoV4', :body => body)
55
55
  end
56
56
 
@@ -66,7 +66,7 @@ class SipcMessage
66
66
  body = options.delete(:body)
67
67
  with_l = options.delete(:with_l)
68
68
 
69
- sorted_key = [:F, :I, :Q, :CN, :CL, :A, :AK, :X, :T, :N, :K, :SV]
69
+ sorted_key = [:F, :I, :Q, :CN, :CL, :A, :AK, :X, :T, :K, :N, :SV]
70
70
  sipc = "#{options.delete(:command)} fetion.com.cn SIP-C/4.0\r\n"
71
71
  sorted_key.each {|k| sipc += "#{k}: #{options[k]}\r\n" if options[k]}
72
72
  sipc += "L: #{body == '' ? 4 : body.size}\r\n" if with_l
@@ -75,8 +75,10 @@ class SipcMessage
75
75
  end
76
76
 
77
77
  def self.sipc_response(http_response_body)
78
- sipc, code, message = http_response_body.to_a.first.split(' ')
78
+ sipc, code, message = http_response_body.split(/(\r)?\n/).first.split(' ')
79
79
  RESPONSES[code.to_i].new(code, message)
80
+ rescue NoMethodError
81
+ raise FetionException.new("Fetion error: No response to #{code} #{message}")
80
82
  end
81
83
 
82
84
  class Response
@@ -93,11 +95,17 @@ class SipcMessage
93
95
  end
94
96
 
95
97
  class OK < Response; end
98
+ class Send < Response; end
99
+ class Bad < Response; end
100
+ class Unauthoried < Response; end
96
101
  class NotFound < Response; end
97
102
  class ExtentionRequired < Response; end
98
103
 
99
104
  RESPONSES = {
100
105
  200 => SipcMessage::OK,
106
+ 280 => SipcMessage::Send,
107
+ 400 => SipcMessage::Bad,
108
+ 401 => SipcMessage::Unauthoried,
101
109
  404 => SipcMessage::NotFound,
102
110
  421 => SipcMessage::ExtentionRequired
103
111
  }
data/rfetion.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rfetion}
8
- s.version = "0.5.0"
8
+ s.version = "0.5.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Richard Huang"]
12
- s.date = %q{2010-05-09}
12
+ s.date = %q{2010-05-10}
13
13
  s.description = %q{rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.}
14
14
  s.email = %q{flyerhzm@gmail.com}
15
15
  s.executables = ["rfetion", "rfetion"]
@@ -87,6 +87,7 @@ F: 730020377
87
87
  I: 1
88
88
  Q: 1 R
89
89
  W: Digest algorithm="SHA1-sess-v4",nonce=""
90
+
90
91
  SIPP
91
92
  EOF
92
93
  FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=3", :body => response_body)
@@ -57,10 +57,10 @@ describe SipcMessage do
57
57
  SipcMessage.send_cat_sms(@fetion, 'sip:730020377@fetion.com.cn;p=6907', 'test').should == sipc_message
58
58
  end
59
59
 
60
- it "should send msg" do
60
+ it "should send cat msg" do
61
61
  @fetion.call = 8
62
- sipc_message = %Q|M fetion.com.cn SIP-C/4.0\r\nF: 730020377\r\nI: 9\r\nQ: 3 M\r\nT: sip:638993408@fetion.com.cn;p=2242\r\nK: SaveHistory\r\nL: 4\r\n\r\ntestSIPP|
63
- SipcMessage.send_msg(@fetion, 'sip:638993408@fetion.com.cn;p=2242', 'test').should == sipc_message
62
+ sipc_message = %Q|M fetion.com.cn SIP-C/4.0\r\nF: 730020377\r\nI: 9\r\nQ: 2 M\r\nT: sip:638993408@fetion.com.cn;p=2242\r\nK: SaveHistory\r\nN: CatMsg\r\nL: 4\r\n\r\ntestSIPP|
63
+ SipcMessage.send_cat_msg(@fetion, 'sip:638993408@fetion.com.cn;p=2242', 'test').should == sipc_message
64
64
  end
65
65
 
66
66
  it "should set schedule sms" do
@@ -72,7 +72,7 @@ describe SipcMessage do
72
72
  it "should get contact info" do
73
73
  @fetion.call = 10
74
74
  sipc_message = %Q|S fetion.com.cn SIP-C/4.0\r\nF: 730020377\r\nI: 11\r\nQ: 1 S\r\nN: GetContactInfoV4\r\nL: 46\r\n\r\n<args><contact uri="tel:15800681507" /></args>SIPP|
75
- SipcMessage.get_contact_info(@fetion, 15800681507).should == sipc_message
75
+ SipcMessage.get_contact_info(@fetion, "tel:15800681507").should == sipc_message
76
76
  end
77
77
 
78
78
  it "should add buddy" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rfetion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-05-09 00:00:00 -06:00
12
+ date: 2010-05-10 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency