polar-renren 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,71 @@
1
+ Polar
2
+ ===================
3
+
4
+ ### About
5
+ Polar is an API wrapper for the Renren social network. This gem is a fork of the renren-api gem. Thanks to Lei Zhi-Qiang for the great work on the renren-api gem. This fork does a number of things differently such as using faraday under the hood and always returning domain objects in preference to hashes.
6
+
7
+ ### Installation
8
+ Polar is a cool name(excuse the pun) but it was already taken on ruby gems so you will have to install polar with the following line in your Gemfile.
9
+
10
+ ```ruby
11
+ gem "polar-renren", :require => "polar"
12
+ ```
13
+
14
+ Not using bundler? Well you should but thats cool.
15
+
16
+ ```ruby
17
+ gem intsall polar-renren
18
+ #then in your code
19
+ require 'polar'
20
+ ```
21
+
22
+ ### Useage
23
+ In polar you use the client object to interact with the api. To create the client you will need to know three different things. Firstly you will need an application key and an application secret. To get these you will need to visit the renren developer site and create an application. Once you have created the application you can go in to the applications control panel and grab the secret and key. As well as these you will need a session key. To get a session key you must login first. This can be done with OAuth2 as renren provides this feature. There is an omni-auth stragity that exists provided by Scott Ballantyne that works well.
24
+
25
+ ```ruby
26
+ client = Polar::Client.new(app_key, app_secret, session_key)
27
+ ```
28
+ Now that we have a client object we can query the renren api. To get all friends call the friends method of the client object.
29
+ ```ruby
30
+ friends = client.get_friends
31
+ ```
32
+ Get friends will return an array of ```Polar::User``` objects. These objects have their data bound to dot methods so we can get information from them as follows
33
+ ```ruby
34
+ friends.each do |friend|
35
+ puts friend.name
36
+ end
37
+ ```
38
+
39
+ Renren's API for some end points will simply return a result = 1 when the operation is successful. Set status is one such endpoint. In this case if the API call does not raise an error then Polar will return an object of class ```Polar::Result```. This object will have success = true.
40
+
41
+ ```ruby
42
+ client = Polar::Client.new(app_key, app_secret, session_key)
43
+ result = client.set_status("Hey welcome to renren.")
44
+ if(result.success)
45
+ puts "woo hoo. The gem works"
46
+ else
47
+ puts "Gem dead. Give up"
48
+ end
49
+ ```
50
+
51
+ Polar also supports cursors to iterate over pages of results. Next page returns true while there is a new set of results to iterate over.
52
+ ```ruby
53
+ client = Polar::Client.new(app_key, app_secret, session_key)
54
+ cursor = client.get_friends
55
+ while cursor.next_page?
56
+ cursor.each do |user|
57
+ puts user.name
58
+ end
59
+ end
60
+ ```
61
+
62
+ ### Pull Requests
63
+ The changes are that what you want to do with the API is not supported. Let me know if that is the case and I will add support for anything you need to do. I will also accept any pull requests with new features included.
64
+
65
+ License
66
+ ===================
67
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
68
+
69
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
70
+
71
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/polar.rb ADDED
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'polar/signature_calculator'
4
+ require 'polar/authentication'
5
+ require 'polar/request'
6
+ require 'polar/base'
7
+ require 'polar/user'
8
+ require 'polar/client'
9
+ require 'polar/cursor'
10
+ require 'polar/response'
11
+ require 'polar/error/http_error'
12
+ require 'polar/error/api_error'
13
+
14
+ module Polar
15
+ BASE_URL = "http://api.renren.com/restserver.do"
16
+ VERSION = [0, 0, 1]
17
+
18
+ def self.version
19
+ VERSION * "."
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require "rack"
2
+ require_relative "signature_calculator"
3
+
4
+ module Polar
5
+ class Authentication
6
+
7
+ def initialize(app, api_key, secret_key, &failed_handler)
8
+ @app = app
9
+ @api_key = api_key
10
+ @secret_key = secret_key
11
+ @signature_calculator = SignatureCalculator.new(@secret_key)
12
+ @required_keys = %w{user session_key ss expires}.collect { |e| @api_key + "_" + e } << @api_key
13
+ @failed_handler = block_given? ? failed_handler : proc { [401, {"Content-Type" => "text/plain"}, ["Unauthorized!"]] }
14
+ end
15
+
16
+ def call(env)
17
+ request = Rack::Request.new(env)
18
+ if %r{^/people/(?<person_id>\d+)} =~ request.path_info
19
+ cookies = request.cookies
20
+ if valid?(cookies) && cookies["#{@api_key}_user"] == person_id
21
+ @app.call(env)
22
+ else
23
+ @failed_handler.call(env)
24
+ end
25
+ else
26
+ @app.call(env)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def valid?(cookies)
33
+ @required_keys.each do |k|
34
+ return false unless cookies.has_key?(k)
35
+ end
36
+ return false if cookies["#{@api_key}_expires"].to_i < Time.now.to_i
37
+ cookies[@api_key] == @signature_calculator.calculate(filter(cookies))
38
+ end
39
+
40
+ def filter(cookies)
41
+ hash = {}
42
+ %w{user session_key ss expires}.each { |e| hash[e] = cookies["#{@api_key}_#{e}"] }
43
+ hash
44
+ end
45
+
46
+ end
47
+ end
data/lib/polar/base.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Polar
2
+ class Base
3
+
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+
8
+ def method_missing(method_name, *attrs)
9
+ if @data.has_key?(method_name.to_s)
10
+ return @data[method_name.to_s]
11
+ else
12
+ raise("No data for: #{method_name}")
13
+ end
14
+ end
15
+
16
+ def to_h
17
+ @data
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,55 @@
1
+ module Polar
2
+ class Client
3
+
4
+ def initialize(api_key, secret_key, session_key)
5
+ @api_key, @secret_key, @session_key = api_key, secret_key, session_key
6
+ end
7
+
8
+ def get_friends
9
+ params = {
10
+ :method => "friends.getFriends",
11
+ :v => "1.0"
12
+ }
13
+
14
+ Polar::Cursor.new(@api_key, @secret_key, @session_key, Polar::User, params)
15
+ end
16
+
17
+ def get_info(uids, fields)
18
+ params = {
19
+ :method => "users.getInfo",
20
+ :v => "1.0",
21
+ :fields => fields * ",",
22
+ :uids => uids * ","
23
+ }
24
+
25
+ user_info = request(params)
26
+ if user_info.count == 1
27
+ return Polar::User.new(user_info.first)
28
+ else
29
+ friend_list = []
30
+ user_info.each { |current_user| friend_list << Polar::User.new(current_user) }
31
+ return friend_list
32
+ end
33
+ end
34
+
35
+ def set_status(status)
36
+ params = {
37
+ :method => "status.set",
38
+ :v => "1.0",
39
+ :status => status
40
+ }
41
+ Polar::Response.new request(params)
42
+ end
43
+
44
+ private
45
+
46
+ def request(params)
47
+ Polar::Request.new(@api_key, @secret_key, @session_key, params).response
48
+ end
49
+
50
+ def current_time_in_milliseconds
51
+ "%.3f" % Time.now.to_f
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ module Polar
2
+ class Cursor
3
+ include Enumerable
4
+ ITEMS_PER_PAGE = 500
5
+
6
+ def initialize(api_key, secret_key, session_key, domain_klass, params)
7
+ @api_key, @secret_key, @session_key, @domain_klass, @params = api_key, secret_key, session_key, domain_klass, params
8
+ @current_page = 0
9
+ @fetched_current_page = false
10
+ end
11
+
12
+ #Each will return the first page of results
13
+ def each(&block)
14
+ @current_page += 1
15
+ fetch_current_page if !@fetched_current_page
16
+ @items.each { |i| block.call i }
17
+ @fetched_current_page = false
18
+ end
19
+
20
+ def next_page?
21
+ if @items
22
+ return @items.count <= ITEMS_PER_PAGE
23
+ elsif !@items && @current_page == 0
24
+ return true
25
+ else
26
+ raise("Items are nil and they should not be.")
27
+ end
28
+ end
29
+
30
+ def total_items
31
+ fetch_current_page if @total_items.nil?
32
+ @total_items
33
+ end
34
+
35
+ def [](index)
36
+ fetch_current_page if !@fetched_current_page
37
+ @items[index]
38
+ end
39
+
40
+ private
41
+
42
+ def page_request(params)
43
+ request = Polar::Request.new(@api_key, @secret_key, @session_key, params)
44
+ request.response
45
+ end
46
+
47
+ def fetch_current_page
48
+ params = @params.merge({ :page => @current_page, :count => ITEMS_PER_PAGE })
49
+ response = page_request(params)
50
+
51
+ @items = []
52
+ response.each do |response_item|
53
+ @items << @domain_klass.new(response_item)
54
+ end
55
+ @fetched_current_page = true
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ module RenrenAPI
2
+ module Error
3
+ class APIError < StandardError
4
+
5
+ def initialize(error_response)
6
+ @code, @message = error_response["error_code"], error_response["error_msg"]
7
+ end
8
+
9
+ def to_s
10
+ "The Renren API has returned an Error:(#{@code} - #{@message})"
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ module RenrenAPI
2
+ module Error
3
+ class HTTPError < StandardError
4
+ def initialize(status)
5
+ @status = status
6
+ super(to_s)
7
+ end
8
+
9
+ def to_s
10
+ "HTTP Error - the request returnd:(#{@status})"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+ require "json"
3
+ require "faraday"
4
+ require "faraday_middleware"
5
+
6
+ module Polar
7
+ class Request
8
+
9
+ attr_reader :response
10
+
11
+ def initialize(api_key, secret_key, session_key, params)
12
+ @api_key, @session_key, @secret_key = api_key, session_key, secret_key
13
+
14
+ conn = Faraday.new(:url => Polar::BASE_URL) do |c|
15
+ c.use Faraday::Request::UrlEncoded
16
+ c.use Faraday::Adapter::NetHttp
17
+ end
18
+
19
+ conn.headers["Content-Type"] = ["application/x-www-form-urlencoded"];
20
+ params[:api_key] = @api_key
21
+ params[:call_id] = Time.now.to_i
22
+ params[:session_key] = @session_key
23
+ params[:format] = "JSON"
24
+ params[:sig] = SignatureCalculator.new(@secret_key).calculate(params)
25
+
26
+ raw_response = conn.post do |request|
27
+ request.body = urlencode_params(params)
28
+ end
29
+
30
+ raise RenrenAPI::Error::HTTPError.new(raw_response.status) if (400..599).include?(raw_response.status)
31
+ @response = JSON.parse(raw_response.body)
32
+ raise RenrenAPI::Error::APIError.new(@response) if renren_api_error?
33
+ end
34
+
35
+ private
36
+
37
+ def urlencode_params(params_hash)
38
+ params = ''
39
+ stack = []
40
+
41
+ params_hash.each do |k, v|
42
+ if v.is_a?(Hash)
43
+ stack << [k,v]
44
+ else
45
+ params << "#{k}=#{v}&"
46
+ end
47
+ end
48
+
49
+ stack.each do |parent, hash|
50
+ hash.each do |k, v|
51
+ if v.is_a?(Hash)
52
+ stack << ["#{parent}[#{k}]", v]
53
+ else
54
+ params << "#{parent}[#{k}]=#{v}&"
55
+ end
56
+ end
57
+ end
58
+
59
+ params.chop! # trailing &
60
+ params
61
+ end
62
+
63
+ def renren_api_error?
64
+ return false if @response.class == Array
65
+ @response.has_key?("error_code") && @response.has_key?("error_msg")
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ module Polar
2
+ class Response < Polar::Base
3
+ def initialize(data)
4
+ super(data)
5
+ end
6
+
7
+ def success
8
+ @data["result"] == 1
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require "digest/md5"
2
+
3
+ module Polar
4
+ class SignatureCalculator
5
+
6
+ def initialize(secret_key)
7
+ @secret_key = secret_key
8
+ end
9
+
10
+ def calculate(hash)
11
+ Digest::MD5.hexdigest(hash.collect { |(k, v)| "#{k}=#{v}" }.sort * "" << @secret_key)
12
+ end
13
+
14
+ end
15
+ end
data/lib/polar/user.rb ADDED
@@ -0,0 +1,15 @@
1
+ module Polar
2
+ class User < Polar::Base
3
+ def initialize(data)
4
+ super(data)
5
+ end
6
+
7
+ def avatar
8
+ tinyurl
9
+ end
10
+
11
+ def to_h
12
+ @data.merge({ "avatar" => @data["tinyurl"]})
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,169 @@
1
+ require "spec_helper"
2
+
3
+ class Rack::MockResponse
4
+ def unauthorized?
5
+ @status == 401
6
+ end
7
+ end
8
+
9
+ describe Polar::Authentication do
10
+ include Rack::Test::Methods
11
+ include Helpers
12
+
13
+ def app
14
+ Polar::Authentication.new(lambda { |env| [200, {}, ["OK"]] }, "8802f8e9b2cf4eb993e8c8adb1e02b06", "34d3d1e26cd44c05a0c450c0a0f8147b") do |env|
15
+ [401, {}, ["Get out of #{env["PATH_INFO"]}!"]]
16
+ end
17
+ end
18
+
19
+ subject { request(path, @env); last_response }
20
+ before { @env = {} }
21
+
22
+ context "when path does not have prefix /people/{person-id}" do
23
+ let(:path) { "/" }
24
+ %w{GET POST PUT DELETE}.each do |m|
25
+ context(m) do
26
+ before { @env[:method] = m }
27
+ it { should be_ok }
28
+ its(:body) { should == "OK" }
29
+ end
30
+ end
31
+ end
32
+
33
+ context "when path has prefix /people/{person-id}" do
34
+ let(:path) { "/people/#{person_id}" }
35
+ let(:person_id) { rand(9999).to_s }
36
+
37
+ context "when no login information provided" do
38
+ %w{GET POST PUT DELETE}.each do |m|
39
+ context(m) do
40
+ before { @env[:method] = m }
41
+ it { should be_unauthorized }
42
+ its(:body) { should == "Get out of #{path}!" }
43
+ end
44
+ end
45
+ end
46
+
47
+ context "when correct login information provided" do
48
+ before { @env[:cookie] = generate_cookie(secret_key, api_key, hash) }
49
+ let(:secret_key) { "34d3d1e26cd44c05a0c450c0a0f8147b" }
50
+ let(:api_key) { "8802f8e9b2cf4eb993e8c8adb1e02b06" }
51
+ let(:hash) do
52
+ {
53
+ "user" => person_id,
54
+ "session_key" => "session_key",
55
+ "ss" => "session_key_secret",
56
+ "expires" => (Time.now.to_i + rand(9999) + 1).to_s
57
+ }
58
+ end
59
+ %w{GET POST PUT DELETE}.each do |m|
60
+ context(m) do
61
+ before { @env[:method] = m }
62
+ it { should be_ok }
63
+ its(:body) { should == "OK" }
64
+ end
65
+ end
66
+ end
67
+
68
+ context "when incorrect login information provided" do
69
+ before { @env[:cookie] = generate_cookie("xxxx", api_key, hash) }
70
+ let(:api_key) { "8802f8e9b2cf4eb993e8c8adb1e02b06" }
71
+ let(:hash) do
72
+ {
73
+ "user" => person_id,
74
+ "session_key" => "session_key",
75
+ "ss" => "session_key_secret",
76
+ "expires" => (Time.now.to_i + rand(9999) + 1).to_s
77
+ }
78
+ end
79
+ %w{GET POST PUT DELETE}.each do |m|
80
+ context(m) do
81
+ before { @env[:method] = m }
82
+ it { should be_unauthorized }
83
+ its(:body) { should == "Get out of #{path}!" }
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ describe Polar::Authentication, "no failed handler is provided" do
93
+ include Rack::Test::Methods
94
+ include Helpers
95
+ def app
96
+ Polar::Authentication.new(lambda { |env| [200, {}, ["OK"]] }, "8802f8e9b2cf4eb993e8c8adb1e02b06", "34d3d1e26cd44c05a0c450c0a0f8147b")
97
+ end
98
+ subject { request(path, @env); last_response }
99
+ before { @env = {} }
100
+
101
+ context "when path does not have prefix /people/{person-id}" do
102
+ let(:path) { "/" }
103
+ %w{GET POST PUT DELETE}.each do |m|
104
+ context(m) do
105
+ before { @env[:method] = m }
106
+ it { should be_ok }
107
+ its(:body) { should == "OK" }
108
+ end
109
+ end
110
+ end
111
+
112
+ context "when path has prefix /people/{person-id}" do
113
+ let(:path) { "/people/#{person_id}" }
114
+ let(:person_id) { rand(9999).to_s }
115
+ context "when no login information provided" do
116
+ %w{GET POST PUT DELETE}.each do |m|
117
+ context(m) do
118
+ before { @env[:method] = m }
119
+ it { should be_unauthorized }
120
+ its(:content_type) { should == "text/plain"}
121
+ its(:body) { should == "Unauthorized!" }
122
+ end
123
+ end
124
+ end
125
+
126
+ context "when correct login information provided" do
127
+ before { @env[:cookie] = generate_cookie(secret_key, api_key, hash) }
128
+ let(:secret_key) { "34d3d1e26cd44c05a0c450c0a0f8147b" }
129
+ let(:api_key) { "8802f8e9b2cf4eb993e8c8adb1e02b06" }
130
+ let(:hash) do
131
+ {
132
+ "user" => person_id,
133
+ "session_key" => "session_key",
134
+ "ss" => "session_key_secret",
135
+ "expires" => (Time.now.to_i + rand(9999) + 1).to_s
136
+ }
137
+ end
138
+ %w{GET POST PUT DELETE}.each do |m|
139
+ context(m) do
140
+ before { @env[:method] = m }
141
+ it { should be_ok }
142
+ its(:body) { should == "OK" }
143
+ end
144
+ end
145
+ end
146
+
147
+ context "when incorrect login information provided" do
148
+ before { @env[:cookie] = generate_cookie("xxxx", api_key, hash) }
149
+ let(:api_key) { "8802f8e9b2cf4eb993e8c8adb1e02b06" }
150
+ let(:hash) do
151
+ {
152
+ "user" => person_id,
153
+ "session_key" => "session_key",
154
+ "ss" => "session_key_secret",
155
+ "expires" => (Time.now.to_i + rand(9999) + 1).to_s
156
+ }
157
+ end
158
+ %w{GET POST PUT DELETE}.each do |m|
159
+ context(m) do
160
+ before { @env[:method] = m }
161
+ it { should be_unauthorized }
162
+ its(:content_type) { should == "text/plain" }
163
+ its(:body) { should == "Unauthorized!" }
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+ require "spec_helper"
3
+
4
+ describe Polar::Client, "#get_friends" do
5
+ let(:api_key) { "api_key" }
6
+ let(:secret_key) { "secret_key" }
7
+ let(:session_key) { "session_key" }
8
+
9
+ subject { described_class.new(api_key, secret_key, session_key).get_friends }
10
+ before { Stubs::GetFriends.new }
11
+
12
+ it do
13
+ subject.class.should eql Polar::Cursor
14
+ subject.first.class.should eql Polar::User
15
+ subject.first.avatar.should eql "http://hdn.xnimg.cn/photos/hdn521/20120508/0915/h_tiny_768l_5f460007d2ae2f75.jpg"
16
+ subject.first.to_h["avatar"].should eql "http://hdn.xnimg.cn/photos/hdn521/20120508/0915/h_tiny_768l_5f460007d2ae2f75.jpg"
17
+ end
18
+ end
19
+
20
+ describe Polar::Client, "#get_info" do
21
+ let(:api_key) { "api_key" }
22
+ let(:secret_key) { "secret_key" }
23
+ let(:session_key) { "session_key" }
24
+ subject { described_class.new(api_key, secret_key, session_key).get_info(uids, fields) }
25
+ before { Stubs::GetUser.new }
26
+
27
+ let(:fields) do
28
+ %w{uid name tinyurl}
29
+ end
30
+
31
+ let(:uids) do
32
+ [449545842]
33
+ end
34
+
35
+ it do
36
+ subject.class.should eql Polar::User
37
+ subject.avatar.should eql "http://hdn.xnimg.cn/photos/hdn321/20120430/0850/h_tiny_7KQT_563e0006d3dc2f76.jpg"
38
+ end
39
+ end
40
+
41
+ describe Polar::Client, "#status_set" do
42
+ let(:api_key) { "api_key" }
43
+ let(:secret_key) { "secret_key" }
44
+ let(:session_key) { "session_key" }
45
+
46
+ let(:status) { "Hello, how are you toady?" }
47
+ before { Stubs::SetStatus.new }
48
+
49
+ subject { described_class.new(api_key, secret_key, session_key).set_status(status) }
50
+
51
+ it do
52
+ subject.class.should eql Polar::Response
53
+ subject.success.should eql true
54
+ end
55
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Polar::Cursor do
4
+ let(:api_key) { "api_key" }
5
+ let(:secret_key) { "secret_key" }
6
+ let(:session_key) { "session_key" }
7
+
8
+ subject { Polar::Client.new(api_key, secret_key, session_key).get_friends }
9
+
10
+ before do
11
+ Timecop.freeze(Time.now)
12
+ Stubs::GetLotsOfFriends.new
13
+ end
14
+
15
+ it do
16
+ subject.class.should eql Polar::Cursor
17
+
18
+ total_users = Array.new
19
+ while subject.next_page?
20
+ subject.each do |user|
21
+ total_users << user
22
+ end
23
+ end
24
+ total_users.count.should eql 500 * 50
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe Polar::SignatureCalculator do
4
+ let(:calculator) { Polar::SignatureCalculator.new(secret_key) }
5
+ describe "#calculate" do
6
+ subject { calculator.calculate(hash) }
7
+ context "when secret_key is 7fbf9791036749cb82e74efd62e9eb38" do
8
+ let(:secret_key) { "7fbf9791036749cb82e74efd62e9eb38" }
9
+ example_hash = {
10
+ "v" => "1.0",
11
+ "api_key" => "ec9e57913c5b42b282ab7b743559e1b0",
12
+ "method" => "xiaonei.users.getLoggedInUser",
13
+ "call_id" => 1232095295656,
14
+ "session_key" => "L6Xe8dXVGISZ17LJy7GzZaeYGpeGfeNdqEPLNUtCJfxPCxCRLWT83x+s/Ur94PqP-700001044"
15
+ }
16
+ context "when hash is #{example_hash.inspect}" do
17
+ let(:hash) { example_hash }
18
+ it { should == "66f332c08191b8a5dd3477d36f3af49f" }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/polar')
2
+
3
+ require 'rack/test'
4
+ require 'ruby-debug'
5
+ require 'webmock'
6
+ require 'webmock/rspec'
7
+ require "polar"
8
+ require "stub_manager"
9
+ require "timecop"
10
+
11
+ #require each stub file
12
+ Dir[File.dirname(__FILE__) + '/stubs/*'].each { |file| require file }
13
+
14
+ module Helpers
15
+ def generate_hash(secret_key, api_key, hash = {})
16
+ auth_code = Digest::MD5.hexdigest(hash.sort.collect { |e| e * "=" } * "" << secret_key)
17
+ Hash[hash.collect { |k, v| [api_key + "_" + k, v] }].merge!(api_key => auth_code)
18
+ end
19
+
20
+ def generate_cookie(secret_key, api_key, hash = {})
21
+ generate_hash(secret_key, api_key, hash).collect { |(k, v)| "#{k}=#{v}" }
22
+ end
23
+ end
24
+
@@ -0,0 +1,56 @@
1
+ require 'webmock'
2
+
3
+ class EndPointStub
4
+ include WebMock::API
5
+
6
+ def initialize
7
+ WebMock.reset!
8
+ if @pages
9
+ @pages.times do |count|
10
+ stub_request(:post, "http://api.renren.com/restserver.do").with(:body => request_body_with_page(count + 1)).to_return(response(count + 1))
11
+ end
12
+ else
13
+ stub_request(:post, "http://api.renren.com/restserver.do").to_return(response(1))
14
+ end
15
+ end
16
+
17
+ def with
18
+ {}
19
+ end
20
+
21
+ def response
22
+ raise("Abstract Method")
23
+ end
24
+
25
+ private
26
+
27
+ def request_body_with_page
28
+ raise("Abstract Method")
29
+ end
30
+
31
+ def urlencode_params(params_hash)
32
+ params = ''
33
+ stack = []
34
+
35
+ params_hash.each do |k, v|
36
+ if v.is_a?(Hash)
37
+ stack << [k,v]
38
+ else
39
+ params << "#{k}=#{v}&"
40
+ end
41
+ end
42
+
43
+ stack.each do |parent, hash|
44
+ hash.each do |k, v|
45
+ if v.is_a?(Hash)
46
+ stack << ["#{parent}[#{k}]", v]
47
+ else
48
+ params << "#{parent}[#{k}]=#{v}&"
49
+ end
50
+ end
51
+ end
52
+
53
+ params.chop! # trailing &
54
+ params
55
+ end
56
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: polar-renren
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lei, Zhi-Qiang, Stewart Matheson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-17 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! ' Polar is an API wrapper for the Renren social network.
15
+
16
+ '
17
+ email: stew@rtmatheson.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files:
21
+ - README.markdown
22
+ files:
23
+ - lib/polar/authentication.rb
24
+ - lib/polar/base.rb
25
+ - lib/polar/client.rb
26
+ - lib/polar/cursor.rb
27
+ - lib/polar/error/api_error.rb
28
+ - lib/polar/error/http_error.rb
29
+ - lib/polar/request.rb
30
+ - lib/polar/response.rb
31
+ - lib/polar/signature_calculator.rb
32
+ - lib/polar/user.rb
33
+ - lib/polar.rb
34
+ - spec/authentication_spec.rb
35
+ - spec/client_spec.rb
36
+ - spec/cursor_spec.rb
37
+ - spec/signature_calculator_spec.rb
38
+ - spec/spec_helper.rb
39
+ - spec/stub_manager.rb
40
+ - README.markdown
41
+ homepage: https://github.com/stewartmatheson/polar
42
+ licenses:
43
+ - BSD
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ segments:
55
+ - 0
56
+ hash: 2819554415476033239
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.19
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Polar is a wrapper around the Renren social network's restful api.
69
+ test_files:
70
+ - spec/authentication_spec.rb
71
+ - spec/client_spec.rb
72
+ - spec/cursor_spec.rb
73
+ - spec/signature_calculator_spec.rb