rfetion 0.5.1 → 0.5.2
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 +1 -1
- data/lib/rfetion/buddy_list.rb +14 -0
- data/lib/rfetion/contact.rb +22 -8
- data/lib/rfetion/fetion.rb +101 -91
- data/lib/rfetion/message.rb +11 -0
- data/lib/rfetion/sipc_message.rb +31 -24
- data/lib/rfetion.rb +2 -0
- data/rfetion.gemspec +4 -2
- data/spec/rfetion/fetion_spec.rb +158 -3
- data/spec/spec.opts +1 -0
- metadata +4 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.2
|
data/lib/rfetion/contact.rb
CHANGED
@@ -1,11 +1,25 @@
|
|
1
|
-
class
|
2
|
-
|
1
|
+
class Fetion
|
2
|
+
class Contact
|
3
|
+
attr_accessor :id, :sid, :uri, :mobile_no, :nickname, :impresa, :nickname, :status
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
STATUS = {
|
6
|
+
"400" => "在线",
|
7
|
+
"300" => "离开",
|
8
|
+
"600" => "繁忙",
|
9
|
+
"0" => "脱机"
|
10
|
+
}
|
11
|
+
|
12
|
+
def self.parse(c)
|
13
|
+
contact = self.new
|
14
|
+
contact.id = c['id']
|
15
|
+
p = c.children.first
|
16
|
+
contact.sid = p["sid"]
|
17
|
+
contact.uri = p["su"]
|
18
|
+
contact.mobile_no = p["m"]
|
19
|
+
contact.nickname = p["n"]
|
20
|
+
contact.impresa = p["i"]
|
21
|
+
contact.status = p["b"]
|
22
|
+
contact
|
23
|
+
end
|
10
24
|
end
|
11
25
|
end
|
data/lib/rfetion/fetion.rb
CHANGED
@@ -9,7 +9,7 @@ require 'logger'
|
|
9
9
|
|
10
10
|
class Fetion
|
11
11
|
attr_accessor :mobile_no, :sid, :password
|
12
|
-
attr_reader :user_id, :uri, :contacts, :response, :nickname
|
12
|
+
attr_reader :user_id, :uri, :contacts, :buddy_lists, :response, :nickname, :receives
|
13
13
|
|
14
14
|
FETION_URL = 'http://221.176.31.39/ht/sd.aspx'
|
15
15
|
FETION_LOGIN_URL = 'https://uid.fetion.com.cn/ssiportal/SSIAppSignInV4.aspx?mobileno=%mobileno%sid=%sid%&domains=fetion.com.cn;m161.com.cn;www.ikuwa.cn&v4digest-type=1&v4digest=%digest%'
|
@@ -21,8 +21,10 @@ class Fetion
|
|
21
21
|
|
22
22
|
def initialize
|
23
23
|
@call = @alive = @seq = 0
|
24
|
+
@buddy_lists = []
|
24
25
|
@buddies = []
|
25
26
|
@contacts = []
|
27
|
+
@receives = []
|
26
28
|
@logger = Logger.new(STDOUT)
|
27
29
|
@logger.level = Logger::INFO
|
28
30
|
@guid = Guid.new.to_s
|
@@ -178,8 +180,7 @@ class Fetion
|
|
178
180
|
|
179
181
|
curl_exec(SIPP, next_url('i'))
|
180
182
|
curl_exec(SipcMessage.register_first(self))
|
181
|
-
|
182
|
-
parse_nonce(response)
|
183
|
+
pulse(SipcMessage::Unauthoried)
|
183
184
|
|
184
185
|
@logger.debug "fetion register first success"
|
185
186
|
end
|
@@ -189,8 +190,7 @@ class Fetion
|
|
189
190
|
|
190
191
|
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>|
|
191
192
|
curl_exec(SipcMessage.register_second(self))
|
192
|
-
|
193
|
-
parse_info(response)
|
193
|
+
pulse
|
194
194
|
|
195
195
|
@logger.debug "fetion register second success"
|
196
196
|
end
|
@@ -199,11 +199,8 @@ class Fetion
|
|
199
199
|
@logger.info "fetion get contacts"
|
200
200
|
|
201
201
|
curl_exec(SipcMessage.get_group_list(self))
|
202
|
-
|
203
|
-
|
204
|
-
response = curl_exec(SipcMessage.get_group_topic(self))
|
205
|
-
parse_contacts(response)
|
206
|
-
|
202
|
+
curl_exec(SipcMessage.presence(self))
|
203
|
+
curl_exec(SipcMessage.get_group_topic(self))
|
207
204
|
curl_exec(SipcMessage.get_address_list(self))
|
208
205
|
pulse
|
209
206
|
|
@@ -214,11 +211,7 @@ class Fetion
|
|
214
211
|
@logger.info "fetion send cat msg to #{receiver}"
|
215
212
|
|
216
213
|
curl_exec(SipcMessage.send_cat_msg(self, receiver, content))
|
217
|
-
|
218
|
-
|
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
|
214
|
+
pulse
|
222
215
|
|
223
216
|
@logger.info "fetion send cat msg to #{receiver} success"
|
224
217
|
end
|
@@ -227,11 +220,7 @@ class Fetion
|
|
227
220
|
@logger.info "fetion send cat sms to #{receiver}"
|
228
221
|
|
229
222
|
curl_exec(SipcMessage.send_cat_sms(self, receiver, content))
|
230
|
-
|
231
|
-
|
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
|
223
|
+
pulse(SipcMessage::Send)
|
235
224
|
|
236
225
|
@logger.info "fetion send cat sms to #{receiver} success"
|
237
226
|
end
|
@@ -246,11 +235,7 @@ class Fetion
|
|
246
235
|
@logger.info "fetion schedule send sms to #{receivers.join(', ')}"
|
247
236
|
|
248
237
|
curl_exec(SipcMessage.set_schedule_sms(self, receivers, content, time.strftime('%Y-%m-%d %H:%M:%S')))
|
249
|
-
|
250
|
-
|
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
|
238
|
+
pulse
|
254
239
|
|
255
240
|
@logger.info "fetion schedule send sms to #{receivers.join(', ')} success"
|
256
241
|
end
|
@@ -260,13 +245,10 @@ class Fetion
|
|
260
245
|
# friend_sip
|
261
246
|
def add_buddy(options)
|
262
247
|
uri = options[:friend_mobile] ? "tel:#{options[:friend_mobile]}" : "sip:#{options[:friend_sip]}"
|
263
|
-
|
264
248
|
@logger.info "fetion send request to add #{uri} as friend"
|
249
|
+
|
265
250
|
curl_exec(SipcMessage.add_buddy(self, options))
|
266
|
-
|
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
|
251
|
+
pulse
|
270
252
|
|
271
253
|
@logger.info "fetion send request to add #{uri} as friend success"
|
272
254
|
end
|
@@ -276,25 +258,28 @@ class Fetion
|
|
276
258
|
# sip
|
277
259
|
def get_contact_info(options)
|
278
260
|
uri = options[:mobile_no] ? "tel:#{options[:mobile_no]}" : "sip:#{options[:sip]}"
|
279
|
-
|
280
261
|
@logger.info "fetion get contact info of #{uri}"
|
262
|
+
|
281
263
|
curl_exec(SipcMessage.get_contact_info(self, uri))
|
282
|
-
|
283
|
-
|
284
|
-
raise FetionException.new("Fetion Error: get contact info error") unless Net::HTTPSuccess === response
|
285
|
-
sipc_response = SipcMessage.sipc_response(response.body)
|
286
|
-
raise Fetion::NoUserException.new("Fetion Error: get contact info #{uri} with #{sipc_response}") unless SipcMessage::OK === sipc_response
|
264
|
+
pulse
|
287
265
|
|
288
266
|
@logger.info "fetion get contact info of #{uri} success"
|
289
267
|
end
|
290
268
|
|
269
|
+
def keep_alive
|
270
|
+
@logger.info "fetion keep alive"
|
271
|
+
|
272
|
+
pulse
|
273
|
+
|
274
|
+
@logger.info "fetion keep alive success"
|
275
|
+
end
|
276
|
+
|
291
277
|
def logout
|
292
278
|
@logger.info "fetion logout"
|
293
279
|
|
294
280
|
curl_exec(SipcMessage.logout(self))
|
295
|
-
|
281
|
+
pulse
|
296
282
|
|
297
|
-
# raise FetionException.new("Fetion Error: Logout error") unless response.is_a? Net::HTTPSuccess
|
298
283
|
@logger.info "fetion logout success"
|
299
284
|
end
|
300
285
|
|
@@ -324,65 +309,16 @@ class Fetion
|
|
324
309
|
@logger.debug "user_id: " + @user_id
|
325
310
|
@logger.debug "sid: " + @sid
|
326
311
|
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
|
344
|
-
|
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|
|
351
|
-
doc = Nokogiri::XML(results)
|
352
|
-
personal = doc.root.xpath("/results/user-info/personal").first
|
353
|
-
@nickname = personal['nickname']
|
354
|
-
doc.root.xpath("/results//buddies/b").each do |buddy|
|
355
|
-
@buddies << {:uri => buddy["u"]}
|
356
|
-
end
|
357
|
-
end
|
358
312
|
|
359
|
-
|
360
|
-
|
313
|
+
def pulse(expected=SipcMessage::OK)
|
314
|
+
curl_exec(SIPP, next_url, expected)
|
361
315
|
end
|
362
316
|
|
363
|
-
def
|
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|
|
369
|
-
doc = Nokogiri::XML(results)
|
370
|
-
doc.root.xpath("/events//c/p").each do |person|
|
371
|
-
@contacts << Contact.new(person) if person['sid']
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
@logger.debug "contacts: #{@contacts.inspect}"
|
376
|
-
end
|
377
|
-
|
378
|
-
def pulse
|
379
|
-
curl_exec(SIPP)
|
380
|
-
end
|
381
|
-
|
382
|
-
def curl_exec(body='', url=next_url)
|
317
|
+
def curl_exec(body='', url=next_url, expected=SipcMessage::OK)
|
383
318
|
@logger.debug "fetion curl exec"
|
384
319
|
@logger.debug "url: #{url}"
|
385
320
|
@logger.debug "body: #{body}"
|
321
|
+
|
386
322
|
uri = URI.parse(url)
|
387
323
|
http = Net::HTTP.new(uri.host, uri.port)
|
388
324
|
headers = {'Content-Type' => 'application/oct-stream', 'Pragma' => "xz4BBcV#{@guid}", 'User-Agent' => USER_AGENT, 'Cookie' => "ssic=#{@ssic}", 'Content-Length' => body.length.to_s}
|
@@ -391,6 +327,71 @@ class Fetion
|
|
391
327
|
@logger.debug "response: #{response.inspect}"
|
392
328
|
@logger.debug "response body: #{response.body}"
|
393
329
|
@logger.debug "fetion curl exec complete"
|
330
|
+
|
331
|
+
raise FetionException.new("request_url: #{url}, request_body: #{body}, response: #{response.code}, response_body: #{response.body}") unless Net::HTTPSuccess === response
|
332
|
+
sipc_response = SipcMessage.sipc_response(response.body, self)
|
333
|
+
|
334
|
+
if sipc_response
|
335
|
+
raise Fetion::SipcException.new(sipc_response, "request_url: #{url}, request_body: #{body}, sipc_response: #{sipc_response}") unless expected === sipc_response
|
336
|
+
|
337
|
+
if sipc_response.code == 401
|
338
|
+
# unauthorized, get nonce, key and signature
|
339
|
+
raise Fetion::NoNonceException.new("Fetion Error: No nonce found") unless response.body =~ /nonce="(.*?)",key="(.*?)",signature="(.*?)"/
|
340
|
+
@nonce = $1
|
341
|
+
@key = $2
|
342
|
+
@signature = $3
|
343
|
+
@response = calc_response
|
344
|
+
|
345
|
+
@logger.debug "nonce: #{@nonce}"
|
346
|
+
@logger.debug "key: #{@key}"
|
347
|
+
@logger.debug "signature: #{@signature}"
|
348
|
+
@logger.debug "response: #{@response}"
|
349
|
+
else
|
350
|
+
response.body.scan(%r{<results>.*?</results>}).each do |results|
|
351
|
+
doc = Nokogiri::XML(results)
|
352
|
+
doc.root.xpath("/results/user-info/personal").each do |personal_element|
|
353
|
+
@nickname = personal_element['nickname']
|
354
|
+
@logger.debug "nickname: #@nickname"
|
355
|
+
end
|
356
|
+
doc.root.xpath("/results/user-info/contact-list/buddy-lists/buddy-list").each do |buddy_list|
|
357
|
+
@buddy_lists << Fetion::BuddyList.parse(buddy_list)
|
358
|
+
@logger.debug "buddy_lists: #{@buddy_lists.inspect}"
|
359
|
+
end
|
360
|
+
doc.root.xpath("/results/user-info/contact-list/buddies/b").each do |buddy|
|
361
|
+
@buddies << {:uri => buddy["u"]}
|
362
|
+
@logger.debug "buddies: #{@buddies.inspect}"
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
response.body.scan(%r{<events>.*?</events>}).each do |events|
|
367
|
+
doc = Nokogiri::XML(events)
|
368
|
+
doc.root.xpath("/events/event[@type='PresenceChanged']/contacts/c").each do |c|
|
369
|
+
contact = contacts.find {|contact| contact.id == c['id']}
|
370
|
+
if contact
|
371
|
+
contact.status = c.children.first['b']
|
372
|
+
else
|
373
|
+
@contacts << Fetion::Contact.parse(c) unless c['id'] == @user_id
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
receive_messages = response.body.scan(%r{M #{@sid} SIP-C/4.0.*?BN}m)
|
379
|
+
receive_messages = response.body.scan(%r{M #{@sid} SIP-C/4.0.*?SIPP$}m) if receive_messages.empty?
|
380
|
+
receive_messages.each do |message_response|
|
381
|
+
message_header, message_content = message_response.split(/(\r)?\n(\r)?\n/)
|
382
|
+
sip = sent_at = length = nil
|
383
|
+
message_header.split(/(\r)?\n/).each do |line|
|
384
|
+
case line
|
385
|
+
when /^F: sip:(.+)/ then sip = $1
|
386
|
+
when /^D: (.+)/ then sent_at = Time.parse($1)
|
387
|
+
when /^L: (\d+)/ then length = $1.to_i
|
388
|
+
end
|
389
|
+
end
|
390
|
+
text = message_content.slice(0, length)
|
391
|
+
@receives << Fetion::Message.new(sip, sent_at, text)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
394
395
|
response
|
395
396
|
end
|
396
397
|
|
@@ -438,3 +439,12 @@ class Fetion::SetScheduleSmsException < FetionException; end
|
|
438
439
|
class Fetion::AddBuddyException < FetionException; end
|
439
440
|
class Fetion::GetContactsException < FetionException; end
|
440
441
|
class Fetion::NoUserException < FetionException; end
|
442
|
+
class Fetion::SipcException < FetionException
|
443
|
+
attr_reader :code, :description, :message
|
444
|
+
|
445
|
+
def initialize(sipc_response, message)
|
446
|
+
@code = sipc_response.code
|
447
|
+
@description = sipc_response.description
|
448
|
+
@message = message
|
449
|
+
end
|
450
|
+
end
|
data/lib/rfetion/sipc_message.rb
CHANGED
@@ -58,39 +58,29 @@ class SipcMessage
|
|
58
58
|
sipc_create(:command => 'R', :F => fetion.sid, :I => 1, :Q => '3 R', :X => 0, :with_l => false)
|
59
59
|
end
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
sipc = "#{options.delete(:command)} fetion.com.cn SIP-C/4.0\r\n"
|
71
|
-
sorted_key.each {|k| sipc += "#{k}: #{options[k]}\r\n" if options[k]}
|
72
|
-
sipc += "L: #{body == '' ? 4 : body.size}\r\n" if with_l
|
73
|
-
sipc += "\r\n#{body}#{Fetion::SIPP}"
|
74
|
-
sipc
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.sipc_response(http_response_body)
|
78
|
-
sipc, code, message = http_response_body.split(/(\r)?\n/).first.split(' ')
|
79
|
-
RESPONSES[code.to_i].new(code, message)
|
61
|
+
def self.sipc_response(http_response_body, fetion)
|
62
|
+
return if http_response_body == Fetion::SIPP
|
63
|
+
|
64
|
+
if http_response_body =~ %r{^SIP-C/4.0}
|
65
|
+
sipc, code, *message = http_response_body.split(/(\r)?\n/).first.split(' ')
|
66
|
+
RESPONSES[code.to_i].new(code.to_i, message.join(' '))
|
67
|
+
elsif http_response_body =~ %r{(BN|M) #{fetion.sid} SIP-C/4.0}
|
68
|
+
SipcMessage::OK.new(200, $1)
|
69
|
+
end
|
80
70
|
rescue NoMethodError
|
81
|
-
raise FetionException.new("Fetion error: No response to #{code} #{message}")
|
71
|
+
raise FetionException.new("Fetion error: No response to #{code} #{message.join(' ')}")
|
82
72
|
end
|
83
73
|
|
84
74
|
class Response
|
85
|
-
attr_reader :code, :
|
75
|
+
attr_reader :code, :description
|
86
76
|
|
87
|
-
def initialize(code,
|
77
|
+
def initialize(code, description)
|
88
78
|
@code = code
|
89
|
-
@
|
79
|
+
@description = description
|
90
80
|
end
|
91
81
|
|
92
82
|
def to_s
|
93
|
-
"#@code #@
|
83
|
+
"#@code #@description"
|
94
84
|
end
|
95
85
|
end
|
96
86
|
|
@@ -109,4 +99,21 @@ class SipcMessage
|
|
109
99
|
404 => SipcMessage::NotFound,
|
110
100
|
421 => SipcMessage::ExtentionRequired
|
111
101
|
}
|
102
|
+
|
103
|
+
private
|
104
|
+
# command one of 'R', 'S'
|
105
|
+
# with_l display L or not
|
106
|
+
# body sipc body
|
107
|
+
def self.sipc_create(options)
|
108
|
+
options = {:body => '', :with_l => true}.merge(options)
|
109
|
+
body = options.delete(:body)
|
110
|
+
with_l = options.delete(:with_l)
|
111
|
+
|
112
|
+
sorted_key = [:F, :I, :Q, :CN, :CL, :A, :AK, :X, :T, :K, :N, :SV]
|
113
|
+
sipc = "#{options.delete(:command)} fetion.com.cn SIP-C/4.0\r\n"
|
114
|
+
sorted_key.each {|k| sipc += "#{k}: #{options[k]}\r\n" if options[k]}
|
115
|
+
sipc += "L: #{body == '' ? 4 : body.size}\r\n" if with_l
|
116
|
+
sipc += "\r\n#{body}#{Fetion::SIPP}"
|
117
|
+
sipc
|
118
|
+
end
|
112
119
|
end
|
data/lib/rfetion.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require File.dirname(__FILE__) + '/rfetion/buddy_list'
|
2
3
|
require File.dirname(__FILE__) + '/rfetion/contact'
|
4
|
+
require File.dirname(__FILE__) + '/rfetion/message'
|
3
5
|
require File.dirname(__FILE__) + '/rfetion/sipc_message'
|
4
6
|
require File.dirname(__FILE__) + '/rfetion/fetion'
|
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.
|
8
|
+
s.version = "0.5.2"
|
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-
|
12
|
+
s.date = %q{2010-05-15}
|
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"]
|
@@ -22,9 +22,11 @@ Gem::Specification.new do |s|
|
|
22
22
|
"VERSION",
|
23
23
|
"bin/rfetion",
|
24
24
|
"lib/rfetion.rb",
|
25
|
+
"lib/rfetion/buddy_list.rb",
|
25
26
|
"lib/rfetion/command.rb",
|
26
27
|
"lib/rfetion/contact.rb",
|
27
28
|
"lib/rfetion/fetion.rb",
|
29
|
+
"lib/rfetion/message.rb",
|
28
30
|
"lib/rfetion/sipc_message.rb",
|
29
31
|
"rfetion.gemspec",
|
30
32
|
"spec/rfetion/fetion_spec.rb",
|
data/spec/rfetion/fetion_spec.rb
CHANGED
@@ -124,6 +124,7 @@ EOF
|
|
124
124
|
@fetion.register_second
|
125
125
|
|
126
126
|
@fetion.nickname.should == "flyerhzm"
|
127
|
+
@fetion.buddy_lists.collect {|buddy_list| buddy_list.name}.should == ['我的好友', '好友', '同学']
|
127
128
|
end
|
128
129
|
end
|
129
130
|
end
|
@@ -131,6 +132,8 @@ EOF
|
|
131
132
|
describe "get contacts" do
|
132
133
|
before :each do
|
133
134
|
@fetion.instance_variable_set(:@seq, 5)
|
135
|
+
@fetion.instance_variable_set(:@sid, "730020377")
|
136
|
+
@fetion.instance_variable_set(:@user_id, "390937727")
|
134
137
|
end
|
135
138
|
|
136
139
|
it "should get all contacts" do
|
@@ -227,6 +230,112 @@ EOF
|
|
227
230
|
@fetion.get_contacts
|
228
231
|
@fetion.contacts.collect {|contact| contact.sid}.should == ["793401629", "737769829", "660250260", "926157269", "669700695", "760087520", "480867781", "572512981", "638993408"]
|
229
232
|
end
|
233
|
+
|
234
|
+
it "should get received msg" do
|
235
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=6", :body => "SIPP")
|
236
|
+
response_body =<<-EOF
|
237
|
+
SIP-C/4.0 200 OK
|
238
|
+
I: 3
|
239
|
+
Q: 1 S
|
240
|
+
L: 59
|
241
|
+
|
242
|
+
<results><group-list version ="1" ></group-list></results>SIPP
|
243
|
+
EOF
|
244
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=7", :body => "SIPP")
|
245
|
+
response_body =<<-EOF
|
246
|
+
SIP-C/4.0 200 OK
|
247
|
+
I: 4
|
248
|
+
Q: 1 SUB
|
249
|
+
|
250
|
+
M 730020377 SIP-C/4.0
|
251
|
+
F: sip:480867781@fetion.com.cn;p=16105
|
252
|
+
I: -1
|
253
|
+
C: text/plain
|
254
|
+
Q: 2 M
|
255
|
+
D: Mon, 10 May 2010 14:26:17 GMT
|
256
|
+
L: 12
|
257
|
+
|
258
|
+
testtesttestBN 730020377 SIP-C/4.0
|
259
|
+
N: SystemNotifyV4
|
260
|
+
L: 84
|
261
|
+
I: 1
|
262
|
+
Q: 3 BN
|
263
|
+
|
264
|
+
<events><event type="MobileMailBoxChanged"><mail unread-count="1"/></event></events>BN 730020377 SIP-C/4.0
|
265
|
+
N: PresenceV4
|
266
|
+
I: 1
|
267
|
+
L: 322
|
268
|
+
Q: 4 BN
|
269
|
+
|
270
|
+
<events><event type="PresenceChanged"><contacts><c id="222516658"><p v="0" sid="793401629" su="sip:793401629@fetion.com.cn;p=1919" m="13601804916" c="CMCC" cs="0" s="1" l="0" svc="" n="Peter" i="人生哈哈哈" p="428986348" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
271
|
+
N: PresenceV4
|
272
|
+
I: 1
|
273
|
+
L: 329
|
274
|
+
Q: 5 BN
|
275
|
+
|
276
|
+
<events><event type="PresenceChanged"><contacts><c id="229415466"><p v="0" sid="737769829" su="sip:737769829@fetion.com.cn;p=4078" m="13817731963" c="CMCC" cs="0" s="1" l="8" svc="" n="ice" i="" p="-2000590228" sms="0.0:0:0" sp="0" sh="0"/><pr di="PCCL030516427968" b="400" d="" dt="PC" dc="137"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
277
|
+
N: PresenceV4
|
278
|
+
I: 1
|
279
|
+
L: 303
|
280
|
+
Q: 6 BN
|
281
|
+
|
282
|
+
<events><event type="PresenceChanged"><contacts><c id="228358286"><p v="0" sid="660250260" su="sip:660250260@fetion.com.cn;p=3854" m="13795359343" c="CMCC" cs="0" s="1" l="4" svc="" n="蔡智武" i="" p="0" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
283
|
+
N: PresenceV4
|
284
|
+
I: 1
|
285
|
+
L: 643
|
286
|
+
Q: 7 BN
|
287
|
+
|
288
|
+
<events><event type="PresenceChanged"><contacts><c id="390937727"><p v="0" cs="0" n="flyerhzm" i="http://www.fetionrobot.com" sms="0.0:0:0" sp="0"/></c><c id="665046562"><p v="0" sid="926157269" su="sip:926157269@fetion.com.cn;p=12906" m="" c="CMCC" cs="0" s="1" l="0" svc="" n="黄雅莉" i="" p="0" sms="10099.12:57:24" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c><c id="227091544"><p v="0" sid="669700695" su="sip:669700695@fetion.com.cn;p=3546" m="13764589545" c="CMCC" cs="0" s="1" l="10" svc="" n="郭庆" i="looloo" p="598224859" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
289
|
+
N: PresenceV4
|
290
|
+
I: 1
|
291
|
+
L: 338
|
292
|
+
Q: 8 BN
|
293
|
+
|
294
|
+
<events><event type="PresenceChanged"><contacts><c id="296436724"><p v="0" sid="760087520" su="sip:760087520@fetion.com.cn;p=2467" m="13656681075" c="CMCC" cs="0" s="1" l="5" svc="" n="蒋健" i="TD只需成功,不许失败" p="2074595345" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
295
|
+
N: PresenceV4
|
296
|
+
I: 1
|
297
|
+
L: 291
|
298
|
+
Q: 9 BN
|
299
|
+
|
300
|
+
<events><event type="PresenceChanged"><contacts><c id="732743291"><p v="0" sid="480867781" su="sip:480867781@fetion.com.cn;p=16105" m="" c="" cs="1" s="1" l="0" svc="" n="黄志敏" i="" p="0" sms="365.0:0:0" sp="0" sh="1"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
301
|
+
N: PresenceV4
|
302
|
+
I: 1
|
303
|
+
L: 369
|
304
|
+
Q: 10 BN
|
305
|
+
|
306
|
+
<events><event type="PresenceChanged"><contacts><c id="226911221"><p v="0" sid="572512981" su="sip:572512981@fetion.com.cn;p=3544" m="13764325001" c="CMCC" cs="0" s="1" l="10" svc="" n="陈勇sh" i="http://slide.news.sina.com.cn/c/slide_1_797_11165.html#p=1" p="-98773891" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>BN 730020377 SIP-C/4.0
|
307
|
+
N: PresenceV4
|
308
|
+
I: 1
|
309
|
+
L: 300
|
310
|
+
Q: 11 BN
|
311
|
+
|
312
|
+
<events><event type="PresenceChanged"><contacts><c id="295098062"><p v="0" sid="638993408" su="sip:638993408@fetion.com.cn;p=2242" m="13634102006" c="CMCC" cs="0" s="1" l="0" svc="" n="梦妍" i="" p="0" sms="0.0:0:0" sp="0" sh="0"/><pr di="" b="0" d="" dt="" dc="0"/></c></contacts></event></events>SIPP
|
313
|
+
EOF
|
314
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=8", :body => response_body)
|
315
|
+
response_body =<<-EOF
|
316
|
+
SIP-C/4.0 200 OK
|
317
|
+
I: 5
|
318
|
+
Q: 1 S
|
319
|
+
L: 835
|
320
|
+
|
321
|
+
<results><topic-list event="RecommendGroupTopic" version="171" max-count="5"><topic title="陌上人如玉 韩庚世无双" url="http://group.fetion.com.cn/topic/common/31333572/196313?c=[c:m161.com.cn]" create-date="2010-5-6 15:36:30" id="171" topic-type="1" /><topic title="世博园10大最美景观" url="http://group.fetion.com.cn/topic/common/8249155/196251?c=[c:m161.com.cn]" create-date="2010-5-6 15:33:49" id="170" topic-type="1" /><topic title="诺基亚价值百万的手机" url="http://group.fetion.com.cn/topic/common/7366464/196288?c=[c:m161.com.cn]" create-date="2010-5-6 15:31:57" id="169" topic-type="1" /><topic title="选秀调查:伪娘的真相" url="http://group.fetion.com.cn/topic/common/30660603/196323?c=[c:m161.com.cn]" create-date="2010-5-6 15:22:51" id="168" topic-type="1" /></topic-list></results>SIPP
|
322
|
+
EOF
|
323
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=9", :body => response_body)
|
324
|
+
response_body =<<-EOF
|
325
|
+
SIP-C/4.0 200 OK
|
326
|
+
I: 6
|
327
|
+
Q: 1 S
|
328
|
+
L: 61
|
329
|
+
|
330
|
+
<results><contacts version="326661305" ></contacts></results>SIPP
|
331
|
+
EOF
|
332
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=10", :body => response_body)
|
333
|
+
@fetion.get_contacts
|
334
|
+
@fetion.contacts.collect {|c| c.sid}.should == ["793401629", "737769829", "660250260", "926157269", "669700695", "760087520", "480867781", "572512981", "638993408"]
|
335
|
+
@fetion.receives.collect {|r| r.sip}.should == ["480867781@fetion.com.cn;p=16105"]
|
336
|
+
@fetion.receives.collect {|r| r.sent_at}.should == [Time.parse("Mon, 10 May 2010 14:26:17 GMT")]
|
337
|
+
@fetion.receives.collect {|r| r.text}.should == ["testtesttest"]
|
338
|
+
end
|
230
339
|
end
|
231
340
|
|
232
341
|
describe "send msg" do
|
@@ -353,7 +462,7 @@ Q: 1 S
|
|
353
462
|
SIPP
|
354
463
|
EOF
|
355
464
|
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=13", :body => response_body)
|
356
|
-
lambda {@fetion.get_contact_info(:friend_mobile => '15800681505')}.should raise_exception(Fetion::
|
465
|
+
lambda {@fetion.get_contact_info(:friend_mobile => '15800681505')}.should raise_exception(Fetion::SipcException)
|
357
466
|
end
|
358
467
|
end
|
359
468
|
|
@@ -363,8 +472,54 @@ EOF
|
|
363
472
|
end
|
364
473
|
|
365
474
|
it "should logout" do
|
366
|
-
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=13", :body =>
|
367
|
-
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=14", :body =>
|
475
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=13", :body => "SIPP")
|
476
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=14", :body => "SIPP")
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
describe "keep-alive" do
|
481
|
+
before :each do
|
482
|
+
@fetion.instance_variable_set(:@seq, 10)
|
483
|
+
@fetion.instance_variable_set(:@sid, "730020377")
|
484
|
+
contact = Fetion::Contact.new
|
485
|
+
contact.id = '295098062'
|
486
|
+
@fetion.instance_variable_set(:@contacts, [contact])
|
487
|
+
end
|
488
|
+
|
489
|
+
it "should get presence with online" do
|
490
|
+
response_body =<<-EOF
|
491
|
+
BN 730020377 SIP-C/4.0
|
492
|
+
N: PresenceV4
|
493
|
+
I: 1
|
494
|
+
L: 154
|
495
|
+
Q: 11 BN
|
496
|
+
|
497
|
+
<events><event type="PresenceChanged"><contacts><c id="295098062"><pr di="PCCL030340538483" b="400" d="" dt="PC" dc="17"/></c></contacts></event></events>SIPP
|
498
|
+
EOF
|
499
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => response_body)
|
500
|
+
@fetion.keep_alive
|
501
|
+
@fetion.contacts.find {|contact| contact.id == '295098062'}.status.should == "400"
|
502
|
+
end
|
503
|
+
|
504
|
+
it "should get receive msg" do
|
505
|
+
response_body =<<-EOF
|
506
|
+
M 730020377 SIP-C/4.0
|
507
|
+
I: -17
|
508
|
+
Q: 4 M
|
509
|
+
F: sip:638993408@fetion.com.cn;p=2242
|
510
|
+
C: text/html-fragment
|
511
|
+
K: SaveHistory
|
512
|
+
L: 12
|
513
|
+
D: Tue, 11 May 2010 15:18:56 GMT
|
514
|
+
XI: 7eb8bc4e9df742b2aa557f9e85c8d8af
|
515
|
+
|
516
|
+
testtesttestSIPP
|
517
|
+
EOF
|
518
|
+
FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=11", :body => response_body)
|
519
|
+
@fetion.keep_alive
|
520
|
+
@fetion.receives.collect {|r| r.sip}.should == ["638993408@fetion.com.cn;p=2242"]
|
521
|
+
@fetion.receives.collect {|r| r.sent_at}.should == [Time.parse("Tue, 11 May 2010 15:18:56 GMT")]
|
522
|
+
@fetion.receives.collect {|r| r.text}.should == ["testtesttest"]
|
368
523
|
end
|
369
524
|
end
|
370
525
|
end
|
data/spec/spec.opts
CHANGED
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.
|
4
|
+
version: 0.5.2
|
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-
|
12
|
+
date: 2010-05-15 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -47,9 +47,11 @@ files:
|
|
47
47
|
- VERSION
|
48
48
|
- bin/rfetion
|
49
49
|
- lib/rfetion.rb
|
50
|
+
- lib/rfetion/buddy_list.rb
|
50
51
|
- lib/rfetion/command.rb
|
51
52
|
- lib/rfetion/contact.rb
|
52
53
|
- lib/rfetion/fetion.rb
|
54
|
+
- lib/rfetion/message.rb
|
53
55
|
- lib/rfetion/sipc_message.rb
|
54
56
|
- rfetion.gemspec
|
55
57
|
- spec/rfetion/fetion_spec.rb
|