rfetion 0.5.6 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -29,8 +29,10 @@ Jeweler::Tasks.new do |gemspec|
29
29
  gemspec.homepage = 'http://github.com/flyerhzm/rfetion'
30
30
  gemspec.authors = ['Richard Huang']
31
31
  gemspec.files.exclude '.gitignore'
32
- gemspec.add_dependency 'guid', '>= 0.1.1'
32
+ gemspec.add_dependency 'guid'
33
33
  gemspec.add_dependency 'nokogiri'
34
+ gemspec.add_dependency 'json'
35
+ gemspec.add_dependency 'macaddr'
34
36
  gemspec.executables << 'rfetion'
35
37
  end
36
38
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.6
1
+ 0.5.7
@@ -8,8 +8,8 @@ class Fetion
8
8
  @contacts = []
9
9
  end
10
10
 
11
- def to_json
12
- {:bid => @bid, :name => @name, :contacts => @contacts}.to_json
11
+ def to_json(*args)
12
+ {:bid => @bid, :name => @name, :contacts => @contacts, :total_contacts => total_contacts_count, :online_contacts => online_contacts_count}.to_json(*args)
13
13
  end
14
14
 
15
15
  def self.parse(buddy_list)
@@ -10,8 +10,8 @@ class Fetion
10
10
  "0" => "脱机"
11
11
  }
12
12
 
13
- def to_json
14
- {:uid => @uid, :sid => @sid, :bid => @bid, :uri => @uri, :mobile_no => @mobile_no, :nickname => @nickname, :impresa => @impresa, :status => @status}.to_json
13
+ def to_json(*args)
14
+ {:uid => @uid, :sid => @sid, :bid => @bid, :uri => @uri, :mobile_no => @mobile_no, :nickname => @nickname, :impresa => @impresa, :status => @status, :display => display}.to_json(*args)
15
15
  end
16
16
 
17
17
  def self.parse_buddy(b)
@@ -28,18 +28,19 @@ class Fetion
28
28
  end
29
29
 
30
30
  def initialize(options={})
31
+ @status = "0"
31
32
  options.each do |key, value|
32
33
  send("#{key}=", value)
33
34
  end
34
35
  end
35
36
 
36
- def update(p)
37
+ def update(p, pr)
37
38
  self.sid = p["sid"] if p["sid"] and !p["sid"].empty?
38
39
  self.uri = p["su"] if p["su"] and !p["su"].empty?
39
40
  self.mobile_no = p["m"] if p["m"] and !p["m"].empty?
40
41
  self.nickname = p["n"] if p["n"] and !p["n"].empty?
41
42
  self.impresa = p["i"] if p["i"] and !p["i"].empty?
42
- self.status = p["b"] if p["b"] and !p["b"].empty?
43
+ self.status = pr["b"] if pr["b"] and !pr["b"].empty?
43
44
  end
44
45
 
45
46
  def display
@@ -1,15 +1,18 @@
1
+ #coding: utf-8
1
2
  require 'guid'
2
3
  require 'time'
3
4
  require 'net/http'
4
5
  require 'net/https'
5
6
  require 'nokogiri'
6
7
  require 'digest/sha1'
8
+ require 'digest/md5'
9
+ require 'macaddr'
7
10
  require 'openssl'
8
11
  require 'logger'
9
12
  require 'json'
10
13
 
11
14
  class Fetion
12
- attr_accessor :mobile_no, :sid, :password, :call, :seq, :alive, :ssic, :guid, :uri
15
+ attr_accessor :mobile_no, :sid, :password, :call, :seq, :alive, :ssic, :guid, :uri, :pid, :pic, :algorithm, :machine_code
13
16
  attr_reader :uid, :buddy_lists, :add_requests, :response, :nickname, :impresa, :receives
14
17
 
15
18
  FETION_URL = 'http://221.176.31.39/ht/sd.aspx'
@@ -32,8 +35,8 @@ class Fetion
32
35
  @guid = Guid.new.to_s
33
36
  end
34
37
 
