npr 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +13 -0
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README.md +115 -3
- data/Rakefile +6 -0
- data/gemfiles/Gemfile.rb-1.8.7 +6 -0
- data/lib/npr/api/client.rb +87 -0
- data/lib/npr/api/message.rb +38 -0
- data/lib/npr/api/query_builder.rb +222 -0
- data/lib/npr/api/response.rb +32 -0
- data/lib/npr/api.rb +7 -0
- data/lib/npr/concern/attr_typecast.rb +59 -0
- data/lib/npr/concern/relation.rb +103 -0
- data/lib/npr/concern/shallow_attributes.rb +71 -0
- data/lib/npr/concern.rb +9 -0
- data/lib/npr/configuration.rb +120 -0
- data/lib/npr/core_ext/array/wrap.rb +15 -0
- data/lib/npr/entity/audio.rb +28 -0
- data/lib/npr/entity/author.rb +22 -0
- data/lib/npr/entity/base.rb +19 -0
- data/lib/npr/entity/book.rb +21 -0
- data/lib/npr/entity/book_edition.rb +26 -0
- data/lib/npr/entity/byline.rb +18 -0
- data/lib/npr/entity/collection.rb +11 -0
- data/lib/npr/entity/crop.rb +20 -0
- data/lib/npr/entity/enlargement.rb +20 -0
- data/lib/npr/entity/formats.rb +19 -0
- data/lib/npr/entity/image.rb +33 -0
- data/lib/npr/entity/intro_text.rb +21 -0
- data/lib/npr/entity/link.rb +23 -0
- data/lib/npr/entity/list.rb +28 -0
- data/lib/npr/entity/list_text.rb +19 -0
- data/lib/npr/entity/member.rb +23 -0
- data/lib/npr/entity/member_byline.rb +17 -0
- data/lib/npr/entity/member_promo_art.rb +17 -0
- data/lib/npr/entity/mp3.rb +23 -0
- data/lib/npr/entity/organization.rb +18 -0
- data/lib/npr/entity/paragraph.rb +27 -0
- data/lib/npr/entity/permissions.rb +18 -0
- data/lib/npr/entity/program.rb +24 -0
- data/lib/npr/entity/promo_art.rb +17 -0
- data/lib/npr/entity/promo_art_book_edition.rb +18 -0
- data/lib/npr/entity/provider.rb +23 -0
- data/lib/npr/entity/pull_quote.rb +16 -0
- data/lib/npr/entity/related_link.rb +21 -0
- data/lib/npr/entity/show.rb +19 -0
- data/lib/npr/entity/story.rb +179 -0
- data/lib/npr/entity/text.rb +22 -0
- data/lib/npr/entity/title.rb +21 -0
- data/lib/npr/entity/transcript.rb +16 -0
- data/lib/npr/entity.rb +7 -0
- data/lib/npr/errors.rb +17 -0
- data/lib/npr/version.rb +1 -1
- data/lib/npr.rb +64 -3
- data/npr.gemspec +12 -2
- data/spec/fixtures/README.md +30 -0
- data/spec/fixtures/atom/01_story_full_media.atom +36 -0
- data/spec/fixtures/atom/02_story_multiple_images.atom +32 -0
- data/spec/fixtures/atom/03_no_results.atom +10 -0
- data/spec/fixtures/atom/04_invalid_id.atom +344 -0
- data/spec/fixtures/atom/05_no_api_key.atom +9 -0
- data/spec/fixtures/atom/06_story_multiple_ids.atom +59 -0
- data/spec/fixtures/fetch_formats.rb +65 -0
- data/spec/fixtures/html/01_story_full_media.html +54 -0
- data/spec/fixtures/html/02_story_multiple_images.html +55 -0
- data/spec/fixtures/html/03_no_results.html +38 -0
- data/spec/fixtures/html/04_invalid_id.html +82 -0
- data/spec/fixtures/html/05_no_api_key.html +8 -0
- data/spec/fixtures/html/06_story_multiple_ids.html +69 -0
- data/spec/fixtures/js/01_story_full_media.js +1 -0
- data/spec/fixtures/js/02_story_multiple_images.js +1 -0
- data/spec/fixtures/js/03_no_results.js +1 -0
- data/spec/fixtures/js/04_invalid_id.js +1 -0
- data/spec/fixtures/js/05_no_api_key.js +8 -0
- data/spec/fixtures/js/06_story_multiple_ids.js +1 -0
- data/spec/fixtures/json/01_story_full_media.json +1 -0
- data/spec/fixtures/json/02_story_multiple_images.json +1 -0
- data/spec/fixtures/json/03_no_results.json +1 -0
- data/spec/fixtures/json/04_invalid_id.json +1 -0
- data/spec/fixtures/json/05_no_api_key.json +1 -0
- data/spec/fixtures/json/06_story_multiple_ids.json +1 -0
- data/spec/fixtures/json/list.json +1 -0
- data/spec/fixtures/mediarss/01_story_full_media.rss +31 -0
- data/spec/fixtures/mediarss/02_story_multiple_images.rss +40 -0
- data/spec/fixtures/mediarss/03_no_results.rss +17 -0
- data/spec/fixtures/mediarss/04_invalid_id.rss +279 -0
- data/spec/fixtures/mediarss/05_no_api_key.rss +31 -0
- data/spec/fixtures/mediarss/06_story_multiple_ids.rss +65 -0
- data/spec/fixtures/nprml/01_story_full_media.xml +271 -0
- data/spec/fixtures/nprml/02_story_multiple_images.xml +165 -0
- data/spec/fixtures/nprml/03_no_results.xml +14 -0
- data/spec/fixtures/nprml/04_invalid_id.xml +1780 -0
- data/spec/fixtures/nprml/05_no_api_key.xml +9 -0
- data/spec/fixtures/nprml/06_story_multiple_ids.xml +435 -0
- data/spec/fixtures/nprml/list.xml +440 -0
- data/spec/fixtures/podcast/01_story_full_media.rss +30 -0
- data/spec/fixtures/podcast/02_story_multiple_images.rss +32 -0
- data/spec/fixtures/podcast/03_no_results.rss +19 -0
- data/spec/fixtures/podcast/04_invalid_id.rss +186 -0
- data/spec/fixtures/podcast/05_no_api_key.rss +31 -0
- data/spec/fixtures/podcast/06_story_multiple_ids.rss +43 -0
- data/spec/fixtures/rss/01_story_full_media.rss +25 -0
- data/spec/fixtures/rss/02_story_multiple_images.rss +25 -0
- data/spec/fixtures/rss/03_no_results.rss +17 -0
- data/spec/fixtures/rss/04_invalid_id.rss +137 -0
- data/spec/fixtures/rss/05_no_api_key.rss +31 -0
- data/spec/fixtures/rss/06_story_multiple_ids.rss +33 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/config_helper.rb +64 -0
- data/spec/support/fake_response.rb +54 -0
- data/spec/support/fixture_helper.rb +23 -0
- data/spec/unit/api/client_spec.rb +42 -0
- data/spec/unit/api/message_spec.rb +68 -0
- data/spec/unit/api/query_builder_spec.rb +195 -0
- data/spec/unit/api/response_spec.rb +45 -0
- data/spec/unit/configuration_spec.rb +63 -0
- data/spec/unit/entity/audio_spec.rb +75 -0
- data/spec/unit/entity/author_spec.rb +30 -0
- data/spec/unit/entity/base_spec.rb +87 -0
- data/spec/unit/entity/book_edition_spec.rb +57 -0
- data/spec/unit/entity/book_spec.rb +31 -0
- data/spec/unit/entity/byline_spec.rb +23 -0
- data/spec/unit/entity/collection_spec.rb +39 -0
- data/spec/unit/entity/crop_spec.rb +25 -0
- data/spec/unit/entity/englargement_spec.rb +21 -0
- data/spec/unit/entity/formats_spec.rb +41 -0
- data/spec/unit/entity/image_spec.rb +82 -0
- data/spec/unit/entity/intro_text_spec.rb +25 -0
- data/spec/unit/entity/link_spec.rb +25 -0
- data/spec/unit/entity/list_spec.rb +22 -0
- data/spec/unit/entity/list_text_spec.rb +31 -0
- data/spec/unit/entity/member_byline_spec.rb +21 -0
- data/spec/unit/entity/member_promo_art_spec.rb +21 -0
- data/spec/unit/entity/member_spec.rb +59 -0
- data/spec/unit/entity/mp3_spec.rb +25 -0
- data/spec/unit/entity/organization_spec.rb +29 -0
- data/spec/unit/entity/paragraph_spec.rb +25 -0
- data/spec/unit/entity/permissions_spec.rb +56 -0
- data/spec/unit/entity/program_spec.rb +27 -0
- data/spec/unit/entity/promo_art_book_edition_spec.rb +21 -0
- data/spec/unit/entity/promo_art_spec.rb +42 -0
- data/spec/unit/entity/pull_quote_spec.rb +29 -0
- data/spec/unit/entity/related_link_spec.rb +55 -0
- data/spec/unit/entity/show_spec.rb +41 -0
- data/spec/unit/entity/story_spec.rb +154 -0
- data/spec/unit/entity/text_spec.rb +54 -0
- data/spec/unit/entity/title_spec.rb +25 -0
- data/spec/unit/entity/transcript_spec.rb +22 -0
- metadata +340 -8
data/.travis.yml
ADDED
data/{LICENSE → MIT-LICENSE}
RENAMED
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
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.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,6 +1,40 @@
|
|
1
|
-
# NPR Ruby Client
|
1
|
+
# NPR API Ruby Client
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/bricker88/npr.png)](https://travis-ci.org/bricker88/npr)
|
4
|
+
|
5
|
+
**NOTE** This gem is a WIP
|
6
|
+
|
7
|
+
A simple Ruby client for the
|
8
|
+
[NPR API](http://www.npr.org/api/index).
|
9
|
+
|
10
|
+
|
11
|
+
## Support
|
12
|
+
|
13
|
+
This gem is tested with these versions (but may
|
14
|
+
work with others):
|
15
|
+
|
16
|
+
* Ruby 1.8.7, 1.9.2, 1.9.3, ruby-head
|
17
|
+
* NPR API version 0.94
|
18
|
+
|
19
|
+
|
20
|
+
## Dependencies
|
21
|
+
|
22
|
+
* `faraday >= 0.8.0` (HTTP requests)
|
23
|
+
* `faraday_middleware >= 0.9.0` (response processing)
|
24
|
+
|
25
|
+
**NOTE** If you are running **Ruby < 1.9**, you will have to install
|
26
|
+
the [json gem](http://rubygems.org/gems/json):
|
27
|
+
|
28
|
+
In your Gemfile:
|
29
|
+
|
30
|
+
gem 'json', '~> 1.7.5'
|
31
|
+
|
32
|
+
From the command line:
|
33
|
+
|
34
|
+
$ gem install json
|
35
|
+
|
36
|
+
Ruby 1.9+ comes with JSON support built-in!
|
2
37
|
|
3
|
-
A simple Ruby client for the NPR API
|
4
38
|
|
5
39
|
## Installation
|
6
40
|
|
@@ -16,9 +50,87 @@ Or install it yourself as:
|
|
16
50
|
|
17
51
|
$ gem install npr
|
18
52
|
|
53
|
+
|
19
54
|
## Usage
|
20
55
|
|
21
|
-
|
56
|
+
### API Key
|
57
|
+
|
58
|
+
NPR requires that you have an API key in order to use
|
59
|
+
their API. More information about this (including how
|
60
|
+
to register) can be found at
|
61
|
+
[NPR's API Documentation](http://www.npr.org/api/index).
|
62
|
+
|
63
|
+
### Configuration
|
64
|
+
|
65
|
+
API requests can be configured globally. This is recommended
|
66
|
+
for setting the API Key, but you can also set other parameters
|
67
|
+
which will be passed in with every request (unless overridden):
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
NPR.configure do |config|
|
71
|
+
config.apiKey = "YOUR_API_KEY"
|
72
|
+
config.sort = "date descending"
|
73
|
+
config.requiredAssets = "text"
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
For a Rails application, a good place to put the configuration
|
78
|
+
would be in an initializer, such as `config/initializers/npr_config.rb`.
|
79
|
+
|
80
|
+
### DSL
|
81
|
+
|
82
|
+
The DSL is modeled after Rails' `ActiveRecord::Relation`, so for the
|
83
|
+
most part, if you understand that, then using the NPR gem will come
|
84
|
+
naturally to you!
|
85
|
+
|
86
|
+
To find a story by ID:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
NPR::Story.find(1999) #=> NPR::Story
|
90
|
+
```
|
91
|
+
|
92
|
+
`NPR::Story#find` will either return a Story object if it was found,
|
93
|
+
or an array of Messages from the NPR API.
|
94
|
+
|
95
|
+
Building a query:
|
96
|
+
|
97
|
+
```
|
98
|
+
NPR::Story.where(date: [2.days.ago..Time.now]).order("date ascending").limit(10).offset(50)
|
99
|
+
```
|
100
|
+
|
101
|
+
That's a contrived example but it shows all the methods available.
|
102
|
+
|
103
|
+
You can also query directly on an `NPR::API::Client` object, if you're
|
104
|
+
feeling adventurous:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
client = NPR::API::Client.new(apiKey: NPR.config.apiKey)
|
108
|
+
client.query(sort: "editor assigned", numResults: "12")
|
109
|
+
```
|
110
|
+
|
111
|
+
The params that get passed into the `#query` method map directly to
|
112
|
+
the parameters that NPR's API accepts. See the
|
113
|
+
[NPR API Input Reference](http://www.npr.org/api/inputReference.php)
|
114
|
+
for all of the options.
|
115
|
+
|
116
|
+
|
117
|
+
## TODO
|
118
|
+
|
119
|
+
* More Documentation
|
120
|
+
* Search functionality
|
121
|
+
* Add "select" method to QueryBuilder for the "fields" input
|
122
|
+
* Abstract attributes so they're not tied directly to the API response.
|
123
|
+
Also to make them more Ruby-conventional (i.e. snake_case)
|
124
|
+
* Example: "apiKey" => :api_key
|
125
|
+
* Support for "container" node
|
126
|
+
* Support for "parent" node
|
127
|
+
* Support for "thumbnail" node
|
128
|
+
* Support a way to return raw formats of:
|
129
|
+
* HTML / Javascript (for views)
|
130
|
+
* JSON
|
131
|
+
* ATOM
|
132
|
+
* RSS
|
133
|
+
|
22
134
|
|
23
135
|
## Contributing
|
24
136
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,87 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Client
|
3
|
+
#
|
4
|
+
# Basic client for interacting with the NPR API.
|
5
|
+
#
|
6
|
+
# Options passed in when initializing the client will
|
7
|
+
# go out with every API request. You may also pass in
|
8
|
+
# options to +#query+ for a per-request basis.
|
9
|
+
#
|
10
|
+
# You can also set params via +client.params+
|
11
|
+
#
|
12
|
+
# Params should be passed in exactly as they will be sent
|
13
|
+
# to the API. Example: "apiKey", not "api_key"
|
14
|
+
# See the API documentation for what those params are.
|
15
|
+
#
|
16
|
+
module NPR
|
17
|
+
module API
|
18
|
+
class Client
|
19
|
+
attr_accessor :params
|
20
|
+
|
21
|
+
#-----------------
|
22
|
+
# Argument is a hash of params to send to the API.
|
23
|
+
# See <http://www.npr.org/api/inputReference.php> for
|
24
|
+
# API documentation.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
#
|
28
|
+
# NPR::Client.new(apiKey: "YOUR_API_KEY", sort: "date descending")
|
29
|
+
#
|
30
|
+
# Any parameters passed into this method will override the
|
31
|
+
# global configuration.
|
32
|
+
#
|
33
|
+
def initialize(params={})
|
34
|
+
@params = NPR.config.merge(params)
|
35
|
+
@apiKey = @params.delete(:apiKey)
|
36
|
+
end
|
37
|
+
|
38
|
+
#-----------------
|
39
|
+
# Send a query to the NPR API.
|
40
|
+
#
|
41
|
+
# Accepts a hash of options which get passed
|
42
|
+
# directly to the API.
|
43
|
+
#
|
44
|
+
# Any parameters passed directly into this method
|
45
|
+
# will override both the global configuration,
|
46
|
+
# as well as any parameters stored in this object's
|
47
|
+
# @params.
|
48
|
+
#
|
49
|
+
# Example:
|
50
|
+
#
|
51
|
+
# client.query(sort: "date descending", requiredAssets: "image")
|
52
|
+
#
|
53
|
+
# For now, this forced JSON output.
|
54
|
+
# TODO: Support more formats
|
55
|
+
#
|
56
|
+
def query(params={})
|
57
|
+
if @apiKey.nil?
|
58
|
+
raise NPR::NotConfiguredError, "apiKey must be set to perform a query"
|
59
|
+
end
|
60
|
+
|
61
|
+
response = connection.get do |request|
|
62
|
+
request.url NPR::Configuration::API_QUERY_PATH
|
63
|
+
request.params = @params.merge(params)
|
64
|
+
request.params['output'] = "json"
|
65
|
+
request.params['apiKey'] = @apiKey
|
66
|
+
end
|
67
|
+
|
68
|
+
NPR::API::Response.new(response)
|
69
|
+
end
|
70
|
+
|
71
|
+
#-----------------
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
#-----------------
|
76
|
+
|
77
|
+
def connection
|
78
|
+
@connection ||= begin
|
79
|
+
Faraday.new NPR::Configuration::API_ROOT do |conn|
|
80
|
+
conn.response :json, :content_type => /\bjson$/
|
81
|
+
conn.adapter Faraday.default_adapter
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end # Client
|
86
|
+
end # API
|
87
|
+
end # NPR
|
@@ -0,0 +1,38 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Message
|
3
|
+
#
|
4
|
+
# If the API returns any messages, use this class
|
5
|
+
# to represent it.
|
6
|
+
#
|
7
|
+
module NPR
|
8
|
+
module API
|
9
|
+
class Message
|
10
|
+
include NPR::Concern::ShallowAttributes
|
11
|
+
|
12
|
+
attr_accessor :id, :level
|
13
|
+
shallow_attribute "text", "timestamp"
|
14
|
+
|
15
|
+
#------------------
|
16
|
+
|
17
|
+
def initialize(json)
|
18
|
+
@_json = json
|
19
|
+
@id = @_json["id"]
|
20
|
+
@level = @_json["level"]
|
21
|
+
|
22
|
+
extract_shallow_attributes(@_json)
|
23
|
+
end
|
24
|
+
|
25
|
+
#------------------
|
26
|
+
|
27
|
+
def error?
|
28
|
+
self.level == "error"
|
29
|
+
end
|
30
|
+
|
31
|
+
#------------------
|
32
|
+
|
33
|
+
def warning?
|
34
|
+
self.level == "warning"
|
35
|
+
end
|
36
|
+
end # Message
|
37
|
+
end # API
|
38
|
+
end # NPR
|
@@ -0,0 +1,222 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::QueryBuilder
|
3
|
+
#
|
4
|
+
module NPR
|
5
|
+
module API
|
6
|
+
class QueryBuilder
|
7
|
+
CLASS_BUILDER_METHODS = [
|
8
|
+
:where,
|
9
|
+
:order,
|
10
|
+
:limit,
|
11
|
+
:offset
|
12
|
+
]
|
13
|
+
|
14
|
+
attr_reader :_klass, :builder
|
15
|
+
|
16
|
+
#-----------------------
|
17
|
+
|
18
|
+
def initialize(klass)
|
19
|
+
@_klass = klass
|
20
|
+
@builder = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
#-----------------------
|
24
|
+
# Build the params hash.
|
25
|
+
# This is automatically called by #to_a, so it probably
|
26
|
+
# doesn't need to be used manually.
|
27
|
+
def to_params
|
28
|
+
if @_klass == NPR::Entity::Story && @builder[:conditions]
|
29
|
+
conditions = parse_conditions(@builder[:conditions])
|
30
|
+
else
|
31
|
+
conditions = @builder[:conditions]
|
32
|
+
end
|
33
|
+
|
34
|
+
params = conditions || {}
|
35
|
+
params[:sort] = @builder[:order] if @builder[:order]
|
36
|
+
params[:numResults] = @builder[:limit] if @builder[:limit]
|
37
|
+
params[:startNum] = @builder[:offset] if @builder[:offset]
|
38
|
+
params.merge!(@builder[:extra]) if @builder[:extra]
|
39
|
+
|
40
|
+
params
|
41
|
+
end
|
42
|
+
|
43
|
+
#-----------------------
|
44
|
+
# Fire the query and return an Array of stories (or empty [])
|
45
|
+
#
|
46
|
+
# Named +to_a+ to keep in line with ActiveRecord::Relation's
|
47
|
+
# naming convention. It is also aliased as +query+, which
|
48
|
+
# probably makes a little more sense.
|
49
|
+
#
|
50
|
+
# Returns an Array. If the query returned any stories, then
|
51
|
+
# it will be an array of those stories. If no stories were
|
52
|
+
# returned, then it will be an empty array.
|
53
|
+
#
|
54
|
+
# There is no way to access the List or Messages returned
|
55
|
+
# from the response. This method is meant to be a way to
|
56
|
+
# get to the Stories as quickly and easily as possible.
|
57
|
+
# If you want access to the full Response object, use #query.
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
#
|
61
|
+
# query = NPR::API::QueryBuilder.new(NPR::Story)
|
62
|
+
# query.where(:id => [100, 150]).to_a
|
63
|
+
# #=> [NPR::Story, NPR::Story]
|
64
|
+
#
|
65
|
+
# # Assuming there is no story with an ID of 1
|
66
|
+
# query.where(:id => 1).to_a
|
67
|
+
# #=> []
|
68
|
+
#
|
69
|
+
# Note that for this method, +NPR.config.apiKey+ must be set.
|
70
|
+
#
|
71
|
+
def to_a
|
72
|
+
response = self.query
|
73
|
+
stories = []
|
74
|
+
|
75
|
+
if list = response.list
|
76
|
+
stories = Array.wrap(response.list.stories)
|
77
|
+
end
|
78
|
+
|
79
|
+
stories
|
80
|
+
end
|
81
|
+
|
82
|
+
#-----------------------
|
83
|
+
# Fire the query and return the full Response object
|
84
|
+
#
|
85
|
+
# Example:
|
86
|
+
#
|
87
|
+
# query = NPR::API::QueryBuilder.new(NPR::Story)
|
88
|
+
# query.where(:id => [100, 150]).query
|
89
|
+
# #=> NPR::API::Response
|
90
|
+
#
|
91
|
+
# See NPR::API::Response for what methods are available
|
92
|
+
# to you.
|
93
|
+
#
|
94
|
+
# Note that for this method, +NPR.config.apiKey+ must be set.
|
95
|
+
def query
|
96
|
+
client.query(self.to_params)
|
97
|
+
end
|
98
|
+
|
99
|
+
#-----------------------
|
100
|
+
# Add in arbitrary parameters.
|
101
|
+
#
|
102
|
+
# These take precedence over anything set via
|
103
|
+
# any of the other builder methods.
|
104
|
+
#
|
105
|
+
# Accepts a hash of key/values that the API
|
106
|
+
# can receive and handle.
|
107
|
+
#
|
108
|
+
# Example:
|
109
|
+
#
|
110
|
+
# query.set(apiKey: "YOUR_API_KEY")
|
111
|
+
#
|
112
|
+
def set(params)
|
113
|
+
@builder[:extra] = (@builder[:extra] || {}).merge(params)
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
#-----------------------
|
118
|
+
# Merge in the passed-in conditions to what
|
119
|
+
# already exists.
|
120
|
+
#
|
121
|
+
# Accepts a Hash.
|
122
|
+
#
|
123
|
+
# Example:
|
124
|
+
#
|
125
|
+
# query.where(id: 999, requiredAssets: "text")
|
126
|
+
#
|
127
|
+
# Extra convenience:
|
128
|
+
#
|
129
|
+
# * You may pass an array to :id
|
130
|
+
#
|
131
|
+
# query.where(id: [70, 180])
|
132
|
+
#
|
133
|
+
# * You may pass a date range to :date
|
134
|
+
#
|
135
|
+
# last_week = Time.new(2012, 10, 21)
|
136
|
+
# yesterday = Time.new(2012, 10, 25)
|
137
|
+
# query.where(date: (last_week..yesterday))
|
138
|
+
#
|
139
|
+
def where(conditions)
|
140
|
+
@builder[:conditions] = (@builder[:conditions] || {}).merge(conditions)
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
#-----------------------
|
145
|
+
# Set the order.
|
146
|
+
#
|
147
|
+
# Accepts a String.
|
148
|
+
#
|
149
|
+
# Example:
|
150
|
+
#
|
151
|
+
# query.order("date descending")
|
152
|
+
#
|
153
|
+
def order(order)
|
154
|
+
@builder[:order] = order
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
#-----------------------
|
159
|
+
# Set the limit.
|
160
|
+
#
|
161
|
+
# Accepts an Integer.
|
162
|
+
#
|
163
|
+
# Example:
|
164
|
+
#
|
165
|
+
# query.limit(10)
|
166
|
+
#
|
167
|
+
# Note that NPR limits the maximum results to 20,
|
168
|
+
# and will return only 20 results if more than the
|
169
|
+
# maximum is requested.
|
170
|
+
def limit(limit)
|
171
|
+
@builder[:limit] = limit
|
172
|
+
self
|
173
|
+
end
|
174
|
+
|
175
|
+
#-----------------------
|
176
|
+
# Offset the number of results
|
177
|
+
# Useful for pagination
|
178
|
+
#
|
179
|
+
# Accepts an Integer.
|
180
|
+
#
|
181
|
+
# Example:
|
182
|
+
#
|
183
|
+
# query.offset(100)
|
184
|
+
#
|
185
|
+
def offset(offset)
|
186
|
+
@builder[:offset] = offset
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
#-----------------------
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def client
|
195
|
+
@client ||= NPR::API::Client.new(:apiKey => NPR.config.apiKey)
|
196
|
+
end
|
197
|
+
|
198
|
+
#-----------------------
|
199
|
+
|
200
|
+
def parse_conditions(conditions)
|
201
|
+
parse_conditions!(conditions.dup)
|
202
|
+
end
|
203
|
+
|
204
|
+
#-----------------------
|
205
|
+
|
206
|
+
def parse_conditions!(conditions)
|
207
|
+
|
208
|
+
if conditions[:id].is_a? Array
|
209
|
+
conditions[:id] = conditions[:id].join(",")
|
210
|
+
end
|
211
|
+
|
212
|
+
if conditions[:date].is_a? Range
|
213
|
+
conditions[:startDate] = conditions[:date].first
|
214
|
+
conditions[:endDate] = conditions[:date].last
|
215
|
+
conditions.delete(:date)
|
216
|
+
end
|
217
|
+
|
218
|
+
conditions
|
219
|
+
end
|
220
|
+
end # QueryBuilder
|
221
|
+
end # API
|
222
|
+
end # NPR
|
@@ -0,0 +1,32 @@
|
|
1
|
+
##
|
2
|
+
# NPR::API::Response
|
3
|
+
#
|
4
|
+
# Wrapper around a Faraday response object
|
5
|
+
# Pass in the full response object from Faraday
|
6
|
+
#
|
7
|
+
module NPR
|
8
|
+
module API
|
9
|
+
class Response
|
10
|
+
include NPR::Concern::Relation
|
11
|
+
|
12
|
+
has_many "messages", :key => "message", :class_name => NPR::API::Message
|
13
|
+
attr_reader :raw, :version, :messages, :list
|
14
|
+
|
15
|
+
#--------------------------
|
16
|
+
|
17
|
+
def initialize(response)
|
18
|
+
create_relations(response)
|
19
|
+
@raw = response
|
20
|
+
@version = response.body["version"]
|
21
|
+
|
22
|
+
if response.body["list"]
|
23
|
+
@list = NPR::Entity::List.new(response.body["list"])
|
24
|
+
end
|
25
|
+
|
26
|
+
Array.wrap(response.body["message"]).each do |message|
|
27
|
+
@messages.push NPR::API::Message.new(message)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end # Response
|
31
|
+
end # API
|
32
|
+
end # NPR
|
data/lib/npr/api.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
##
|
4
|
+
# NPR::Concern::AttrTypecast
|
5
|
+
#
|
6
|
+
module NPR
|
7
|
+
#------------------
|
8
|
+
# Attributes that are being typecast to Ruby classes
|
9
|
+
ATTR_TYPES = {
|
10
|
+
"id" => :string_to_i,
|
11
|
+
"partnerId" => :string_to_i,
|
12
|
+
"storyDate" => :string_time_parse,
|
13
|
+
"pubDate" => :string_time_parse,
|
14
|
+
"lastModifiedDate" => :string_time_parse,
|
15
|
+
"showDate" => :string_time_parse,
|
16
|
+
"date" => :string_time_parse,
|
17
|
+
"segNum" => :string_to_i,
|
18
|
+
"num" => :string_to_i,
|
19
|
+
"timestamp" => :string_time_at,
|
20
|
+
"duration" => :string_to_i
|
21
|
+
}
|
22
|
+
|
23
|
+
module Concern
|
24
|
+
module AttrTypecast
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
#------------------
|
29
|
+
# Typecasting methods
|
30
|
+
def string_to_i(value)
|
31
|
+
value.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
#------------------
|
35
|
+
|
36
|
+
def string_time_parse(value)
|
37
|
+
!value.empty? ? Time.parse(value) : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
#------------------
|
41
|
+
|
42
|
+
def string_time_at(value)
|
43
|
+
Time.at(value.to_f)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
#------------------
|
48
|
+
#------------------
|
49
|
+
|
50
|
+
def attr_typecast(key, value)
|
51
|
+
if method = NPR::ATTR_TYPES[key]
|
52
|
+
send method, value
|
53
|
+
else
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end # AttrTypecast
|
58
|
+
end # Concern
|
59
|
+
end # NPR
|