rfetion 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.1
1
+ 0.5.2
@@ -0,0 +1,14 @@
1
+ class Fetion
2
+ class BuddyList
3
+ attr_reader :id, :name
4
+
5
+ def initialize(id, name)
6
+ @id = id
7
+ @name = name
8
+ end
9
+
10
+ def self.parse(buddy_list)
11
+ self.new(buddy_list['id'], buddy_list['name'])
12
+ end
13
+ end
14
+ end
@@ -1,11 +1,25 @@
1
- class Contact
2
- attr_reader :sid, :uri, :mobile_no, :nickname, :impresa, :nickname
1
+ class Fetion
2
+ class Contact
3
+ attr_accessor :id, :sid, :uri, :mobile_no, :nickname, :impresa, :nickname, :status
3
4
 
4
- def initialize(attrs)
5
- @sid = attrs["sid"]
6
- @uri = attrs["su"]
7
- @mobile_no = attrs["m"]
8
- @nickname = attrs["n"]
9
- @impresa = attrs["i"]
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
@@ -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
- response = pulse
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
- response = pulse
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
- response = curl_exec(SipcMessage.presence(self))
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
- response = pulse
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
- response = pulse
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
- response = pulse
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
- response = pulse
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
- response = pulse
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
- response = pulse
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
- @logger.debug "nickname: #@nickname"
360
- @logger.debug "buddies: #{@buddies.inspect}"
313
+ def pulse(expected=SipcMessage::OK)
314
+ curl_exec(SIPP, next_url, expected)
361
315
  end
362
316
 
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|
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
@@ -0,0 +1,11 @@
1
+ class Fetion
2
+ class Message
3
+ attr_reader :sip, :sent_at, :text
4
+
5
+ def initialize(sip, sent_at, text)
6
+ @sip = sip
7
+ @sent_at = sent_at
8
+ @text = text
9
+ end
10
+ end
11
+ end
@@ -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
- # command one of 'R', 'S'
62
- # with_l display L or not
63
- # body sipc body
64
- def self.sipc_create(options)
65
- options = {:body => '', :with_l => true}.merge(options)
66
- body = options.delete(:body)
67
- with_l = options.delete(:with_l)
68
-
69
- sorted_key = [:F, :I, :Q, :CN, :CL, :A, :AK, :X, :T, :K, :N, :SV]
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, :message
75
+ attr_reader :code, :description
86
76
 
87
- def initialize(code, message)
77
+ def initialize(code, description)
88
78
  @code = code
89
- @message = message
79
+ @description = description
90
80
  end
91
81
 
92
82
  def to_s
93
- "#@code #@message"
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.1"
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-10}
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",
@@ -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::NoUserException)
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
@@ -4,5 +4,6 @@ specdoc
4
4
  --reverse
5
5
  --timeout
6
6
  20
7
+ --backtrace
7
8
  --loadby
8
9
  mtime
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.1
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-10 00:00:00 -06:00
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