goodreads 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -2,4 +2,4 @@ rvm:
2
2
  - 1.8.7
3
3
  - 1.9.2
4
4
  - 1.9.3
5
- - ree
5
+ - 2.0.0
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- source 'http://rubygems.org'
2
-
3
- gemspec
1
+ source 'https://rubygems.org'
4
2
 
3
+ gemspec
data/README.md CHANGED
@@ -1,18 +1,16 @@
1
- # Goodreads API wrapper
1
+ # Goodreads [![Build Status](https://secure.travis-ci.org/sosedoff/goodreads.png)](http://travis-ci.org/sosedoff/goodreads)
2
2
 
3
- Ruby library to connect with Goodreads API.
4
-
5
- [![Build Status](https://secure.travis-ci.org/sosedoff/goodreads.png)](http://travis-ci.org/sosedoff/goodreads)
3
+ Ruby wrapper to communicate with Goodreads API.
6
4
 
7
5
  ## Installation
8
6
 
9
- You can install this library via rubygems:
7
+ Install gem with rubygems:
10
8
 
11
9
  ```
12
10
  gem install goodreads
13
11
  ```
14
12
 
15
- Or using rake:
13
+ Or manually:
16
14
 
17
15
  ```
18
16
  rake install
@@ -20,28 +18,30 @@ rake install
20
18
 
21
19
  ## Getting Started
22
20
 
23
- In order to use Goodreads API you must obtain an API key for your account.
21
+ Before using Goodreads API you must create a new application. Visit [signup form](http://www.goodreads.com/api/keys) for details.
24
22
 
25
23
  Setup client:
26
24
 
27
- ```ruby
28
- client = Goodreads::Client.new(:api_key => 'YOUR_KEY')
29
-
30
- # or using a shortcut
31
- client = Goodreads.new(:api_key => 'YOUR_KEY')
25
+ ``` ruby
26
+ client = Goodreads::Client.new(:api_key => 'KEY', :api_secret => 'SECRET')
27
+ client = Goodreads.new(:api_key => 'KEY') # short version
32
28
  ```
33
29
 
34
30
  ### Global configuration
35
31
 
36
- Library allows you to define a global configuration options.
32
+ You can define client credentials on global level. Just create an initializer file (if using rails) under
33
+ `config/initializers`:
37
34
 
38
- ```ruby
39
- Goodreads.configure(:api_key => 'YOUR_KEY')
35
+ ``` ruby
36
+ Goodreads.configure(
37
+ :api_key => 'KEY',
38
+ :api_secret => 'SECRET'
39
+ )
40
40
  ```
41
41
 
42
- Get current options:
42
+ Get global configuration:
43
43
 
44
- ```ruby
44
+ ``` ruby
45
45
  Goodreads.configuration # => {:api_key => 'YOUR_KEY'}
46
46
  ```
47
47
 
@@ -55,32 +55,55 @@ Goodreads.reset_configuration
55
55
 
56
56
  ### Lookup books
57
57
 
58
- Find a book by ISBN:
58
+ You can lookup a book by ISBN, ID or Title:
59
59
 
60
60
  ```ruby
61
- book = client.book_by_isbn('ISBN')
61
+ client.book('id')
62
+ client.book_by_isbn('ISBN')
63
+ client.book_by_title('Book title')
62
64
  ```
63
-
64
- Find a book by Goodreads ID:
65
+
66
+ Search for books (by title, isbn, genre):
65
67
 
66
68
  ```ruby
67
- book = client.book('id')
69
+ search = client.search_books('The Lord Of The Rings')
70
+
71
+ search.results.work.each do |book|
72
+ book.id # => book id
73
+ book.title # => book title
74
+ end
68
75
  ```
69
-
70
- Find a book by title:
76
+
77
+ ### Authors
78
+
79
+ Look up an author by their Goodreads Author ID:
71
80
 
72
81
  ```ruby
73
- book = client.book_by_title('Book title')
82
+ author = client.author('id')
83
+
84
+ author.id # => author id
85
+ author.name # => author's name
86
+ author.link # => link to author's Goodreads page
87
+ author.fans_count # => number of fans author has on Goodreads
88
+ author.image_url # => link to image of the author
89
+ author.small_image_url # => link to smaller of the author
90
+ author.about # => description of the author
91
+ author.influences # => list of links to author's influences
92
+ author.works_count # => number of works by the author in Goodreads
93
+ author.gender # => author's gender
94
+ author.hometown # => author's hometown
95
+ author.born_at # => author's birthdate
96
+ author.died_at # => date of author's death
74
97
  ```
75
-
76
- Search for books (by title, isbn, genre):
98
+
99
+ Look up an author by name:
77
100
 
78
101
  ```ruby
79
- search = client.search_books('Your search query')
80
- search.results.work.each do |book|
81
- book.id # => book ID
82
- book.title # => book title
83
- end
102
+ author = client.author_by_name('Author Name')
103
+
104
+ author.id # => author id
105
+ author.name # => author name
106
+ author.link # => link to author's Goodreads page
84
107
  ```
85
108
 
86
109
  ### Reviews
@@ -95,15 +118,16 @@ client.recent_reviews.each do |r|
95
118
  r.user.name # => review user name
96
119
  end
97
120
  ```
98
-
121
+
99
122
  Get review details:
100
123
 
101
124
  ```ruby
102
125
  review = client.review('id')
103
- review.id # => ID
104
- review.user # => User information
105
- review.book # => Book information
106
- review.rating # => User rating
126
+
127
+ review.id # => review id
128
+ review.user # => user information
129
+ review.book # => uook information
130
+ review.rating # => user rating
107
131
  ```
108
132
 
109
133
  ### Shelves
@@ -112,37 +136,76 @@ Get the books on a user's shelf:
112
136
 
113
137
  ```ruby
114
138
  shelf = client.shelf(user_id, shelf_name)
139
+
115
140
  shelf.books # array of books on this shelf
116
141
  shelf.start # start index of this page of paginated results
117
142
  shelf.end # end index of this page of paginated results
118
143
  shelf.total # total number of books on this shelf
119
144
  ```
120
145
 
121
- ### User Id
146
+ ### Groups
122
147
 
123
- Get the user id of the user who authorized via OAuth:
148
+ Get group details:
124
149
 
125
150
  ```ruby
126
- client = Goodreads::Client.new(:api_key => 'YOUR_KEY', :oauth_token => token)
127
- client.user_id # id of user who authorized via OAuth
151
+ group = client.group('id')
152
+
153
+ group.id # => group id
154
+ group.title # => group title
155
+ group.access # => group's access settings
156
+ # => (e.g., public or private)
157
+ group.group_users_count # => number of users in the group
128
158
  ```
129
159
 
130
- `token` is an instance of `OAuth::AccessToken`. See the [Goodreads documentation](http://www.goodreads.com/api/oauth_example) for examples of how to correct create one.
160
+ List the groups a given user is a member of:
131
161
 
132
- ## Contributions
162
+ ```ruby
163
+ group_list = client.group_list('user_id', 'sort')
164
+
165
+ group_list.total # => total number of groups
166
+ group_list.group.count # => number of groups returned in the request
167
+
168
+ # Loop through the list to get details for each of the groups.
169
+
170
+ group_list.group.each do |g|
171
+ g.id # => group id
172
+ g.access # => access settings (private, public)
173
+ g.users_count # => number of members
174
+ g.title # => title
175
+ g.image_url # => url of the group's image
176
+ g.last_activity_at # => date and time of the group's last activity
177
+ end
178
+ ```
133
179
 
134
- Feel free to contribute any patches or new features.
180
+ The `sort` parameter is optional, and defaults to `my_activity`. For other sorting options, [see here](http://www.goodreads.com/api#group.list).
181
+
182
+ ### OAuth
183
+
184
+ For API calls requiring permission, such as write operations or browsing friends, see our [OAuth tutorial](examples/oauth.md).
185
+
186
+ ## Testing
187
+
188
+ To run the test suite:
189
+
190
+ ```
191
+ rake test
192
+ ```
193
+
194
+ ## Contributions
135
195
 
136
- Make sure to add a test coverage so it does not break any existing code.
196
+ You're welcome to submit patches and new features.
137
197
 
138
- For documentation please visit [API Reference](http://www.goodreads.com/api)
198
+ - Create a new branch for your feature of bugfix
199
+ - Add tests so it does not break any existing code
200
+ - Open a new pull request
201
+ - Check official [API documentation](http://www.goodreads.com/api)
139
202
 
140
203
  ## License
141
204
 
142
- Copyright © 2011-2012 Dan Sosedoff.
205
+ Copyright © 2011-2013 Dan Sosedoff.
143
206
 
144
207
  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:
145
208
 
146
209
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
147
210
 
148
- 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.
211
+ 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/examples/oauth.md ADDED
@@ -0,0 +1,57 @@
1
+ # Authorizing Goodreads via OAuth
2
+
3
+ For services requiring permission, such as write operations or browsing friends, the client must be authorized through OAuth.
4
+
5
+ ## Request Tokens vs. Access Tokens
6
+
7
+ First, get an OAuth *request* token:
8
+
9
+ ```ruby
10
+ request_token = OAuth::Consumer.new(
11
+ Goodreads.configuration[:api_key],
12
+ Goodreads.configuration[:api_secret],
13
+ :site => 'http://www.goodreads.com'
14
+ ).get_request_token
15
+ ```
16
+
17
+ Next, authorize by opening the authorization URL in a browser:
18
+
19
+ ```ruby
20
+ request_token.authorize_url
21
+ ```
22
+
23
+ Then request an OAuth *access* token:
24
+
25
+ ```ruby
26
+ access_token = request_token.get_access_token
27
+ ```
28
+
29
+ Finally, initialize a Goodreads client with it:
30
+
31
+ ```ruby
32
+ goodreads_client = Goodreads.new :oauth_token => access_token
33
+ ```
34
+
35
+ For more info, see the [Goodreads documentation](http://www.goodreads.com/api/oauth_example).
36
+
37
+ ## User ID
38
+
39
+ Get the ID of the user who authorized via OAuth:
40
+
41
+ ```ruby
42
+ goodreads_client.user_id
43
+ ```
44
+
45
+ ## Friends
46
+
47
+ Get the friend details for a user:
48
+
49
+ ```ruby
50
+ friends_hash = goodreads_client.friends [user_id]
51
+ ```
52
+
53
+ Get a list of their names:
54
+
55
+ ```ruby
56
+ friends_hash.user.map{ |u| u.name }
57
+ ```
data/goodreads.gemspec CHANGED
@@ -9,17 +9,17 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Dan Sosedoff"]
10
10
  s.email = ["dan.sosedoff@gmail.com"]
11
11
 
12
- s.add_development_dependency 'webmock', '~> 1.6'
13
- s.add_development_dependency 'rake', '~> 0.8'
14
- s.add_development_dependency 'rspec', '~> 2.5'
15
- s.add_development_dependency 'simplecov', '~> 0.4'
12
+ s.add_development_dependency 'webmock', '~> 1.11'
13
+ s.add_development_dependency 'rake', '~> 0.9'
14
+ s.add_development_dependency 'rspec', '~> 2.12'
15
+ s.add_development_dependency 'simplecov', '~> 0.7'
16
16
  s.add_development_dependency 'yard', '~> 0.6'
17
17
 
18
18
  s.add_runtime_dependency 'rest-client', '~> 1.6'
19
- s.add_runtime_dependency 'hashie', '~> 1.0'
19
+ s.add_runtime_dependency 'hashie', '~> 2.0'
20
20
  s.add_runtime_dependency 'activesupport', '~> 3'
21
21
  s.add_runtime_dependency 'i18n', '~> 0.5'
22
- s.add_runtime_dependency 'oauth', '~> 0.4'
22
+ s.add_runtime_dependency 'oauth', '~> 0.4'
23
23
 
24
24
  s.files = `git ls-files`.split("\n")
25
25
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -7,5 +7,13 @@ module Goodreads
7
7
  data = request('/author/show', params)
8
8
  Hashie::Mash.new(data['author'])
9
9
  end
10
+
11
+ # Search for an author by name
12
+ #
13
+ def author_by_name(name, params={})
14
+ params[:id] = name
15
+ data = request('/api/author_url', params)
16
+ Hashie::Mash.new(data['author'])
17
+ end
10
18
  end
11
19
  end
@@ -0,0 +1,12 @@
1
+ module Goodreads
2
+ module Friends
3
+ # Get the specified user's friends
4
+ #
5
+ # user_id - integer or string
6
+ #
7
+ def friends(user_id)
8
+ data = oauth_request("/friend/user/#{user_id}")
9
+ Hashie::Mash.new(data['friends'])
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module Goodreads
2
+ module Groups
3
+ # Get group details
4
+ def group(group_id)
5
+ data = request('/group/show', :id => group_id)
6
+ Hashie::Mash.new(data['group'])
7
+ end
8
+
9
+ # Get list of groups a given user is a member of
10
+ def group_list(user_id, sort='my_activity')
11
+ data = request('/group/list', :id => user_id, :sort => sort)
12
+ Hashie::Mash.new(data['groups']['list'])
13
+ end
14
+ end
15
+ end
@@ -5,6 +5,8 @@ require 'goodreads/client/authors'
5
5
  require 'goodreads/client/users'
6
6
  require 'goodreads/client/shelves'
7
7
  require 'goodreads/client/authorized'
8
+ require 'goodreads/client/groups'
9
+ require 'goodreads/client/friends'
8
10
 
9
11
  module Goodreads
10
12
  class Client
@@ -15,22 +17,24 @@ module Goodreads
15
17
  include Goodreads::Users
16
18
  include Goodreads::Shelves
17
19
  include Goodreads::Authorized
18
-
20
+ include Goodreads::Groups
21
+ include Goodreads::Friends
22
+
19
23
  attr_reader :api_key, :api_secret, :oauth_token
20
-
24
+
21
25
  # Initialize a Goodreads::Client instance
22
26
  #
23
27
  # options[:api_key] - Account API key
24
28
  # options[:api_secret] - Account API secret
25
- # options[:oauth_token] - OAuth token (optional, required for some calls)
29
+ # options[:oauth_token] - OAuth access token (optional, required for some calls)
26
30
  #
27
31
  def initialize(options={})
28
32
  unless options.kind_of?(Hash)
29
33
  raise ArgumentError, "Options hash required."
30
34
  end
31
-
32
- @api_key = options[:api_key]
33
- @api_secret = options[:api_secret]
35
+
36
+ @api_key = options[:api_key] || Goodreads.configuration[:api_key]
37
+ @api_secret = options[:api_secret] || Goodreads.configuration[:api_secret]
34
38
  @oauth_token = options[:oauth_token]
35
39
  end
36
40
  end
@@ -6,9 +6,9 @@ module Goodreads
6
6
  module Request
7
7
  API_URL = 'http://www.goodreads.com'
8
8
  API_FORMAT = 'xml'
9
-
9
+
10
10
  protected
11
-
11
+
12
12
  # Perform an API request
13
13
  #
14
14
  # path - Request path
@@ -16,14 +16,14 @@ module Goodreads
16
16
  #
17
17
  def request(path, params={})
18
18
  token = api_key || Goodreads.configuration[:api_key]
19
-
19
+
20
20
  if token.nil?
21
21
  raise Goodreads::ConfigurationError, 'API key required.'
22
22
  end
23
-
23
+
24
24
  params.merge!(:format => API_FORMAT, :key => token)
25
25
  url = "#{API_URL}#{path}"
26
-
26
+
27
27
  resp = RestClient.get(url, :params => params) do |response, request, result, &block|
28
28
  case response.code
29
29
  when 200
@@ -38,15 +38,21 @@ module Goodreads
38
38
  parse(resp)
39
39
  end
40
40
 
41
+ # Perform an OAuth API request. Goodreads must have been initialized with a valid OAuth access token.
42
+ #
43
+ # path - Request path
44
+ # params - Parameters hash
45
+ #
41
46
  def oauth_request(path, params=nil)
42
47
  raise 'OAuth access token required!' unless @oauth_token
43
48
  path = "#{path}?#{params.map{|k,v|"#{k}=#{v}"}.join('&')}" if params
44
- resp = @oauth_token.get(path)
49
+ resp = @oauth_token.get(path, {'Accept'=>'application/xml'})
50
+
45
51
  case resp
46
- when Net::HTTPUnauthorized
47
- raise Goodreads::Unauthorized
48
- when Net::HTTPNotFound
49
- raise Goodreads::NotFound
52
+ when Net::HTTPUnauthorized
53
+ raise Goodreads::Unauthorized
54
+ when Net::HTTPNotFound
55
+ raise Goodreads::NotFound
50
56
  end
51
57
 
52
58
  parse(resp)
@@ -57,6 +63,5 @@ module Goodreads
57
63
  hash.delete('Request')
58
64
  hash
59
65
  end
60
-
61
66
  end
62
67
  end
@@ -1,5 +1,5 @@
1
1
  module Goodreads
2
2
  unless defined?(Goodreads::VERSION)
3
- VERSION = '0.2.1'.freeze
3
+ VERSION = '0.2.2'.freeze
4
4
  end
5
5
  end