35
- def to_json
36
- {:mobile_no => @mobile_no, :sid => @sid, :uid => @uid, :uri => @uri, :status_code => @status_code, :buddy_lists => @buddy_lists, :receives => @receives, :add_requests => @add_requests, :nickname => @nickname, :impresa => @impresa, :ssic => @ssic, :guid => @guid, :call => @call, :seq => @seq, :alive => @alive}.to_json
38
+ def to_json(*args)
39
+ {:mobile_no => @mobile_no, :sid => @sid, :uid => @uid, :uri => @uri, :status_code => @status_code, :buddy_lists => @buddy_lists, :receives => @receives, :add_requests => @add_requests, :nickname => @nickname, :impresa => @impresa, :ssic => @ssic, :guid => @guid, :call => @call, :seq => @seq, :alive => @alive}.to_json(*args)
37
40
  end
38
41
 
39
42
  def logger_level=(level)
@@ -169,7 +172,9 @@ class Fetion
169
172
  else
170
173
  url = FETION_LOGIN_URL.sub('%sid%', @sid).sub('mobileno=%mobileno%', '')
171
174
  end
172
- uri = URI.parse(url.sub('%digest%', Digest::SHA1.hexdigest("#{DOMAIN}:#{@password}")))
175
+ url.sub!('%digest%', Digest::SHA1.hexdigest("#{DOMAIN}:#{@password}"))
176
+ url += "&pid=#@pid&pic=#@pic&algorithm=#@algorithm" if @pic
177
+ uri = URI.parse(url)
173
178
  http = Net::HTTP.new(uri.host, uri.port)
174
179
  http.use_ssl = true
175
180
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@@ -204,7 +209,6 @@ class Fetion
204
209
  def register_second
205
210
  @logger.debug "fetion register second"
206
211
 
207
- body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{@mobile_no}" user-id="#{@uid}"><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>|
208
212
  curl_exec(SipcMessage.register_second(self))
209
213
  pulse
210
214
 
@@ -369,17 +373,17 @@ class Fetion
369
373
  http = Net::HTTP.new(uri.host, uri.port)
370
374
  headers = {'User-Agent' => USER_AGENT}
371
375
  response = http.request_get(uri.request_uri, headers)
372
- pic_certificate = parse_pic_certificate(response)
376
+ pic_certificate = parse_pic_certificate(response, algorithm)
373
377
 
374
378
  @logger.info "fetion get pic success"
375
379
  pic_certificate
376
380
  end
377
381
 
378
382
  def parse_ssic(response)
