zemanta_client 0.0.1
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +64 -0
- data/Rakefile +1 -0
- data/lib/zemanta.rb +39 -0
- data/lib/zemanta/cache.rb +7 -0
- data/lib/zemanta/cache/disk.rb +21 -0
- data/lib/zemanta/configuration.rb +32 -0
- data/lib/zemanta/configuration/null_storage.rb +12 -0
- data/lib/zemanta/fetcher.rb +36 -0
- data/lib/zemanta/fetcher/cache.rb +33 -0
- data/lib/zemanta/fetcher/cache/key.rb +27 -0
- data/lib/zemanta/fetcher/cache/null_response.rb +11 -0
- data/lib/zemanta/fetcher/cache/response.rb +16 -0
- data/lib/zemanta/fetcher/web.rb +35 -0
- data/lib/zemanta/markup.rb +14 -0
- data/lib/zemanta/markup/link.rb +23 -0
- data/lib/zemanta/markup/link/target.rb +15 -0
- data/lib/zemanta/version.rb +3 -0
- data/spec/fixtures/zemanta/full_response.json +75 -0
- data/spec/fixtures/zemanta/link.json +15 -0
- data/spec/fixtures/zemanta/markup.json +20 -0
- data/spec/fixtures/zemanta/target.json +5 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/zemanta/cache/disk_spec.rb +53 -0
- data/spec/zemanta/configuration/null_storage_spec.rb +13 -0
- data/spec/zemanta/configuration_spec.rb +63 -0
- data/spec/zemanta/fetcher/cache/key_spec.rb +17 -0
- data/spec/zemanta/fetcher/cache/null_response_spec.rb +7 -0
- data/spec/zemanta/fetcher/cache/response_spec.rb +8 -0
- data/spec/zemanta/fetcher/cache_spec.rb +31 -0
- data/spec/zemanta/fetcher/web_spec.rb +8 -0
- data/spec/zemanta/fetcher_spec.rb +16 -0
- data/spec/zemanta/integration/correct_response_spec.rb +57 -0
- data/spec/zemanta/integration/incorrect_api_key_spec.rb +11 -0
- data/spec/zemanta/markup/link/target_spec.rb +19 -0
- data/spec/zemanta/markup/link_spec.rb +48 -0
- data/spec/zemanta/markup_spec.rb +16 -0
- data/spec/zemanta_spec.rb +19 -0
- data/zemanta.gemspec +25 -0
- metadata +171 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 TODO: Write your name
|
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,64 @@
|
|
1
|
+
# Zemanta
|
2
|
+
|
3
|
+
This is a ruby client to awesome Zemanta app. At this point it only supports suggest_markup method and is tested on ruby 1.9.3.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'zemanta_client'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install zemanta_client
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
You need to set api_key to use the client. If you won't do that, gem will raise an error. There are 2 ways:
|
22
|
+
1. Environment variable
|
23
|
+
- Set ZEMANTA_KEY key in you environment variables and gem will use it
|
24
|
+
|
25
|
+
2. Configuration
|
26
|
+
- You can set your api_key in configuration block like this:
|
27
|
+
- Zemanta.configure { |c| c.api_key = 'your_api_key' }
|
28
|
+
|
29
|
+
After your api_key has been set, all you need to do is:
|
30
|
+
|
31
|
+
Zemanta.new("Text you want to send to Zemanta").suggest_markup
|
32
|
+
|
33
|
+
And you will be returned Markup object or error will be raised if Zemanta returns one.
|
34
|
+
|
35
|
+
## Configuration
|
36
|
+
|
37
|
+
There are several configuration options you can set:
|
38
|
+
|
39
|
+
Zemanta.configure do |config|
|
40
|
+
You can pass a hash of custom options that will be passed into each request. It's empty by default.
|
41
|
+
config.custom_request_opts = {}
|
42
|
+
|
43
|
+
Zemanta supports various response formats. However, this client works only with json, so changing this would be rather bad idea.
|
44
|
+
config.format = "json"
|
45
|
+
|
46
|
+
This client supports caching, details below. Default is no caching.
|
47
|
+
config.cache_store = Zemanta::Configuration::NullStorage
|
48
|
+
|
49
|
+
You can pass api_key to zemanta, as described above.
|
50
|
+
config.api_key = "yourapikeyhere"
|
51
|
+
end
|
52
|
+
|
53
|
+
## Caching
|
54
|
+
By default there is no caching. You can pass any cache store to config.cache_store in configuration.
|
55
|
+
The only expectation is that it answers to [] and []= methods. For example, you can pass ruby hash or Cache::Disk.new
|
56
|
+
object to use simple file system storage.
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
1. Fork it
|
61
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
64
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/zemanta.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'active_support/dependencies/autoload'
|
2
|
+
require 'typhoeus'
|
3
|
+
require 'json'
|
4
|
+
require 'digest/md5'
|
5
|
+
|
6
|
+
class Zemanta
|
7
|
+
extend ActiveSupport::Autoload
|
8
|
+
|
9
|
+
autoload :Cache
|
10
|
+
autoload :Configuration
|
11
|
+
autoload :Fetcher
|
12
|
+
autoload :Markup
|
13
|
+
|
14
|
+
def initialize(text)
|
15
|
+
@text = text
|
16
|
+
end
|
17
|
+
|
18
|
+
def suggest_markup(opts = {})
|
19
|
+
Markup.new(suggest_markup_request(opts))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.configure
|
23
|
+
yield config
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.config
|
27
|
+
@configuration ||= Configuration.new
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def suggest_markup_request(opts)
|
33
|
+
@response ||= request({ text: @text, method: "zemanta.suggest_markup" }.merge(opts))['markup']
|
34
|
+
end
|
35
|
+
|
36
|
+
def request(opts)
|
37
|
+
Fetcher.new(opts).post
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Zemanta
|
2
|
+
module Cache
|
3
|
+
class Disk
|
4
|
+
attr_accessor :db
|
5
|
+
|
6
|
+
def initialize(directory='tmp/db')
|
7
|
+
@db = Pathname.new(directory)
|
8
|
+
@db.mkpath
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
file = @db.join(key)
|
13
|
+
file.read if file.exist?
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(key,value)
|
17
|
+
@db.join(key).open('w') {|f| f.write(value.to_s)}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Configuration
|
3
|
+
extend ActiveSupport::Autoload
|
4
|
+
|
5
|
+
autoload :NullStorage
|
6
|
+
|
7
|
+
attr_accessor :custom_request_opts, :format, :api_key, :cache_storage
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@custom_request_opts = {}
|
11
|
+
@format = "json"
|
12
|
+
@cache_storage = NullStorage.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def request_opts
|
16
|
+
{
|
17
|
+
api_key: actual_api_key,
|
18
|
+
format: @format
|
19
|
+
}.merge(@custom_request_opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def end_point
|
23
|
+
"http://api.zemanta.com/services/rest/0.0/"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def actual_api_key
|
29
|
+
@api_key || ENV["ZEMANTA_KEY"] or raise "You need to specify ZEMANTA_KEY in your environment or set api_key in your config"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Fetcher
|
3
|
+
extend ActiveSupport::Autoload
|
4
|
+
|
5
|
+
autoload :Cache
|
6
|
+
autoload :Web
|
7
|
+
|
8
|
+
def initialize(opts = {})
|
9
|
+
@opts = opts
|
10
|
+
end
|
11
|
+
|
12
|
+
def post
|
13
|
+
@response = cache.fetch || web.fetch
|
14
|
+
cache.save(@response)
|
15
|
+
parse(@response)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def cache
|
21
|
+
@cache ||= Cache.new(@opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def web
|
25
|
+
Web.new(request_opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse(data)
|
29
|
+
JSON.parse(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
def request_opts
|
33
|
+
@request_opts ||= Zemanta.config.request_opts.merge(@opts)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Fetcher
|
3
|
+
class Cache
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :NullResponse
|
7
|
+
autoload :Response
|
8
|
+
autoload :Key
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@key = Key.new(opts).to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch
|
15
|
+
fetch_from_storage(@key).to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def save(response)
|
19
|
+
storage[@key] = Response.new(response) unless storage[@key]
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def storage
|
25
|
+
Zemanta.config.cache_storage
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_from_storage(opts)
|
29
|
+
storage[@key] || NullResponse.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Fetcher
|
3
|
+
class Cache
|
4
|
+
class Key
|
5
|
+
def initialize(value)
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
if @value.is_a?(String)
|
11
|
+
digest(@value)
|
12
|
+
elsif @value.is_a?(Hash)
|
13
|
+
digest(@value.sort.to_s)
|
14
|
+
else
|
15
|
+
raise "You are trying to use #{@value.class} as cache key. Only Strings and Hashes are supported."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def digest(value)
|
22
|
+
Digest::MD5.hexdigest(value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Fetcher
|
3
|
+
class Web
|
4
|
+
def initialize(opts = {})
|
5
|
+
@opts = opts
|
6
|
+
end
|
7
|
+
|
8
|
+
def fetch
|
9
|
+
if http_fetch == zemanta_error_response
|
10
|
+
raise_api_key_exception!
|
11
|
+
else
|
12
|
+
http_fetch
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def http_fetch
|
19
|
+
@response ||= Typhoeus.post(url, params: @opts).response_body
|
20
|
+
end
|
21
|
+
|
22
|
+
def zemanta_error_response
|
23
|
+
'<h1>403 Developer Inactive</h1>'
|
24
|
+
end
|
25
|
+
|
26
|
+
def raise_api_key_exception!
|
27
|
+
raise "Zemanta returned '#{zemanta_error_response}' exception. Quite possibly you passed incorrect api_key."
|
28
|
+
end
|
29
|
+
|
30
|
+
def url
|
31
|
+
Zemanta.config.end_point
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Zemanta
|
2
|
+
class Markup
|
3
|
+
class Link
|
4
|
+
extend ActiveSupport::Autoload
|
5
|
+
|
6
|
+
autoload :Target
|
7
|
+
|
8
|
+
attr_reader :relevance, :confidence, :entity_type, :target, :anchor
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@relevance = opts["relevance"]
|
12
|
+
@confidence = opts["confidence"]
|
13
|
+
@entity_type = opts["entity_type"]
|
14
|
+
@target = opts["target"].map{ |opts| Target.new(opts) }
|
15
|
+
@anchor = opts["anchor"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def above?(relevance, confidence)
|
19
|
+
@relevance >= relevance and @confidence >= confidence
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
{
|
2
|
+
"status": "ok",
|
3
|
+
"articles": [
|
4
|
+
{
|
5
|
+
"confidence": 0.00114,
|
6
|
+
"published_datetime": "2013-02-23T06:39:14Z",
|
7
|
+
"title": "Tiananmen Square- Forbidden City- Summer Palace - Beijing, China",
|
8
|
+
"url": "http://blog.travelpod.com/travel-blog-entries/peregrinations/1/1315695831/tpod.html",
|
9
|
+
"retweets": 0,
|
10
|
+
"text_preview": "Tiananmen Square- Forbidden City- Summer Palace - Beijing, China\nBeijing, China\nThis was our last day of touring and it was by far the most arduous of the whole trip. I have no idea how anyone can do this in the heat and humidity of July and August. It was just the end of May and the heat did me in. Even though our guide took a very leisurely pace...",
|
11
|
+
"article_id": 147457867,
|
12
|
+
"zemified": 0
|
13
|
+
}
|
14
|
+
],
|
15
|
+
"markup": {
|
16
|
+
"text": "",
|
17
|
+
"links": [
|
18
|
+
{
|
19
|
+
"relevance": 0.8093,
|
20
|
+
"confidence": 0.873863,
|
21
|
+
"entity_type": [
|
22
|
+
"/location/location"
|
23
|
+
],
|
24
|
+
"target": [
|
25
|
+
{
|
26
|
+
"url": "http://maps.google.com/maps?ll=27.2359361111,100.132480556&spn=0.01,0.01&q=27.2359361111,100.132480556 (Tiger%20Leaping%20Gorge)&t=h",
|
27
|
+
"type": "geolocation",
|
28
|
+
"title": "Tiger Leaping Gorge"
|
29
|
+
}
|
30
|
+
],
|
31
|
+
"anchor": "Tiger Leaping Gorge"
|
32
|
+
}
|
33
|
+
]
|
34
|
+
},
|
35
|
+
"images": [
|
36
|
+
{
|
37
|
+
"url_m_h": 240,
|
38
|
+
"confidence": 0.5,
|
39
|
+
"url_s_h": 75,
|
40
|
+
"attribution": "Naxi Horseman (Photo credit: <a href=\"http://www.flickr.com/photos/85904220@N00/3182514166\">Renato @ Mainland China</a>)",
|
41
|
+
"description": "Naxi Horseman",
|
42
|
+
"license": "License CreativeCommons NonCommercial NoDerivs",
|
43
|
+
"url_l_w": 365,
|
44
|
+
"url_s": "http://farm4.static.flickr.com/3115/3182514166_186de79cab_s.jpg",
|
45
|
+
"source_url": "http://www.flickr.com/photos/85904220@N00/3182514166",
|
46
|
+
"url_m": "http://farm4.static.flickr.com/3115/3182514166_186de79cab_m.jpg",
|
47
|
+
"url_l": "http://farm4.static.flickr.com/3115/3182514166_186de79cab.jpg",
|
48
|
+
"url_l_h": 500,
|
49
|
+
"url_s_w": 75,
|
50
|
+
"url_m_w": 175
|
51
|
+
}
|
52
|
+
],
|
53
|
+
"signature": "<div class=\"zemanta-pixie\"><a class=\"zemanta-pixie-a\" href=\"http://www.zemanta.com/?px\" title=\"Enhanced by Zemanta\"><img class=\"zemanta-pixie-img\" src=\"http://img.zemanta.com/zemified_e.png?x-id=27556886-7e10-4b64-8bff-9fa4352fd524\" alt=\"Enhanced by Zemanta\" /></a></div>",
|
54
|
+
"keywords": [
|
55
|
+
{
|
56
|
+
"confidence": 0.267918,
|
57
|
+
"scheme": "general",
|
58
|
+
"name": "Beijing"
|
59
|
+
}
|
60
|
+
],
|
61
|
+
"rid": "27556886-7e10-4b64-8bff-9fa4352fd524",
|
62
|
+
"categories": [],
|
63
|
+
"rich_objects": [
|
64
|
+
{
|
65
|
+
"title": "Tiananmen Square",
|
66
|
+
"url": "http://maps.google.com/maps?ll=39.9033333333,116.391666667&spn=0.01,0.01&q=39.9033333333,116.391666667 (Tiananmen%20Square)&t=h",
|
67
|
+
"thumbnail_width": 75,
|
68
|
+
"height": 250,
|
69
|
+
"width": 300,
|
70
|
+
"html": "<iframe width=\"300\" height=\"250\" frameborder=\"0\" scrolling=\"no\" marginheight=\"0\" marginwidth=\"0\" src=\"http://maps.google.com/?ie=UTF8&center=39.9033333333,116.391666667&spn=0.01,0.01&q=39.9033333333,116.391666667 (Tiananmen%20Square)&t=h&output=embed&sensor=false&s=AARTsJqzARj-Z8VnW5pkPMLMmZbqrJcYpw\"></iframe><br/><small><a href=\"http://maps.google.com/?ie=UTF8&center=39.9033333333,116.391666667&spn=0.01,0.01&q=39.9033333333,116.391666667 (Tiananmen%20Square)&t=h&source=embed&sensor=false\" style=\"color:#0000FF;text-align:left\">View Larger Map</a></small>",
|
71
|
+
"thumbnail_height": 75,
|
72
|
+
"thumbnail_url": "http://maps.google.com/staticmap?size=300x250&sensor=false¢er=39.9033333333,116.391666667&zoom=15"
|
73
|
+
}
|
74
|
+
]
|
75
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"relevance": 0.8093,
|
3
|
+
"confidence": 0.873863,
|
4
|
+
"entity_type": [
|
5
|
+
"/location/location"
|
6
|
+
],
|
7
|
+
"target": [
|
8
|
+
{
|
9
|
+
"url": "www.this.is.an/url",
|
10
|
+
"type": "geolocation",
|
11
|
+
"title": "Tiger Leaping Gorge"
|
12
|
+
}
|
13
|
+
],
|
14
|
+
"anchor": "Tiger Leaping Gorge"
|
15
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"text": "text",
|
3
|
+
"links": [
|
4
|
+
{
|
5
|
+
"relevance": 0.8093,
|
6
|
+
"confidence": 0.873863,
|
7
|
+
"entity_type": [
|
8
|
+
"/location/location"
|
9
|
+
],
|
10
|
+
"target": [
|
11
|
+
{
|
12
|
+
"url": "www.this.is.an/url",
|
13
|
+
"type": "geolocation",
|
14
|
+
"title": "Tiger Leaping Gorge"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"anchor": "Tiger Leaping Gorge"
|
18
|
+
}
|
19
|
+
]
|
20
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'zemanta'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
|
4
|
+
Zemanta.configure do |c|
|
5
|
+
c.api_key = 'fake_key'
|
6
|
+
end
|
7
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
8
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
9
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
10
|
+
# loaded once.
|
11
|
+
#
|
12
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
|
18
|
+
# Run specs in random order to surface order dependencies. If you find an
|
19
|
+
# order dependency and want to debug it, you can fix the order by providing
|
20
|
+
# the seed, which is printed after each run.
|
21
|
+
# --seed 1234
|
22
|
+
config.order = 'random'
|
23
|
+
end
|
24
|
+
|
25
|
+
def fixture(path)
|
26
|
+
JSON.parse(File.read("spec/fixtures/zemanta/#{path}.json"))
|
27
|
+
end
|
28
|
+
|
29
|
+
def stub_zemanta_success!
|
30
|
+
stub_request(:post, /api.zemanta.com/).
|
31
|
+
to_return(:status => 200, :body => "{\"response\":\"zemanta_response\"}").times(1).then.
|
32
|
+
to_return(:status => 404)
|
33
|
+
end
|
34
|
+
|
35
|
+
def stub_zemanta_full!
|
36
|
+
stub_request(:post, /api.zemanta.com/).
|
37
|
+
to_return(:status => 200, :body => {markup: fixture("markup")}.to_json)
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_zemanta_exception!
|
41
|
+
stub_request(:post, /api.zemanta.com/).
|
42
|
+
to_return(:status => 200, :body => '<h1>403 Developer Inactive</h1>')
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Cache::Disk do
|
4
|
+
let(:cache) { Zemanta::Cache::Disk }
|
5
|
+
let(:storage) { cache.new }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "creates directory to store files if one doesnt exist" do
|
9
|
+
temp_dir = Pathname.new('spec/temp_dir')
|
10
|
+
temp_dir.delete if temp_dir.exist?
|
11
|
+
temp_dir.should_not exist
|
12
|
+
|
13
|
+
cache.new(temp_dir)
|
14
|
+
temp_dir.should exist
|
15
|
+
temp_dir.delete
|
16
|
+
end
|
17
|
+
|
18
|
+
it "uses tmp/db as default directory" do
|
19
|
+
storage.db.should == Pathname.new('tmp/db')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#[key]" do
|
24
|
+
it "returns nil if key doesnt exist" do
|
25
|
+
storage['non-existing-key'].should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns stored value if the key exists" do
|
29
|
+
value = "string data"
|
30
|
+
storage['key'] = value
|
31
|
+
storage['key'].should == value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#[key]=" do
|
36
|
+
let(:key) { 'some-key' }
|
37
|
+
let(:value) { 'text-value' }
|
38
|
+
|
39
|
+
it "creates new file for specified key" do
|
40
|
+
Pathname.new(storage.db.join(key)).delete
|
41
|
+
Pathname.new(storage.db.join(key)).should_not exist
|
42
|
+
|
43
|
+
storage[key] = value
|
44
|
+
Pathname.new(storage.db.join(key)).should exist
|
45
|
+
end
|
46
|
+
|
47
|
+
it "overwrites existing file for specified key" do
|
48
|
+
storage[key] = value
|
49
|
+
storage[key] = "new value"
|
50
|
+
storage[key].should == "new value"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Fetcher::Web do
|
4
|
+
subject { Zemanta::Configuration::NullStorage.new }
|
5
|
+
|
6
|
+
it "returns nil on #[]" do
|
7
|
+
subject[:key].should be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it "responds to #save" do
|
11
|
+
subject.should respond_to :[]=
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Configuration do
|
4
|
+
subject { Zemanta::Configuration.new }
|
5
|
+
|
6
|
+
describe "getter" do
|
7
|
+
it "gets custom_request_opts" do
|
8
|
+
subject.custom_request_opts.should == {}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "gets format" do
|
12
|
+
subject.format.should == "json"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "gets api_key" do
|
16
|
+
subject.api_key.should == nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gets cache_storage" do
|
20
|
+
subject.cache_storage.should be_a Zemanta::Configuration::NullStorage
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "setter" do
|
25
|
+
it "sets custom_request_opts" do
|
26
|
+
subject.custom_request_opts = {target_types: "geolocation"}
|
27
|
+
subject.custom_request_opts.should == {target_types: "geolocation"}
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sets format" do
|
31
|
+
subject.format = "xml"
|
32
|
+
subject.format.should == "xml"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "sets api_key" do
|
36
|
+
subject.api_key = "key"
|
37
|
+
subject.api_key.should == "key"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sets cache_storage" do
|
41
|
+
subject.cache_storage = {}
|
42
|
+
subject.cache_storage.should == {}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "knows the end_point" do
|
47
|
+
subject.end_point.should == "http://api.zemanta.com/services/rest/0.0/"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can build the request_opts" do
|
51
|
+
subject.stub(:actual_api_key).and_return("api_key")
|
52
|
+
subject.request_opts.should == {
|
53
|
+
api_key: "api_key",
|
54
|
+
format: "json"
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "custom_request_opts into request_opts" do
|
59
|
+
subject.stub(:actual_api_key).and_return("api_key")
|
60
|
+
subject.custom_request_opts = {target_types: "geolocation"}
|
61
|
+
subject.request_opts[:target_types].should == "geolocation"
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Fetcher::Cache::Key do
|
4
|
+
it "returns string by #to_s, given string" do
|
5
|
+
Zemanta::Fetcher::Cache::Key.new("").to_s.should be_a String
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns string by #to_s, given hash" do
|
9
|
+
Zemanta::Fetcher::Cache::Key.new({}).to_s.should be_a String
|
10
|
+
end
|
11
|
+
|
12
|
+
it "creates identical values for hashes with different order" do
|
13
|
+
key_1 = Zemanta::Fetcher::Cache::Key.new({key: "value", awesomeness: "high"})
|
14
|
+
key_2 = Zemanta::Fetcher::Cache::Key.new({awesomeness: "high", key: "value"})
|
15
|
+
key_1.to_s.should == key_2.to_s
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Fetcher::Cache do
|
4
|
+
describe "for set storage" do
|
5
|
+
before :each do
|
6
|
+
Zemanta.configure { |config| config.cache_storage = {} }
|
7
|
+
Zemanta::Fetcher::Cache.new("key").save("test data")
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
Zemanta.configure { |config| config.cache_storage = Zemanta::Configuration::NullStorage.new }
|
12
|
+
end
|
13
|
+
|
14
|
+
it "saves the data to cache if it's saved first time" do
|
15
|
+
Zemanta.config.cache_storage.size.should == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
it "doesn't save the data if same key was used before" do
|
19
|
+
Zemanta::Fetcher::Cache.new("key").save("test data")
|
20
|
+
Zemanta.config.cache_storage.size.should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "fetch returns nil if no key in cache" do
|
24
|
+
Zemanta::Fetcher::Cache.new("another_key").fetch.should be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "fetch returns the value data if key is present" do
|
28
|
+
Zemanta::Fetcher::Cache.new("key").fetch.should == "test data"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Fetcher do
|
4
|
+
it "returns the value in cache, if there is one" do
|
5
|
+
Zemanta.configure { |config| config.cache_storage = {} }
|
6
|
+
stub_zemanta_success!
|
7
|
+
subject.post
|
8
|
+
subject.post.should == {"response"=>"zemanta_response"}
|
9
|
+
Zemanta.configure { |config| config.cache_storage = Zemanta::Configuration::NullStorage.new }
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the value in web, if there is no cache" do
|
13
|
+
stub_zemanta_success!
|
14
|
+
subject.post.should == {"response"=>"zemanta_response"}
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "suggest_markup" do
|
4
|
+
before(:each) do
|
5
|
+
stub_zemanta_full!
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:markup) { Zemanta.new("some text").suggest_markup }
|
9
|
+
|
10
|
+
it "responds to #text" do
|
11
|
+
markup.text.should == "text"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "responds to #links" do
|
15
|
+
markup.links.should be_a Array
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".links.first" do
|
19
|
+
let(:link) { markup.links.first }
|
20
|
+
|
21
|
+
it "responds to #relevance" do
|
22
|
+
link.relevance.should == 0.8093
|
23
|
+
end
|
24
|
+
|
25
|
+
it "responds to #confidence" do
|
26
|
+
link.confidence.should == 0.873863
|
27
|
+
end
|
28
|
+
|
29
|
+
it "responds to #entity_type" do
|
30
|
+
link.entity_type.should == ["/location/location"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "responds to #target" do
|
34
|
+
link.target.should be_a Array
|
35
|
+
end
|
36
|
+
|
37
|
+
it "responds to #anchor" do
|
38
|
+
link.anchor.should == "Tiger Leaping Gorge"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".target.first" do
|
42
|
+
let(:target) { link.target.first }
|
43
|
+
|
44
|
+
it "answers to #url" do
|
45
|
+
target.url.should == "www.this.is.an/url"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "answers to #type" do
|
49
|
+
target.type.should == "geolocation"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "answers to #title" do
|
53
|
+
target.title.should == "Tiger Leaping Gorge"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "incorrect api key" do
|
5
|
+
let(:markup) { Zemanta.new("some text").suggest_markup }
|
6
|
+
|
7
|
+
it "raises exception when 403 error returned" do
|
8
|
+
stub_zemanta_exception!
|
9
|
+
expect { markup }.to raise_error("Zemanta returned '<h1>403 Developer Inactive</h1>' exception. Quite possibly you passed incorrect api_key.")
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Markup::Link::Target do
|
4
|
+
describe "getter" do
|
5
|
+
subject { Zemanta::Markup::Link::Target.new(fixture("target")) }
|
6
|
+
|
7
|
+
it "for url works well" do
|
8
|
+
subject.url.should == "www.this.is.an/url"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "for type works well" do
|
12
|
+
subject.type.should == "geolocation"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "for target title works well" do
|
16
|
+
subject.title.should == "Tiger Leaping Gorge"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Markup::Link do
|
4
|
+
describe "getter" do
|
5
|
+
subject { Zemanta::Markup::Link.new(fixture("link")) }
|
6
|
+
|
7
|
+
describe "getter" do
|
8
|
+
it "for relevance works well" do
|
9
|
+
subject.relevance.should == 0.8093
|
10
|
+
end
|
11
|
+
|
12
|
+
it "for confidence works well" do
|
13
|
+
subject.confidence.should == 0.873863
|
14
|
+
end
|
15
|
+
|
16
|
+
it "for entity title works well" do
|
17
|
+
subject.entity_type.should == ["/location/location"]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "for target returns array of targets" do
|
21
|
+
subject.target.should be_a Array
|
22
|
+
subject.target.first.should be_a Zemanta::Markup::Link::Target
|
23
|
+
end
|
24
|
+
|
25
|
+
it "for anchor works well" do
|
26
|
+
subject.anchor.should == "Tiger Leaping Gorge"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "above?" do
|
31
|
+
it "returns true if is above both relevance and confidence" do
|
32
|
+
subject.above?(0.5, 0.5).should == true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns false if relevance is lower" do
|
36
|
+
subject.above?(0.9, 0.5).should == false
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns false if confidence is lower" do
|
40
|
+
subject.above?(0.5, 0.9).should == false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns false if both confidence and relevance is lower" do
|
44
|
+
subject.above?(0.9, 0.9).should == false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta::Markup do
|
4
|
+
describe "getter" do
|
5
|
+
subject { Zemanta::Markup.new(fixture("markup")) }
|
6
|
+
|
7
|
+
it "for text works well" do
|
8
|
+
subject.text.should == "text"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "for links returns array of links" do
|
12
|
+
subject.links.should be_a Array
|
13
|
+
subject.links.first.should be_a Zemanta::Markup::Link
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Zemanta do
|
4
|
+
it "makes request with text and method params on #suggest_markup" do
|
5
|
+
context = Zemanta.new("This is a text")
|
6
|
+
context.stub(:suggest_markup_request) { fixture("markup") }
|
7
|
+
context.suggest_markup.should be_a Zemanta::Markup
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns Configuration instance on Zemanta.config" do
|
11
|
+
Zemanta.config.should be_a Zemanta::Configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
it "passes Configuration instance to block on Zemanta.configure" do
|
15
|
+
Zemanta.configure do |config|
|
16
|
+
config.should be_a Zemanta::Configuration
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/zemanta.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'zemanta/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "zemanta_client"
|
8
|
+
gem.version = Zemanta::VERSION
|
9
|
+
gem.authors = ["Łukasz Strzebińczyk"]
|
10
|
+
gem.email = ["l.strzebinczyk@gorailsgo.com"]
|
11
|
+
gem.description = "This is a ruby client for Zemanta api."
|
12
|
+
gem.summary = "This is a ruby client for Zemanta api."
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "typhoeus"
|
21
|
+
gem.add_dependency "activesupport"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "webmock"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zemanta_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Łukasz Strzebińczyk
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: typhoeus
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: webmock
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: This is a ruby client for Zemanta api.
|
79
|
+
email:
|
80
|
+
- l.strzebinczyk@gorailsgo.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- lib/zemanta.rb
|
91
|
+
- lib/zemanta/cache.rb
|
92
|
+
- lib/zemanta/cache/disk.rb
|
93
|
+
- lib/zemanta/configuration.rb
|
94
|
+
- lib/zemanta/configuration/null_storage.rb
|
95
|
+
- lib/zemanta/fetcher.rb
|
96
|
+
- lib/zemanta/fetcher/cache.rb
|
97
|
+
- lib/zemanta/fetcher/cache/key.rb
|
98
|
+
- lib/zemanta/fetcher/cache/null_response.rb
|
99
|
+
- lib/zemanta/fetcher/cache/response.rb
|
100
|
+
- lib/zemanta/fetcher/web.rb
|
101
|
+
- lib/zemanta/markup.rb
|
102
|
+
- lib/zemanta/markup/link.rb
|
103
|
+
- lib/zemanta/markup/link/target.rb
|
104
|
+
- lib/zemanta/version.rb
|
105
|
+
- spec/fixtures/zemanta/full_response.json
|
106
|
+
- spec/fixtures/zemanta/link.json
|
107
|
+
- spec/fixtures/zemanta/markup.json
|
108
|
+
- spec/fixtures/zemanta/target.json
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
- spec/zemanta/cache/disk_spec.rb
|
111
|
+
- spec/zemanta/configuration/null_storage_spec.rb
|
112
|
+
- spec/zemanta/configuration_spec.rb
|
113
|
+
- spec/zemanta/fetcher/cache/key_spec.rb
|
114
|
+
- spec/zemanta/fetcher/cache/null_response_spec.rb
|
115
|
+
- spec/zemanta/fetcher/cache/response_spec.rb
|
116
|
+
- spec/zemanta/fetcher/cache_spec.rb
|
117
|
+
- spec/zemanta/fetcher/web_spec.rb
|
118
|
+
- spec/zemanta/fetcher_spec.rb
|
119
|
+
- spec/zemanta/integration/correct_response_spec.rb
|
120
|
+
- spec/zemanta/integration/incorrect_api_key_spec.rb
|
121
|
+
- spec/zemanta/markup/link/target_spec.rb
|
122
|
+
- spec/zemanta/markup/link_spec.rb
|
123
|
+
- spec/zemanta/markup_spec.rb
|
124
|
+
- spec/zemanta_spec.rb
|
125
|
+
- zemanta.gemspec
|
126
|
+
homepage: ''
|
127
|
+
licenses: []
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 1.8.24
|
147
|
+
signing_key:
|
148
|
+
specification_version: 3
|
149
|
+
summary: This is a ruby client for Zemanta api.
|
150
|
+
test_files:
|
151
|
+
- spec/fixtures/zemanta/full_response.json
|
152
|
+
- spec/fixtures/zemanta/link.json
|
153
|
+
- spec/fixtures/zemanta/markup.json
|
154
|
+
- spec/fixtures/zemanta/target.json
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
- spec/zemanta/cache/disk_spec.rb
|
157
|
+
- spec/zemanta/configuration/null_storage_spec.rb
|
158
|
+
- spec/zemanta/configuration_spec.rb
|
159
|
+
- spec/zemanta/fetcher/cache/key_spec.rb
|
160
|
+
- spec/zemanta/fetcher/cache/null_response_spec.rb
|
161
|
+
- spec/zemanta/fetcher/cache/response_spec.rb
|
162
|
+
- spec/zemanta/fetcher/cache_spec.rb
|
163
|
+
- spec/zemanta/fetcher/web_spec.rb
|
164
|
+
- spec/zemanta/fetcher_spec.rb
|
165
|
+
- spec/zemanta/integration/correct_response_spec.rb
|
166
|
+
- spec/zemanta/integration/incorrect_api_key_spec.rb
|
167
|
+
- spec/zemanta/markup/link/target_spec.rb
|
168
|
+
- spec/zemanta/markup/link_spec.rb
|
169
|
+
- spec/zemanta/markup_spec.rb
|
170
|
+
- spec/zemanta_spec.rb
|
171
|
+
has_rdoc:
|