douban 0.1.0
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/.gitignore +3 -0
- data/MIT-LICENSE +20 -0
- data/README +53 -0
- data/Rakefile +18 -0
- data/VERSION +1 -0
- data/lib/douban.rb +118 -0
- data/lib/generators/douban/douban_generator.rb +20 -0
- data/lib/generators/douban/templates/douban.yml +8 -0
- data/lib/generators/douban/templates/douban_controller.rb +31 -0
- data/lib/generators/douban/templates/douban_helper.rb +21 -0
- metadata +82 -0
data/.gitignore
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
Douban
|
2
|
+
======
|
3
|
+
|
4
|
+
A Ruby wrapper for Douban(豆瓣) API, Rails 3 support only.
|
5
|
+
|
6
|
+
Install
|
7
|
+
=======
|
8
|
+
|
9
|
+
$ gem install douban
|
10
|
+
|
11
|
+
Usage
|
12
|
+
=======
|
13
|
+
|
14
|
+
1. Add below lines to your Gemfile:
|
15
|
+
|
16
|
+
gem 'douban', :require => 'oauth'
|
17
|
+
require 'douban'
|
18
|
+
|
19
|
+
2. Run generator
|
20
|
+
|
21
|
+
$ script/rails generate douban
|
22
|
+
|
23
|
+
3. Set you api key and secret in config/douban.yml, and include
|
24
|
+
DoubanHelper in your ApplicationController:
|
25
|
+
|
26
|
+
class ApplicationController
|
27
|
+
include DoubanHelper
|
28
|
+
end
|
29
|
+
|
30
|
+
4. Then you can insert below lines into your application layout
|
31
|
+
|
32
|
+
<% if douban_authorized? %>
|
33
|
+
<%= link_to 'Logout From Douban', douban_logout_path %>
|
34
|
+
<% else %>
|
35
|
+
<%= link_to "Login with douban", douban_login_path %>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
Other available helpers:
|
39
|
+
|
40
|
+
* douban_auth_or_login_required, it's useful if you use RESTFUL_AUTH.
|
41
|
+
* douban_auth_required, you can add it to before_filter.
|
42
|
+
|
43
|
+
5. To access douban resources, you can simple call:
|
44
|
+
|
45
|
+
douban.get('/people/ahbei')
|
46
|
+
douban.post('/reviews', review)
|
47
|
+
|
48
|
+
6. To determine if your have authorized by user, simple call:
|
49
|
+
|
50
|
+
douban.authorized?
|
51
|
+
=> true # if your access token is valid.
|
52
|
+
|
53
|
+
Feedback are always welcome, Yuanyi Zhang(zhangyuanyi#gmail.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |s|
|
7
|
+
s.name = "douban"
|
8
|
+
s.summary = "A Ruby wrapper of Douban(豆瓣) API"
|
9
|
+
s.email = "zhangyuanyi@gmail.com"
|
10
|
+
s.homepage = "http://github.com/yzhang/douban"
|
11
|
+
s.description = "A Ruby wrapper of Douban(豆瓣) API"
|
12
|
+
s.authors = ["Yuanyi Zhang"]
|
13
|
+
s.files = FileList["[A-Z]*", "{lib}/**/*", '.gitignore']
|
14
|
+
s.add_dependency 'oauth'
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/douban.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
|
3
|
+
class Douban
|
4
|
+
attr_accessor :callback, :request_token, :access_token
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def load(data)
|
8
|
+
access_token = data[:access_token]
|
9
|
+
access_token_secret = data[:access_token_secret]
|
10
|
+
|
11
|
+
douban = Douban.new(data[:request_token], data[:request_token_secret])
|
12
|
+
douban.access_token = OAuth::AccessToken.new(api_consumer, access_token, access_token_secret) if access_token
|
13
|
+
douban
|
14
|
+
end
|
15
|
+
|
16
|
+
def auth_consumer
|
17
|
+
@@auth_consumer ||= OAuth::Consumer.new(key, secret, {
|
18
|
+
:signature_method => "HMAC-SHA1",
|
19
|
+
:site => "http://www.douban.com",
|
20
|
+
:scheme => :header,
|
21
|
+
:request_token_path => '/service/auth/request_token',
|
22
|
+
:access_token_path => '/service/auth/access_token',
|
23
|
+
:authorize_path => '/service/auth/authorize',
|
24
|
+
:realm => url
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_consumer
|
29
|
+
@@api_consumer ||= OAuth::Consumer.new(key, secret,
|
30
|
+
{
|
31
|
+
:site => "http://api.douban.com",
|
32
|
+
:scheme => :header,
|
33
|
+
:signature_method => "HMAC-SHA1",
|
34
|
+
:realm => url
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
def key; config['key']; end
|
39
|
+
def secret; config['secret']; end
|
40
|
+
def url; config['url']; end
|
41
|
+
|
42
|
+
def config
|
43
|
+
@@config ||= lambda do
|
44
|
+
require 'yaml'
|
45
|
+
filename = "#{Rails.root}/config/douban.yml"
|
46
|
+
file = File.open(filename)
|
47
|
+
yaml = YAML.load(file)
|
48
|
+
return yaml[Rails.env]
|
49
|
+
end.call
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(request_token = nil, request_token_secret = nil)
|
54
|
+
if request_token && request_token_secret
|
55
|
+
self.request_token = OAuth::RequestToken.new(self.class.auth_consumer, request_token, request_token_secret)
|
56
|
+
else
|
57
|
+
self.request_token = self.class.auth_consumer.get_request_token()
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def authorize_url
|
62
|
+
@authorize_url ||= request_token.authorize_url(:oauth_callback => self.callback)
|
63
|
+
end
|
64
|
+
|
65
|
+
def authorize
|
66
|
+
return unless self.access_token.nil?
|
67
|
+
|
68
|
+
access_token = self.request_token.get_access_token
|
69
|
+
self.access_token ||= OAuth::AccessToken.new(self.class.api_consumer, access_token.token, access_token.secret)
|
70
|
+
end
|
71
|
+
|
72
|
+
def authorized?
|
73
|
+
return false if access_token.nil?
|
74
|
+
response = self.get("/access_token/#{access_token.token}")
|
75
|
+
response.code == '200'
|
76
|
+
end
|
77
|
+
|
78
|
+
def destroy
|
79
|
+
destroy_access_key if !access_token.nil?
|
80
|
+
request_token = access_token = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def dump
|
84
|
+
{
|
85
|
+
:request_token => request_token.token,
|
86
|
+
:request_token_secret => request_token.secret,
|
87
|
+
:access_token => access_token.nil? ? nil : access_token.token,
|
88
|
+
:access_token_secret => access_token.nil? ? nil : access_token.secret
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
def request(http_method, path, headers = {})
|
93
|
+
access_token.request(http_method, path, headers)
|
94
|
+
end
|
95
|
+
|
96
|
+
def get(path, headers = {})
|
97
|
+
request(:get, path, headers)
|
98
|
+
end
|
99
|
+
|
100
|
+
def post(path, headers = {})
|
101
|
+
request(:post, path, headers)
|
102
|
+
end
|
103
|
+
|
104
|
+
def delete(path, headers = {})
|
105
|
+
request(:delete, path, headers)
|
106
|
+
end
|
107
|
+
|
108
|
+
def put(path, headers = {})
|
109
|
+
request(:put, path, headers)
|
110
|
+
end
|
111
|
+
|
112
|
+
protected
|
113
|
+
|
114
|
+
def destroy_access_key
|
115
|
+
response = delete("/access_token/#{access_token.token}")
|
116
|
+
response.code == '200'
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class DoubanGenerator < Rails::Generators::Base
|
4
|
+
def install_douban
|
5
|
+
copy_file('douban_controller.rb', 'app/controllers/douban_controller.rb')
|
6
|
+
copy_file("douban_helper.rb", 'app/helpers/douban_helper.rb')
|
7
|
+
copy_file("douban.yml", 'config/douban.yml')
|
8
|
+
|
9
|
+
route %(# Routes for Douban OAuth
|
10
|
+
scope "/douban" do
|
11
|
+
match '/new' => 'douban#new', :as => :douban_login
|
12
|
+
match '/callback' => 'douban#callback', :as => :douban_callback
|
13
|
+
match '/logout' => 'douban#destroy', :as => :douban_logout
|
14
|
+
end)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.source_root
|
18
|
+
File.join(File.dirname(__FILE__), 'templates')
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class DoubanController < ApplicationController
|
2
|
+
def new
|
3
|
+
douban = Douban.new
|
4
|
+
douban.callback = douban_callback_url
|
5
|
+
authorize_url = douban.authorize_url
|
6
|
+
|
7
|
+
respond_to do |wants|
|
8
|
+
session[:back] = request.env['HTTP_REFERER'] unless request.env['HTTP_REFERER'].blank?
|
9
|
+
session[:douban] = douban.dump
|
10
|
+
wants.html {redirect_to authorize_url}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def callback
|
15
|
+
if session[:douban]
|
16
|
+
douban = Douban.load(session[:douban])
|
17
|
+
douban.authorize
|
18
|
+
session[:douban] = douban.dump
|
19
|
+
end
|
20
|
+
|
21
|
+
redirect_to(session[:back] || '/')
|
22
|
+
session[:back] = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def destroy
|
26
|
+
return unless douban_authorized?
|
27
|
+
session[:douban] = nil
|
28
|
+
douban.destroy
|
29
|
+
redirect_to '/'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DoubanHelper
|
2
|
+
def douban
|
3
|
+
@douban ||= (session[:douban] && session[:douban][:access_token]) ? Douban.load(session[:douban]) : nil
|
4
|
+
end
|
5
|
+
|
6
|
+
def douban_authorized?
|
7
|
+
!douban.nil?
|
8
|
+
end
|
9
|
+
|
10
|
+
def douban_auth_required
|
11
|
+
douban_authorized? || redirect_to(douban_auth_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def douban_auth_or_login_required
|
15
|
+
douban_authorized? || login_required
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.included(base)
|
19
|
+
base.send :helper_method, :douban_authorized? if base.respond_to? :helper_method
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: douban
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Yuanyi Zhang
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-04-07 00:00:00 +08:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: oauth
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: "A Ruby wrapper of Douban(\xE8\xB1\x86\xE7\x93\xA3) API"
|
33
|
+
email: zhangyuanyi@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README
|
40
|
+
files:
|
41
|
+
- .gitignore
|
42
|
+
- MIT-LICENSE
|
43
|
+
- README
|
44
|
+
- Rakefile
|
45
|
+
- VERSION
|
46
|
+
- lib/douban.rb
|
47
|
+
- lib/generators/douban/douban_generator.rb
|
48
|
+
- lib/generators/douban/templates/douban.yml
|
49
|
+
- lib/generators/douban/templates/douban_controller.rb
|
50
|
+
- lib/generators/douban/templates/douban_helper.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/yzhang/douban
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=UTF-8
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
segments:
|
72
|
+
- 0
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.6
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: "A Ruby wrapper of Douban(\xE8\xB1\x86\xE7\x93\xA3) API"
|
81
|
+
test_files: []
|
82
|
+
|