juicer-client 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +2 -0
- data/juicer-client.gemspec +29 -0
- data/lib/juicer.rb +100 -0
- data/lib/juicer/client.rb +66 -0
- data/lib/juicer/version.rb +3 -0
- data/spec/client_spec.rb +60 -0
- data/spec/juicer_spec.rb +154 -0
- data/spec/spec_helper.rb +5 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13438d05877e7471849d931789e96e8e07e7cec6
|
4
|
+
data.tar.gz: 4e6b4d2ede7e54a1710cb34a03cd3403e974f302
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 56dd21d839cb08779bfe8823e4281251193bafd34ae718f34888ff9c55dc4df7aef0b0a5d55393939d5cba33386d1b08a6befad947e1c0bf7981d3c1ba1150b6
|
7
|
+
data.tar.gz: cd0798958ba81451368e145b4285a1e5f02f605ff2c0aa331a738b294aed8afd348fb40a1b0ba1db50a817b5b3c2db82e9c1230c2ead7311d1255611b7ea27e9
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.1
|
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Karl Sutt
|
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,80 @@
|
|
1
|
+
# Juicer Client
|
2
|
+
|
3
|
+
The API client for the [BBC News Labs Juicer API](http://juicer.bbcnewslabs.co.uk).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'juicer-client'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install juicer-client
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Using the library is very simple. You'll need to obtain an API key from
|
24
|
+
[BBC Developer Portal](https://developer.bbc.co.uk/) by signing up
|
25
|
+
and registering a new app for the `bbcrd-juicer-apis` product in the
|
26
|
+
API listing.
|
27
|
+
|
28
|
+
Once you have obtained an API key and have installed the gem, you can
|
29
|
+
use it by requiring the `juicer` library and instantiating it with
|
30
|
+
your API key:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'juicer'
|
34
|
+
|
35
|
+
juicer = Juicer.new("<your API key>")
|
36
|
+
```
|
37
|
+
|
38
|
+
Have a look at the [documentation](http://bbc-news-labs.github.io/juicer-client/)
|
39
|
+
for the library on how to filter articles, find similar content, etc.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
juicer.products
|
43
|
+
=> ["NewsWeb", "Twitter", "Monitoring", "TheMirror", "Jupiter", "TheGuardian", ...]
|
44
|
+
|
45
|
+
juicer.articles({text: "London",
|
46
|
+
product: ["NewsWeb"],
|
47
|
+
published_after: "2014-10-14"})
|
48
|
+
=> [{"title"=>"London Market Report",
|
49
|
+
"description"=>"London Market Report",
|
50
|
+
"cps_id"=>"news_web_0962731f8c375d5096590ca38cee96e0e408180d",
|
51
|
+
"published"=>"2014-10-14T08:14:07.000Z",
|
52
|
+
"url"=>"http://www.bbc.co.uk/news/business-29610241#sa-ns_mchannel=rss&ns_source=PublicRSS20-sa",
|
53
|
+
"highlight"=>false,
|
54
|
+
"source"=>"NewsWeb",
|
55
|
+
"format"=>"TextualFormat",
|
56
|
+
"image"=>nil,
|
57
|
+
"themes"=>[],
|
58
|
+
"people"=>[],
|
59
|
+
"places"=>[],
|
60
|
+
"organisations"=>[{"kind"=>"Organisation", "name"=>"Burberry", ..}]},
|
61
|
+
{...}]
|
62
|
+
|
63
|
+
juicer.similar_articles("news_web_0962731f8c375d5096590ca38cee96e0e408180d")
|
64
|
+
=> [{"score"=>1.8277457,
|
65
|
+
"title"=>"Mulberry profit warning hits shares",
|
66
|
+
"cps_id"=>"20038835",
|
67
|
+
"created_at"=>"2012-10-23T12:58:45.247Z",
|
68
|
+
"published_at"=>"2012-10-23T11:57:37Z",
|
69
|
+
"juicer_url"=>"http://juicer.bbcnewslabs.co.uk/articles/20038835.json",
|
70
|
+
"url"=>"http://www.bbc.co.uk/news/business-20038835"},
|
71
|
+
{...}]
|
72
|
+
```
|
73
|
+
|
74
|
+
## Contributing
|
75
|
+
|
76
|
+
1. Fork it ( https://github.com/BBC-News-Labs/juicer-client/fork )
|
77
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
79
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
80
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'juicer'
|
5
|
+
require 'juicer/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "juicer-client"
|
9
|
+
spec.version = Juicer::VERSION
|
10
|
+
spec.authors = ["Karl Sutt"]
|
11
|
+
spec.email = ["karl@sutt.ee"]
|
12
|
+
spec.summary = %q{API client for BBC News Labs Juicer.}
|
13
|
+
spec.homepage = "http://juicer.bbcnewslabs.co.uk"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "httpi", "~> 2.2"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
26
|
+
spec.add_development_dependency "webmock", "~> 1.19"
|
27
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
28
|
+
spec.add_development_dependency "redcarpet", "~> 3.2"
|
29
|
+
end
|
data/lib/juicer.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# @author Karl Sutt
|
2
|
+
|
3
|
+
class Juicer
|
4
|
+
|
5
|
+
# @return [Juicer::Client] The HTTP client for making requests.
|
6
|
+
attr_reader :client
|
7
|
+
|
8
|
+
# Initialize the Juicer API client.
|
9
|
+
#
|
10
|
+
# @param api_key [String] API key obtained from Apigee.
|
11
|
+
# @return [Juicer] The API client.
|
12
|
+
#
|
13
|
+
def initialize(api_key)
|
14
|
+
@client = Juicer::Client.new(api_key)
|
15
|
+
end
|
16
|
+
|
17
|
+
# List sites.
|
18
|
+
# @return [Array<String>] list of available sites.
|
19
|
+
#
|
20
|
+
def sites
|
21
|
+
@client.request(:get, "sites")["sites"]
|
22
|
+
end
|
23
|
+
|
24
|
+
# List sections.
|
25
|
+
# @return [Array<String>] list of available section.
|
26
|
+
#
|
27
|
+
def sections
|
28
|
+
@client.request(:get, "sections")["sections"]
|
29
|
+
end
|
30
|
+
|
31
|
+
# List products.
|
32
|
+
# @return [Array<String>] list of available products.
|
33
|
+
#
|
34
|
+
def products
|
35
|
+
@client.request(:get, "products")["products"]
|
36
|
+
end
|
37
|
+
|
38
|
+
# List content formats.
|
39
|
+
# @return [Array<String>] list of available content formats.
|
40
|
+
#
|
41
|
+
def formats
|
42
|
+
@client.request(:get, "formats")["formats"]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Filter/find articles.
|
46
|
+
#
|
47
|
+
# @note The results will include all entities of an article. Therefore, if
|
48
|
+
# there are many results, the amount of data transferred is quite large.
|
49
|
+
# Just a heads up when doing queries that potentially return a large number
|
50
|
+
# of results.
|
51
|
+
#
|
52
|
+
# @param opts [Hash] A Hash of filter options.
|
53
|
+
# Possible keys are:
|
54
|
+
#
|
55
|
+
# * `text` - a search term, corresponds to Lucene syntax
|
56
|
+
# * `product` - list of products to scope to. See {#products}.
|
57
|
+
# * `content_format` - list of content formats to scope to. See {#formats}.
|
58
|
+
# * `section` - list of sections to scope to. See {#sections}.
|
59
|
+
# * `site` - list of sites to scope to. See {#sites}.
|
60
|
+
# * `published_after` - only retrieve articles published after a certain
|
61
|
+
# date. The format is `yyyy-mm-dd`.
|
62
|
+
# * `published_before` - only retrieve articles published before a certain
|
63
|
+
# date. The format is `yyyy-mm-dd`.
|
64
|
+
# @return [Array<Hash>] list of articles.
|
65
|
+
def articles(opts)
|
66
|
+
@client.request(:get, "articles", opts)["articles"]
|
67
|
+
end
|
68
|
+
|
69
|
+
# Fetch an article by its CPS_ID
|
70
|
+
#
|
71
|
+
# @param cps_id [String] the cps_id of an article.
|
72
|
+
# @return [Hash] the serialized article.
|
73
|
+
#
|
74
|
+
def article(cps_id)
|
75
|
+
@client.request(:get, "articles/#{cps_id}")["article"]
|
76
|
+
end
|
77
|
+
|
78
|
+
# Fetch articles related (similar) to an article. Uses tf-idf algorithm to
|
79
|
+
# find semantically similar documents.
|
80
|
+
#
|
81
|
+
# @param cps_id [String] the `cps_id` of an article.
|
82
|
+
# @return [Array<Hash>] list of similar articles. Currently capped to 10 most
|
83
|
+
# similar.
|
84
|
+
#
|
85
|
+
def similar_articles(cps_id)
|
86
|
+
@client.request(:get, "articles/#{cps_id}/similar")["results"]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Fetch articles related (similar) to an arbitrary blob of text. Uses tf-idf
|
90
|
+
# algorithm to find semantically similar documents.
|
91
|
+
#
|
92
|
+
# @param text [String] a blob of text.
|
93
|
+
# @return [Array<Hash>] list of similar articles. Currently capped to 10 most
|
94
|
+
# similar.
|
95
|
+
#
|
96
|
+
def similar_to(text)
|
97
|
+
body = { like_text: URI.encode(text) }.to_json
|
98
|
+
@client.request(:post, "similar_to", {}, body)["results"]
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# @author Karl Sutt
|
2
|
+
|
3
|
+
require 'httpi'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
class Juicer
|
7
|
+
class Client
|
8
|
+
# Use HTTPI's nested query builder, which builds the query string in the
|
9
|
+
# "correct" format for Rails, i.e param[]=foo¶m[]=bar.
|
10
|
+
# See https://github.com/savonrb/httpi/pull/126
|
11
|
+
HTTPI.query_builder = :nested
|
12
|
+
|
13
|
+
BASE_PATH = "http://data.bbc.co.uk/bbcrd-juicer"
|
14
|
+
|
15
|
+
# @return [String] API key
|
16
|
+
#
|
17
|
+
attr_reader :api_key
|
18
|
+
|
19
|
+
# Initialize HTTP client
|
20
|
+
#
|
21
|
+
# @param api_key [String] the API key from Apigee
|
22
|
+
# @return [Juicer::Client] HTTP client instance
|
23
|
+
#
|
24
|
+
def initialize(api_key)
|
25
|
+
@api_key = api_key
|
26
|
+
end
|
27
|
+
|
28
|
+
# Internal method for constructing API calls to the Juicer public facing
|
29
|
+
# API. Automatically handles the API key when provided.
|
30
|
+
#
|
31
|
+
# @note Internal method, should not be used directly! See {Juicer} docs
|
32
|
+
# instead.
|
33
|
+
# @note The Juicer API currently only supports `:get` and `:post` values for
|
34
|
+
# the `method` param.
|
35
|
+
# @param method [Symbol] HTTP method.
|
36
|
+
# @param path [String] an endpoint path
|
37
|
+
# @param query_params [Hash] a hash of query parameters. List values are
|
38
|
+
# handled "correctly" in the sense that values of [Array] type produce
|
39
|
+
# `key[]=foo&key[]=bar` style values, suitable for Rails.
|
40
|
+
# @param body [String] body of the request. Makes sense for POST requests.
|
41
|
+
# @return [Hash, Array<Hash>] either a list of results or one result.
|
42
|
+
#
|
43
|
+
def request(method, path, query_params = {}, body = nil)
|
44
|
+
req = HTTPI::Request.new
|
45
|
+
req.url = api_url(path)
|
46
|
+
req.query = { apikey: api_key }.merge(query_params)
|
47
|
+
req.body = body if body
|
48
|
+
req.headers["Accept"] = "application/json"
|
49
|
+
req.headers["Content-Type"] = "application/json"
|
50
|
+
JSON.parse(HTTPI.request(method, req).body)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# Small helper method for sanitizing the `path` for `request` method.
|
56
|
+
#
|
57
|
+
# @param path [String] a path to an endpoint
|
58
|
+
# @return [String] sanitized and fully constructed endpoint URL
|
59
|
+
#
|
60
|
+
def api_url(path)
|
61
|
+
path.sub!(/^\/+/, '')
|
62
|
+
path.sub!(/\/+$/, '')
|
63
|
+
"#{BASE_PATH}/#{path}.json"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Juicer::Client do
|
4
|
+
let(:client) { described_class.new(api_key) }
|
5
|
+
let(:api_key) { "123ABC" }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "sets the API key" do
|
9
|
+
expect(client.api_key).to equal(api_key)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#api_url" do
|
14
|
+
it "drops forward slash" do
|
15
|
+
url = client.send(:api_url, "/foobar")
|
16
|
+
expect(url).to eq("http://data.bbc.co.uk/bbcrd-juicer/foobar.json")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "drops trailing slash" do
|
20
|
+
url = client.send(:api_url, "foobar/")
|
21
|
+
expect(url).to eq("http://data.bbc.co.uk/bbcrd-juicer/foobar.json")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "drops slashes front and back" do
|
25
|
+
url = client.send(:api_url, "//foobar/hello/me//")
|
26
|
+
expect(url).to eq("http://data.bbc.co.uk/bbcrd-juicer/foobar/hello/me.json")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#make_request" do
|
31
|
+
context "HTTP verb handling" do
|
32
|
+
before do
|
33
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/foobar.json")
|
34
|
+
.with(query: { apikey: api_key })
|
35
|
+
.to_return(body: { foobar: "ok" }.to_json)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "constructs the request correctly" do
|
39
|
+
response = client.request(:get, "foobar")
|
40
|
+
expect(response).to be_an_instance_of(Hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "throws exception on invalid verb" do
|
44
|
+
expect { client.request(:invalid, "doesn't matter") }.to raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "params handling" do
|
49
|
+
before do
|
50
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/foobar.json")
|
51
|
+
.with(query: hash_including({ products: ["NewsWeb", "TheGuardian"] }))
|
52
|
+
.to_return(body: { foobar: "ok" }.to_json)
|
53
|
+
end
|
54
|
+
it "constructs the request correctly" do
|
55
|
+
response = client.request(:get, "foobar", { products: ["NewsWeb", "TheGuardian"] })
|
56
|
+
expect(response).to be_an_instance_of(Hash)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/juicer_spec.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Juicer do
|
4
|
+
let(:juicer) { Juicer.new(api_key) }
|
5
|
+
let(:api_key) { "123ABC" }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "creates a HTTP client" do
|
9
|
+
expect(juicer.client).to be_an_instance_of(Juicer::Client)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#sites" do
|
14
|
+
let(:body) { { "sites" => ["site1", "site2", "site3"] } }
|
15
|
+
before do
|
16
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/sites.json")
|
17
|
+
.with(query: { apikey: api_key })
|
18
|
+
.to_return(body: body.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "queries the `sites` endpoint" do
|
22
|
+
response = juicer.sites
|
23
|
+
expect(response).to eq(body["sites"])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#sections" do
|
28
|
+
let(:body) { { "sections" => ["section1", "section2", "section3"] } }
|
29
|
+
before do
|
30
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/sections.json")
|
31
|
+
.with(query: { apikey: api_key })
|
32
|
+
.to_return(body: body.to_json)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "queries the `sections` endpoint" do
|
36
|
+
response = juicer.sections
|
37
|
+
expect(response).to eq(body["sections"])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#products" do
|
42
|
+
let(:body) { { "products" => ["product1", "product2", "product3"] } }
|
43
|
+
before do
|
44
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/products.json")
|
45
|
+
.with(query: { apikey: api_key })
|
46
|
+
.to_return(body: body.to_json)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "queries the `products` endpoint" do
|
50
|
+
response = juicer.products
|
51
|
+
expect(response).to eq(body["products"])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#formats" do
|
56
|
+
let(:body) { { "formats" => ["format1", "format2", "format3"] } }
|
57
|
+
before do
|
58
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/formats.json")
|
59
|
+
.with(query: { apikey: api_key })
|
60
|
+
.to_return(body: body.to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "queries the `formats` endpoint" do
|
64
|
+
response = juicer.formats
|
65
|
+
expect(response).to eq(body["formats"])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#articles" do
|
70
|
+
let(:body) do
|
71
|
+
{ "articles" => [{"title" => "Article title 1" },
|
72
|
+
{"title" => "Article title 2" },
|
73
|
+
{"title" => "Article title 3" }] }
|
74
|
+
end
|
75
|
+
|
76
|
+
before do
|
77
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/articles.json")
|
78
|
+
.with(query: {
|
79
|
+
apikey: api_key,
|
80
|
+
text: "London",
|
81
|
+
product: ["TheGuardian", "NewsWeb"],
|
82
|
+
content_format: ["TextualFormat"],
|
83
|
+
published_after: "2014-09-13",
|
84
|
+
published_before: "2014-10-13" })
|
85
|
+
.to_return(body: body.to_json)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "queries the `articles` endpoint" do
|
89
|
+
response = juicer.articles(text: "London",
|
90
|
+
product: ["TheGuardian", "NewsWeb"],
|
91
|
+
content_format: ["TextualFormat"],
|
92
|
+
published_after: "2014-09-13",
|
93
|
+
published_before: "2014-10-13")
|
94
|
+
expect(response).to eq(body["articles"])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#article" do
|
99
|
+
let(:body) do
|
100
|
+
{ "article" => { "title" => "Article title" } }
|
101
|
+
end
|
102
|
+
let(:cps_id) { "ABCD1234" }
|
103
|
+
|
104
|
+
before do
|
105
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/articles/#{cps_id}.json")
|
106
|
+
.with(query: { apikey: api_key })
|
107
|
+
.to_return(body: body.to_json)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "queries the `article` endpoint" do
|
111
|
+
response = juicer.article(cps_id)
|
112
|
+
expect(response).to eq(body["article"])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#similar_articles" do
|
117
|
+
let(:body) do
|
118
|
+
{ "results" => [{ "title" => "Article title 1" },
|
119
|
+
{ "title" => "Article title 2" }] }
|
120
|
+
end
|
121
|
+
let(:cps_id) { "ABCD1234" }
|
122
|
+
|
123
|
+
before do
|
124
|
+
stub_request(:get, "http://data.bbc.co.uk/bbcrd-juicer/articles/#{cps_id}/similar.json")
|
125
|
+
.with(query: { apikey: api_key })
|
126
|
+
.to_return(body: body.to_json)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "queries the `similar` endpoint" do
|
130
|
+
response = juicer.similar_articles(cps_id)
|
131
|
+
expect(response).to eq(body["results"])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#similar_to" do
|
136
|
+
let(:body) do
|
137
|
+
{ "results" => [{ "title" => "Article title 1" },
|
138
|
+
{ "title" => "Article title 2" }] }
|
139
|
+
end
|
140
|
+
let(:text) { "Some cool text here" }
|
141
|
+
|
142
|
+
before do
|
143
|
+
stub_request(:post, "http://data.bbc.co.uk/bbcrd-juicer/similar_to.json")
|
144
|
+
.with(query: { apikey: api_key },
|
145
|
+
body: { like_text: URI.encode(text) }.to_json)
|
146
|
+
.to_return(body: body.to_json)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "queries the `similar_to` endpoint" do
|
150
|
+
response = juicer.similar_to(text)
|
151
|
+
expect(response).to eq(body["results"])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: juicer-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Karl Sutt
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httpi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.19'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.19'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.8'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: redcarpet
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.2'
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
- karl@sutt.ee
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".ruby-version"
|
121
|
+
- ".yardopts"
|
122
|
+
- Gemfile
|
123
|
+
- LICENSE.txt
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- juicer-client.gemspec
|
127
|
+
- lib/juicer.rb
|
128
|
+
- lib/juicer/client.rb
|
129
|
+
- lib/juicer/version.rb
|
130
|
+
- spec/client_spec.rb
|
131
|
+
- spec/juicer_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: http://juicer.bbcnewslabs.co.uk
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.2.2
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: API client for BBC News Labs Juicer.
|
157
|
+
test_files:
|
158
|
+
- spec/client_spec.rb
|
159
|
+
- spec/juicer_spec.rb
|
160
|
+
- spec/spec_helper.rb
|
161
|
+
has_rdoc:
|