379
- raise Fetion::PasswordError.new('Fetion Error: 帐号或密码不正确') if Net::HTTPUnauthorized === response
380
- raise Fetion::PasswordMaxError.new('Fetion Error: 您已连续输入错误密码,为了保障您的帐户安全,请输入图形验证码:') if Net::HTTPClientError === response
381
- raise Fetion::LoginException.new('Fetion Error: Login failed.') unless Net::HTTPSuccess === response
382
- raise Fetion::LoginException.new('Fetion Error: No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
383
+ raise Fetion::PasswordError.new('帐号或密码不正确') if Net::HTTPUnauthorized === response
384
+ raise Fetion::PasswordMaxError.new('您已连续输入错误密码,为了保障您的帐户安全,请输入图形验证码:') if Net::HTTPClientError === response
385
+ raise Fetion::LoginException.new('Login failed.') unless Net::HTTPSuccess === response
386
+ raise Fetion::LoginException.new('No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
383
387
 
384
388
  @ssic = $1
385
389
  @logger.debug response.body
@@ -404,11 +408,11 @@ class Fetion
404
408
  @logger.debug "sid: " + @sid
405
409
  end
406
410
 
407
- def parse_pic_certificate(response)
408
- raise FetionException.new('Fetion Error: Get verification code failed.') unless Net::HTTPSuccess === response
411
+ def parse_pic_certificate(response, algorithm)
412
+ raise FetionException.new('Get verification code failed.') unless Net::HTTPSuccess === response
409
413
  doc = Nokogiri::XML(response.body)
410
414
  certificate = doc.root.xpath('/results/pic-certificate').first
411
- PicCertificate.parse(certificate)
415
+ PicCertificate.parse(certificate, algorithm)
412
416
  end
413
417
 
414
418
  def curl_exec(body='', url=next_url, expected=SipcMessage::OK)
@@ -433,7 +437,7 @@ class Fetion
433
437
 
434
438
  if sipc_response.first_line =~ /401/
435
439
  # unauthorized, get nonce, key and signature
436
- raise Fetion::NoNonceException.new("Fetion Error: No nonce found") unless response.body =~ /nonce="(.*?)",key="(.*?)",signature="(.*?)"/
440
+ raise Fetion::NoNonceException.new("No nonce found") unless response.body =~ /nonce="(.*?)",key="(.*?)",signature="(.*?)"/
437
441
  @nonce = $1
438
442
  @key = $2
439
443
  @signature = $3
@@ -485,7 +489,7 @@ class Fetion
485
489
  unless self.uid == c['id']
486
490
  contact = contacts.find {|contact| contact.uid == c['id']}
487
491
  if contact
488
- contact.update(c.children.first)
492
+ contact.update(c.children.first, c.children.last)
489
493
  else
490
494
  contact = Fetion::Contact.parse(c)
491
495
  if @buddy_lists.size > 1
@@ -532,6 +536,10 @@ class Fetion
532
536
 
533
537
  rsa_key.public_encrypt(str).unpack("H*").first.upcase
534
538
  end
539
+
540
+ def machine_code
541
+ @machine_code ||= Digest::MD5.hexdigest(Mac.addr)
542
+ end
535
543
 
536
544
  def self?(mobile_or_sid)
537
545
  mobile_or_sid == @mobile_no or mobile_or_sid == @sid
@@ -1,12 +1,17 @@
1
1
  class PicCertificate
2
- attr_reader :id, :pic
2
+ attr_reader :pid, :pic, :algorithm
3
3
 
4
- def initialize(id, pic)
5
- @id = id
4
+ def initialize(pid, pic, algorithm)
5
+ @pid = pid
6
6
  @pic = pic
7
+ @algorithm = algorithm
7
8
  end
8
9
 
9
- def self.parse(c)
10
- PicCertificate.new(c['id'], c['pic'])
10
+ def self.parse(c, algorithm)
11
+ PicCertificate.new(c['id'], c['pic'], algorithm)
12
+ end
13
+
14
+ def to_json(*args)
15
+ {:pid => @pid, :pic => @pic, :algorithm => @algorithm}
11
16
  end
12
17
  end
@@ -6,7 +6,7 @@ class SipcMessage
6
6
  end
7
7
 
8
8
  def self.register_second(fetion)
9
- body = %Q|<args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{fetion.mobile_no}" user-id="#{fetion.uid}"><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>|
9
+ body = %Q|<args><device machine-code="#{fetion.machine_code}" /><caps value="ff" /><events value="7f" /><user-info mobile-no="#{fetion.mobile_no}" user-id="#{fetion.uid}"><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>|
10
10
  sipc_create(:command => 'R', :F => fetion.sid, :I => 1, :Q => "#{fetion.next_alive} R", :A => %Q|Digest response="#{fetion.response}",algorithm="SHA1-sess-v4"|, :AK => 'ak-value', :body => body)
11
11
  end
12
12
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rfetion}
8
- s.version = "0.5.6"
8
+ s.version = "0.5.7"
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-24}
12
+ s.date = %q{2010-05-29}
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"]
@@ -53,15 +53,21 @@ Gem::Specification.new do |s|
53
53
  s.specification_version = 3
54
54
 
55
55
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
- s.add_runtime_dependency(%q<guid>, [">= 0.1.1"])
56
+ s.add_runtime_dependency(%q<guid>, [">= 0"])
57
57
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
58
+ s.add_runtime_dependency(%q<json>, [">= 0"])
59
+ s.add_runtime_dependency(%q<macaddr>, [">= 0"])
58
60
  else
59
- s.add_dependency(%q<guid>, [">= 0.1.1"])
61
+ s.add_dependency(%q<guid>, [">= 0"])
60
62
  s.add_dependency(%q<nokogiri>, [">= 0"])
63
+ s.add_dependency(%q<json>, [">= 0"])
64
+ s.add_dependency(%q<macaddr>, [">= 0"])
61
65
  end
62
66
  else
63
- s.add_dependency(%q<guid>, [">= 0.1.1"])
67
+ s.add_dependency(%q<guid>, [">= 0"])
64
68
  s.add_dependency(%q<nokogiri>, [">= 0"])
69
+ s.add_dependency(%q<json>, [">= 0"])
70
+ s.add_dependency(%q<macaddr>, [">= 0"])
65
71
  end
66
72
  end
67
73
 
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
2
 
3
3
  describe Fetion::BuddyList do
4
4
  before :each do
5
- @buddy_list = Fetion::BuddyList.new("1", "我的好友")
5
+ @buddy_list = Fetion::BuddyList.new("1", "My friend")
6
6
  @buddy_list.add_contact(Fetion::Contact.new(:uid => "226911221", :uri => "sip:572512981@fetion.com.cn;p=3544", :bid => "1", :status => "400"))
7
7
  @buddy_list.add_contact(Fetion::Contact.new(:uid => "295098062", :uri => "sip:638993408@fetion.com.cn;p=2242", :bid => "1"))
8
8
  @buddy_list.add_contact(Fetion::Contact.new(:uid => "579113578", :uri => "sip:838271744@fetion.com.cn;p=4805", :bid => "1"))
@@ -19,4 +19,13 @@ describe Fetion::BuddyList do
19
19
  it "should get online contacts count" do
20
20
  @buddy_list.online_contacts_count.should == 3
21
21
  end
22
+
23
+ it "should to_json" do
24
+ buddy_list_json = @buddy_list.to_json
25
+ p buddy_list_json
26
+ buddy_list_json.should be_include %Q|"bid":"1"|
27
+ buddy_list_json.should be_include %Q|"name":"My friend"|
28
+ buddy_list_json.should be_include %Q|"total_contacts":7|
29
+ buddy_list_json.should be_include %Q|"online_contacts":3|
30
+ end
22
31
  end
@@ -312,6 +312,7 @@ EOF
312
312
  FakeWeb.register_uri(:post, "http://221.176.31.39/ht/sd.aspx?t=s&i=10", :body => response_body)
313
313
  @fetion.get_contacts
314
314
  @fetion.contacts.collect {|contact| contact.sid}.should == ["572512981", "638993408", nil, "926157269", nil, nil, "480867781", "793401629", "669700695", "660250260", "737769829", "760087520"]
315
+ @fetion.contacts.collect {|contact| contact.status}.should == ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "400", "0"]
315
316
  end
316
317
 
317
318
  it "should get received msg while get contacts" do
@@ -832,9 +833,10 @@ EOF
832
833
  EOF
833
834
  FakeWeb.register_uri(:get, "http://nav.fetion.com.cn/nav/GetPicCodeV4.aspx?algorithm=picc-PasswordErrorMax", :body => response_body)
834
835
  actual_pic = @fetion.get_pic_certificate("picc-PasswordErrorMax")
835
- expected_pic = PicCertificate.parse(Nokogiri::XML(response_body).root.xpath('/results/pic-certificate').first)
836
- actual_pic.id.should == expected_pic.id
836
+ expected_pic = PicCertificate.parse(Nokogiri::XML(response_body).root.xpath('/results/pic-certificate').first, 'picc-PasswordErrorMax')
837
+ actual_pic.pid.should == expected_pic.pid
837
838
  actual_pic.pic.should == expected_pic.pic
839
+ actual_pic.algorithm.should == expected_pic.algorithm
838
840
  end
839
841
  end
840
842
  end
@@ -48,6 +48,7 @@ L: 447
48
48
  <args><device machine-code="B04B5DA2F5F1B8D01A76C0EBC841414C" /><caps value="ff" /><events value="7f" /><user-info mobile-no="15800681509" user-id="390937727"><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>SIPP
49
49
  EOF
50
50
  sipc_message.gsub!("\n", "\r\n").chomp!
51
+ @fetion.machine_code = "B04B5DA2F5F1B8D01A76C0EBC841414C"
51
52
  SipcMessage.register_second(@fetion).should == sipc_message
52
53
  end
53
54
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 6
9
- version: 0.5.6
8
+ - 7
9
+ version: 0.5.7
10
10
  platform: ruby
11
11
  authors:
12
12
  - Richard Huang
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-24 00:00:00 +08:00
17
+ date: 2010-05-29 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -26,9 +26,7 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
28
  - 0
29
- - 1
30
- - 1
31
- version: 0.1.1
29
+ version: "0"
32
30
  type: :runtime
33
31
  version_requirements: *id001
34
32
  - !ruby/object:Gem::Dependency
@@ -43,6 +41,30 @@ dependencies:
43
41
  version: "0"
44
42
  type: :runtime
45
43
  version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: json
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id003
56
+ - !ruby/object:Gem::Dependency
57
+ name: macaddr
58
+ prerelease: false
59
+ requirement: &id004 !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ type: :runtime
67
+ version_requirements: *id004
46
68
  description: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
47
69
  email: flyerhzm@gmail.com
48
70
  executables: