rfetion 0.5.6 → 0.5.7

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/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: