qplus 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +88 -0
- data/Rakefile +2 -0
- data/bin/qplus +5 -0
- data/lib/qplus.rb +71 -0
- data/lib/qplus/version.rb +3 -0
- data/qplus.gemspec +20 -0
- data/spec/qplus_spec.rb +59 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ken Chen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Qplus
|
2
|
+
|
3
|
+
Qplus 平台第三方应用后端SDK。
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'qplus'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install qplus
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
require 'qplus'
|
23
|
+
|
24
|
+
qplus = Qplus::App.new 'your_app_id', 'your_app_secret'
|
25
|
+
```
|
26
|
+
|
27
|
+
+ check sig
|
28
|
+
|
29
|
+
``` ruby
|
30
|
+
qplus.check_sig url
|
31
|
+
```
|
32
|
+
|
33
|
+
+ check login
|
34
|
+
|
35
|
+
``` ruby
|
36
|
+
user_data = {
|
37
|
+
:app_openid => "your user app_openid here",
|
38
|
+
:app_openkey => "your user app_openkey here",
|
39
|
+
:app_userip => "your user app_userip"
|
40
|
+
}
|
41
|
+
|
42
|
+
result = qplus.check_login user_data
|
43
|
+
|
44
|
+
if result['ret']==0 && result['valide']==1
|
45
|
+
puts 'logined'
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
+ get user info
|
50
|
+
|
51
|
+
``` ruby
|
52
|
+
result = qplus.get_userinfo user_data
|
53
|
+
if result['ret']==0
|
54
|
+
nick = result['info']['nick']
|
55
|
+
gender = result['info']['gender']
|
56
|
+
face = result['info']['face']
|
57
|
+
outh = result['info']['outh']
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
+ push
|
62
|
+
|
63
|
+
``` ruby
|
64
|
+
push_data = {
|
65
|
+
"NUM" => 99,
|
66
|
+
"APPCUSTOMIZE" => "param=你好",
|
67
|
+
"INSTANCEID" => 0,
|
68
|
+
"OPTYPE" => 1,
|
69
|
+
"QPLUSID" => "9989C2EB77FB4217076688D02925CED3",
|
70
|
+
"TEXT" => "你们好吗",
|
71
|
+
"PUSHMSGID" => 1
|
72
|
+
}
|
73
|
+
|
74
|
+
result = qplus.push push_data
|
75
|
+
|
76
|
+
if result['ERRCODE']==0
|
77
|
+
puts 'success'
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
1. Fork it
|
85
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
86
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
87
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
88
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/qplus
ADDED
data/lib/qplus.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "qplus/version"
|
4
|
+
require "net/http"
|
5
|
+
require "open-uri"
|
6
|
+
require "openssl"
|
7
|
+
require "json"
|
8
|
+
|
9
|
+
module Qplus
|
10
|
+
PUSH_URL = "http://tpns.qq.com/cgi-bin/app_push"
|
11
|
+
OPEN_URL = "http://openid.qplus.com/cgi-bin/"
|
12
|
+
|
13
|
+
def self.get_nonce
|
14
|
+
rand 1_000_000_000..9_999_999_999
|
15
|
+
end
|
16
|
+
|
17
|
+
class App
|
18
|
+
|
19
|
+
attr_accessor :app_id, :app_secret, :lang
|
20
|
+
|
21
|
+
def initialize(app_id, app_secret, lang = 2052)
|
22
|
+
@app_id = app_id
|
23
|
+
@app_secret = app_secret + "&"
|
24
|
+
@lang = lang
|
25
|
+
end
|
26
|
+
|
27
|
+
def send_request(action, open_info, options)
|
28
|
+
open_info.update options
|
29
|
+
open_info.update :app_id => @app_id,
|
30
|
+
:app_ts => Time.now.utc.to_i,
|
31
|
+
:app_nonce => Qplus.get_nonce
|
32
|
+
open_info = Hash[open_info.sort]
|
33
|
+
sig = get_sig "#{action}&#{URI.encode_www_form open_info}"
|
34
|
+
open_info.update :sig => sig
|
35
|
+
uri = URI(Qplus::OPEN_URL + action)
|
36
|
+
res = Net::HTTP.post_form(uri, open_info)
|
37
|
+
JSON.parse res.body
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_userinfo(open_info, options = {} )
|
41
|
+
send_request "app_get_userinfo", open_info, options
|
42
|
+
end
|
43
|
+
|
44
|
+
def check_login(open_info, options = {})
|
45
|
+
send_request "app_verify", open_info, options
|
46
|
+
end
|
47
|
+
|
48
|
+
def check_sig(url)
|
49
|
+
data = url[(url.index("?") + 1)..(url.index("&sig") - 1)]
|
50
|
+
sig = url[url.index("&sig=") + "&sig".length + 1, url.length]
|
51
|
+
sig.downcase == get_sig(data)
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_sig(data)
|
55
|
+
OpenSSL::HMAC.hexdigest("sha1", @app_secret, data)
|
56
|
+
end
|
57
|
+
|
58
|
+
def push(data)
|
59
|
+
data.update "APPID" => @app_id,
|
60
|
+
"TIME" => Time.now.utc.to_i,
|
61
|
+
"NONCE" => Qplus.get_nonce
|
62
|
+
data = Hash[data.sort]
|
63
|
+
# don't encode here
|
64
|
+
sig = get_sig "app_push&#{ data.collect { |i| "#{i.first}=#{i.last}" }.join("&") }"
|
65
|
+
params = URI::encode_www_form data
|
66
|
+
push_uri = URI("#{Qplus::PUSH_URL}?#{params}&IDENTIFYSTRING=#{sig}")
|
67
|
+
JSON Net::HTTP.get(push_uri)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/qplus.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/qplus/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["thisiskun"]
|
6
|
+
gem.email = ["chenchaokun@gmail.com"]
|
7
|
+
gem.description = %q{qplus sdk}
|
8
|
+
gem.summary = %q{qplus sdk}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "qplus"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Qplus::VERSION
|
17
|
+
gem.add_runtime_dependency 'json'
|
18
|
+
gem.add_development_dependency 'rake'
|
19
|
+
gem.add_development_dependency 'rspec'
|
20
|
+
end
|
data/spec/qplus_spec.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require "qplus"
|
3
|
+
|
4
|
+
describe Qplus do
|
5
|
+
describe "App" do
|
6
|
+
let(:q) { Qplus::App.new 200072992, "mVXsNvg0AzLk6mb6" }
|
7
|
+
let(:data) { {
|
8
|
+
:app_openid => "B587BF2B65C9A46EFC0D4CE150AF390C",
|
9
|
+
:app_openkey => "7F8C45941EA5CC54EC2A8663A4F194C8",
|
10
|
+
:app_userip => "127.0.0.1"
|
11
|
+
} }
|
12
|
+
let(:url) { "http://app.beva.com/qplus/kids?app_id=200072992&app_lang=2052&app_nonce=1969946501&app_openid=B587BF2B65C9A46EFC0D4CE150AF390C&app_openkey=7F8C45941EA5CC54EC2A8663A4F194C8&app_ts=1337848736&pf=qplus&sig=B6FC3D92A48FD2EAC9DEED00E81D486E47678E7B" }
|
13
|
+
let(:sig) { "B6FC3D92A48FD2EAC9DEED00E81D486E47678E7B" }
|
14
|
+
let(:params) { "app_id=200072992&app_lang=2052&app_nonce=1969946501&app_openid=B587BF2B65C9A46EFC0D4CE150AF390C&app_openkey=7F8C45941EA5CC54EC2A8663A4F194C8&app_ts=1337848736&pf=qplus" }
|
15
|
+
let(:user_data) { {
|
16
|
+
:app_openid => "B587BF2B65C9A46EFC0D4CE150AF390C",
|
17
|
+
:app_openkey => "571336875C824D425CC956AE670CC796",
|
18
|
+
:app_userip => "127.0.0.1"
|
19
|
+
} }
|
20
|
+
let(:push_data) { {
|
21
|
+
"NUM" => 99,
|
22
|
+
"APPCUSTOMIZE" => "param=你好",
|
23
|
+
"INSTANCEID" => 0,
|
24
|
+
"OPTYPE" => 1,
|
25
|
+
"QPLUSID" => "9989C2EB77FB4217076688D02925CED3",
|
26
|
+
"TEXT" => "你们好吗",
|
27
|
+
"PUSHMSGID" => 1
|
28
|
+
} }
|
29
|
+
|
30
|
+
it "should have the right sig" do
|
31
|
+
q.get_sig(params).should == sig.downcase
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "User login status" do
|
35
|
+
it "should return ret 0" do
|
36
|
+
q.check_login(user_data)['ret'].should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return validate 1" do
|
40
|
+
q.check_login(user_data)['valide'].should == 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "User info" do
|
45
|
+
it "should return ret 0" do
|
46
|
+
q.get_userinfo(user_data)['ret'].should == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should return the right nick name" do
|
50
|
+
q.get_userinfo(user_data)['info']['nick'].should == "春天原野小熊"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "push returns success" do
|
55
|
+
q.push(push_data)['ERRCODE'].should == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qplus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- thisiskun
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: qplus sdk
|
63
|
+
email:
|
64
|
+
- chenchaokun@gmail.com
|
65
|
+
executables:
|
66
|
+
- qplus
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- bin/qplus
|
76
|
+
- lib/qplus.rb
|
77
|
+
- lib/qplus/version.rb
|
78
|
+
- qplus.gemspec
|
79
|
+
- spec/qplus_spec.rb
|
80
|
+
homepage: ''
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
hash: -522089631
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
hash: -522089631
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 1.8.24
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: qplus sdk
|
110
|
+
test_files:
|
111
|
+
- spec/qplus_spec.rb
|