evri 0.03

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/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 0.0.1 / 2008-09-25
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ TODO
6
+ evri-api.gemspec
7
+ lib/evri.rb
8
+ lib/evri/entity.rb
9
+ lib/evri/media.rb
10
+ lib/evri/relation.rb
11
+ lib/evri/zeitgeist.rb
12
+ test/test_entity.rb
13
+ test/test_evri.rb
14
+ test/test_media.rb
15
+ test/test_zeitgeist.rb
data/README.txt ADDED
@@ -0,0 +1,48 @@
1
+ = evri-api
2
+
3
+ * http://github.com/joevandyk/evri-api
4
+
5
+ == DESCRIPTION:
6
+
7
+ A beautiful API that wraps the RESTful services provided by evri.com.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ None yet.
12
+
13
+ == SYNOPSIS:
14
+
15
+ None yet.
16
+
17
+ == REQUIREMENTS:
18
+
19
+ none yet.
20
+
21
+ == INSTALL:
22
+
23
+ gem install evri-api
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2008 Joe Van Dyk
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/evri.rb'
6
+
7
+ Hoe.new('evri', Evri::VERSION) do |p|
8
+ p.rubyforge_name = 'evri-api'
9
+ p.developer('Joe Van Dyk', 'joe@@fixieconsulting.com')
10
+ p.extra_deps = [:json]
11
+ p.extra_dev_deps = [:mocha]
12
+ end
13
+
14
+ task :github do
15
+ data = `rake check_manifest | sed 1d`
16
+ IO.popen("patch -p0 Manifest.txt", "w") do |p|
17
+ p << data
18
+ end
19
+ `rake debug_gem | sed 1d > evri-api.gemspec`
20
+ end
21
+
22
+ # vim: syntax=Ruby
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ STUFF LEFT TO DO
2
+
3
+ * Handle Query Tokens
4
+ - QTs are initially generated here:
5
+ - query token for whole medias/entity document
6
+ - query token for each entity in the returned results of ^
7
+ - query token for each pair of entities in above ^
8
+ - Then pass them into the calls that can take them (and handle the returned QTs)
9
+
10
+ * Refactor code to make Resource and JSON handling flexible (after API is done)
11
+
12
+ * Ability to batch requests (via threading)
13
+ - see how facebooker does it
data/evri-api.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{evri}
3
+ s.version = "0.03"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Joe Van Dyk"]
7
+ s.date = %q{2008-10-27}
8
+ s.description = %q{A beautiful API that wraps the RESTful services provided by evri.com.}
9
+ s.email = ["joe@@fixieconsulting.com"]
10
+ s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
11
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "TODO", "evri-api.gemspec", "lib/evri.rb", "lib/evri/entity.rb", "lib/evri/media.rb", "lib/evri/relation.rb", "lib/evri/zeitgeist.rb", "test/test_entity.rb", "test/test_evri.rb", "test/test_media.rb", "test/test_zeitgeist.rb"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/joevandyk/evri-api}
14
+ s.rdoc_options = ["--main", "README.txt"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{evri}
17
+ s.rubygems_version = %q{1.2.0}
18
+ s.summary = %q{A beautiful API that wraps the RESTful services provided by evri.com.}
19
+ s.test_files = ["test/test_media.rb", "test/test_zeitgeist.rb", "test/test_entity.rb", "test/test_evri.rb"]
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if current_version >= 3 then
26
+ s.add_runtime_dependency(%q<json>, [">= 0"])
27
+ s.add_development_dependency(%q<mocha>, [">= 0"])
28
+ s.add_development_dependency(%q<hoe>, [">= 1.7.0"])
29
+ else
30
+ s.add_dependency(%q<json>, [">= 0"])
31
+ s.add_dependency(%q<mocha>, [">= 0"])
32
+ s.add_dependency(%q<hoe>, [">= 1.7.0"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<json>, [">= 0"])
36
+ s.add_dependency(%q<mocha>, [">= 0"])
37
+ s.add_dependency(%q<hoe>, [">= 1.7.0"])
38
+ end
39
+ end
@@ -0,0 +1,240 @@
1
+ module Evri
2
+ # Represents an Evri Entity.
3
+ class Entity
4
+ attr_reader :properties
5
+
6
+ # Finds a specific entity, given an ID.
7
+ def self.find id
8
+ @entended_properties = true
9
+ @results ||= {}
10
+ id = "/" + id unless id =~ /\A\//
11
+ return @results[id] if @results[id]
12
+ @results[id] = create_from_json do
13
+ Evri.query(:type => :uri, :query => id)
14
+ end
15
+ end
16
+
17
+ # Searches for an exact match.
18
+ def self.search name
19
+ create_from_jsons do
20
+ Evri.query(:type => :search, :query => name)
21
+ end
22
+ end
23
+
24
+ # Searches for a partial match. i.e. 'ob' will return 'Obama'.
25
+ def self.search_by_prefix prefix
26
+ create_from_jsons do
27
+ Evri.query(:type => :prefix, :query => prefix)
28
+ end
29
+ end
30
+
31
+ # Given a :uri and :text options, return the related entities.
32
+ def self.from_media options={}
33
+ uri, text = options[:uri], options[:text]
34
+ raise ArgumentError, "Must specify URI via the :uri option" unless uri
35
+ raise ArgumentError, "Must specify some text via the :text option" unless text
36
+
37
+ json = Evri.parse_json(Evri.query(:type => :from_media, :uri => uri, :text => text))
38
+ json["graph"]["entities"].map do |e, entity_json|
39
+ Entity.new entity_json
40
+ end
41
+ end
42
+
43
+ # Returns where the information for this entity came from.
44
+ def source_url
45
+ @source_url
46
+ end
47
+
48
+ # Returns information about an entity.
49
+ # i.e obama.info(:birth_date)
50
+ def info option=nil
51
+ @properties ||= {}
52
+ if defined?(@extended_properties)
53
+ if option
54
+ @properties[option]
55
+ else
56
+ @properties
57
+ end
58
+ else
59
+ @properties = Entity.find(uri).properties
60
+ @extended_properties = true
61
+ info(option)
62
+ end
63
+ end
64
+
65
+ def to_s
66
+ "#{name} (#{ id })"
67
+ end
68
+
69
+ def inspect
70
+ "#<Evri::Entity:#{to_s}>"
71
+ end
72
+
73
+ # Returns the name of the entity
74
+ def name
75
+ @parsed_json["name"]["$"] || @parsed_json["name"]
76
+ end
77
+
78
+ def initialize json
79
+ @parsed_json = json
80
+ @relations = []
81
+ @source_url = Evri.source_url
82
+ if json["properties"]
83
+ set_properties json["properties"]
84
+ end
85
+ end
86
+
87
+ def == b
88
+ self.id == b.id
89
+ end
90
+
91
+ # Returns the Evri URI of the entity
92
+ def href
93
+ @parsed_json["@href"]
94
+ end
95
+
96
+ alias id href
97
+ alias uri href
98
+
99
+ # TODO
100
+ def target_href
101
+ @parsed_json["@targetHref"]
102
+ end
103
+
104
+ # Returns relationships for the entity
105
+ def relations options={}
106
+ from_domains = nil
107
+ if options[:from]
108
+ if options[:from].class == String
109
+ from_domains = options[:from]
110
+ else
111
+ from_domains = options[:from].join(',')
112
+ end
113
+ end
114
+ json = Evri.query(:type => :relations, :query => id, :from_domains => from_domains)
115
+ Evri.parse_json(json)["relations"].each do |type, relation_json|
116
+ next if type != 'relation'
117
+ relation_json.each do |r|
118
+ @relations << Relation.new(r)
119
+ end
120
+ end
121
+ @relations
122
+ end
123
+
124
+ # Returns which entities are related to the current entity
125
+ def related_by options={}
126
+ media, verb, verb_value, entity, uri = nil, nil, nil, nil, nil
127
+ options.each do |key, value|
128
+ if key == :entity
129
+ entity = value
130
+ elsif key == :uri
131
+ uri = value
132
+ elsif key == :type
133
+ media = value
134
+ else
135
+ verb = key
136
+ verb_value = value
137
+ end
138
+ end
139
+ @entities = []
140
+ json = Evri.query(:type => :related_by, :media => media, :query => id, :uri => uri, :entity => entity, :verb => verb, :value => verb_value)
141
+ Evri.parse_json(json)["relations"].each do |type, relation_json|
142
+ next if type != 'relation'
143
+ relation_json["targets"].each do |type, r|
144
+ r.each do |entity|
145
+ if entity.class == Hash
146
+ if entity["@href"]
147
+ @entities << Entity.new(entity)
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
153
+ @entities
154
+ end
155
+
156
+ # Returns images relating to the current entity
157
+ def images options={}
158
+ medias = []
159
+ if options[:entities]
160
+ entity_uris = options[:entities].map do |e|
161
+ if e.class == Evri::Entity
162
+ e.uri
163
+ else
164
+ e
165
+ end
166
+ end
167
+ end
168
+
169
+ json = Evri.parse_json(Evri.query(:type => :related_medias, :query => href, :entities => entity_uris, :media => 'image'))
170
+ # TODO handle images here
171
+ if json["mediaResult"]["imageList"]
172
+ json["mediaResult"]["imageList"]["image"].each do |media_json|
173
+ medias << Image.new(media_json)
174
+ end
175
+ end
176
+ medias
177
+ end
178
+
179
+ # Returns articles relating to the current entity
180
+ def articles options={}
181
+ medias = []
182
+ if options[:entities]
183
+ entity_uris = options[:entities].map do |e|
184
+ if e.class == Evri::Entity
185
+ e.uri
186
+ else
187
+ e
188
+ end
189
+ end
190
+ end
191
+
192
+ type = options[:type] ? options[:type] : nil
193
+ json = Evri.parse_json(Evri.query(:type => :related_medias, :query => href, :entities => entity_uris, :media => type))
194
+ if json["mediaResult"]["articleList"]
195
+ json["mediaResult"]["articleList"]["article"].each do |media_json|
196
+ medias << Article.new(media_json)
197
+ end
198
+ end
199
+ medias
200
+ end
201
+
202
+
203
+ private
204
+
205
+ def self.create_from_json json=nil, &block
206
+ begin
207
+ json = block.call if block
208
+ Entity.new Evri.parse_json(json)["entity"]
209
+ rescue Evri::Error => e
210
+ raise Evri::EntityNotFound.new(e.message)
211
+ end
212
+ end
213
+
214
+ def self.create_from_jsons jsons=nil, &block
215
+ jsons = block.call if block
216
+ result = []
217
+ Evri.parse_json(jsons)["entities"].each do |type, entity|
218
+ if entity.class == Array
219
+ entity.each do |e|
220
+ result << Entity.new(e)
221
+ end
222
+ else
223
+ result << Entity.new(entity)
224
+ end
225
+ end
226
+ result
227
+ end
228
+
229
+ def set_properties json
230
+ @properties = {}
231
+ json["property"].each do |prop|
232
+ if prop.class == Array
233
+ @properties[prop.first.to_sym] = prop.last["$"]
234
+ else
235
+ @properties[prop["name"]["$"].to_sym] = prop["value"]["$"]
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
data/lib/evri/media.rb ADDED
@@ -0,0 +1,47 @@
1
+ module Evri
2
+ class Media
3
+ end
4
+
5
+ # Represents an Article.
6
+ class Article < Media
7
+ attr_accessor :title, :href, :uri, :author, :published_at, :content
8
+ def initialize json
9
+ @title = json["title"]["$"]
10
+ @author = json["author"]["$"]
11
+ @content = json["content"] ? json["content"]["$"] : "No content provided"
12
+ @published_at = json["published"]["$"]
13
+ @href = Evri.api_host + json["link"]["@href"]
14
+ @uri = json["link"]["@hostName"] + json["link"]["@path"]
15
+ end
16
+ end
17
+
18
+ # Represents an Image.
19
+ class Image < Media
20
+ attr_accessor :size, :title, :article_href, :mime_type, :thumbnail, :date, :content, :width, :url, :click_url, :height
21
+ def initialize json
22
+ @title = json["title"]
23
+ @width = json["@width"]
24
+ @height = json["@height"]
25
+ @url = json["@url"]
26
+ @size = json["size"]
27
+ @title = json["title"]
28
+ @article_href = json["articleHref"]["$"]
29
+ @mime_type = json["mimeType"]
30
+ @date = Date.parse(json["date"]["$"])
31
+ @content = json["content"]["$"]
32
+ @click_url = json["clickUrl"]["$"]
33
+ @thumbnail = Thumbnail.new(json["thumbnail"])
34
+ end
35
+
36
+ # Represents an Thumbnail for an Image.
37
+ class Thumbnail
38
+ attr_accessor :size, :width, :height, :url
39
+ def initialize json
40
+ @size = json["size"]
41
+ @width = json["@width"]
42
+ @height = json["@height"]
43
+ @url = json["@url"]
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ module Evri
2
+ # Represents a relation.
3
+ class Relation
4
+ attr_accessor :name, :href, :type
5
+ def initialize json
6
+ @name = json["name"]["$"]
7
+ @href = json["@href"]
8
+ @type = json["type"]["$"]
9
+ @entities = []
10
+ end
11
+
12
+ # Returns the entities in this relation.
13
+ def entities
14
+ return @entities unless @entities.empty?
15
+ json = JSON.parse(Evri.query(:type => :uri, :query => @href))
16
+ json["relations"]["relation"]["targets"]["entity"].each do |entity_json|
17
+ @entities << Entity.new(entity_json)
18
+ end
19
+ @entities
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ module Evri
2
+ # Returns information about a specific trend.
3
+ #
4
+ # To access the information, combine a TREND with a TYPE to form a class method.
5
+ #
6
+ # i.e.
7
+ #
8
+ # * Zeitgeist.all_chemical
9
+ # * Zeitgeist.falling_person
10
+ # * Zeitgeist.popular_organization
11
+ #
12
+ # etc
13
+ class Zeitgeist
14
+
15
+ TYPES = %w( animal backterium chemical concept disorder event location organization person plant product virus )
16
+ TRENDS = %w( all popular rising falling )
17
+
18
+ TRENDS.each do |t|
19
+ TYPES.each do |et|
20
+ eval %(
21
+ def self.#{t}_#{et}
22
+ json = Evri.parse_json(Evri.query :type => :zeitgeist, :query => "#{et}/#{t}")
23
+ json["zeitgeist"]["#{t}"]["entities"]["entity"].map do |entity_json|
24
+ Entity.new(entity_json)
25
+ end
26
+ end
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
data/lib/evri.rb ADDED
@@ -0,0 +1,144 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'cgi'
6
+
7
+ begin
8
+ require 'rubygems'
9
+ rescue LoadError
10
+ nil
11
+ end
12
+
13
+ require 'json'
14
+
15
+ for file in Dir[File.join(File.dirname(__FILE__), 'evri', '*')]
16
+ require file
17
+ end
18
+
19
+ module Evri
20
+
21
+ # A general error.
22
+ class Error < Exception; end
23
+
24
+ # Raised whenever the entity you are searching for cannot be found.
25
+ class EntityNotFound < Error; end
26
+
27
+ VERSION = "0.03"
28
+ @@api_host = "api.evri.com"
29
+ @@source_host = @@api_host
30
+ @@source_url = nil
31
+
32
+ # Sets the hostname for the Evri API.
33
+ def self.api_host= host
34
+ @@api_host = validate_host(host)
35
+ end
36
+
37
+ # Returns the hostname for the Evri API.
38
+ def self.api_host
39
+ @@api_host
40
+ end
41
+
42
+ # Returns the source host for the Evri API
43
+ def self.source_host
44
+ @@source_host
45
+ end
46
+
47
+ # Returns the source host for the Evri API
48
+ def self.source_host= host
49
+ @@source_host = validate_host(host)
50
+ end
51
+
52
+ # Returns the source url for the Evri API
53
+ def self.source_url
54
+ @@source_url
55
+ end
56
+
57
+ # Parses JSON data
58
+ def self.parse_json json
59
+ begin
60
+ JSON.parse(json)
61
+ rescue JSON::ParserError => e
62
+ # puts "Error!"
63
+ # puts e.message
64
+ # puts json
65
+ raise Error.new(e)
66
+ end
67
+ end
68
+
69
+ # TODO Rewrite
70
+ def self.query options={}
71
+ query = ""
72
+ case options[:type]
73
+ when :uri
74
+ path = options[:query]
75
+ when :relations
76
+ path = options[:query] + "/relations"
77
+ if options[:from_domains]
78
+ query = "includeDomain=#{options[:from_domains]}"
79
+ end
80
+ when :related_by
81
+ if options[:uri]
82
+ path = options[:query] + "/related/entities"
83
+ query = "uri=#{escape(options[:uri])}"
84
+ else
85
+ path = options[:query] + "/relations"
86
+ if options[:verb]
87
+ path += "/#{options[:verb]}/#{escape(options[:value])}"
88
+ if options[:entity]
89
+ path += options[:entity].href
90
+ end
91
+ end
92
+ if options[:media]
93
+ query += "media=#{options[:media]}"
94
+ end
95
+ end
96
+ when :zeitgeist
97
+ path = "/zeitgeist/entities/" + options[:query]
98
+ when :related_medias
99
+ path = options[:query] + "/media/related"
100
+ if options[:entities]
101
+ query = options[:entities].map do |e|
102
+ "entityURI=#{e}&"
103
+ end
104
+ query = query.join
105
+ end
106
+ query += "type=#{options[:media]}" if options[:media]
107
+ when :from_media
108
+ path = "/media/entities"
109
+ query = "uri=#{escape(options[:uri])}&text=#{escape(options[:text])}"
110
+ when :search
111
+ path = "/entities/find"
112
+ query = "name=#{escape(options[:query])}"
113
+ when :prefix
114
+ path = "/entities/find"
115
+ query = "prefix=#{escape(options[:query])}"
116
+ else
117
+ raise ArgumentError, "unexpected type #{ options[:type] }"
118
+ end
119
+ query = nil if query.empty?
120
+ uri = URI::HTTP.build :host => self.api_host, :path => path + '.json', :query => query
121
+ # puts "getting #{ uri }"
122
+ response = Net::HTTP.get_response(uri)
123
+ raise Error.new("unexpected http response: #{ response.code }") unless response.code == "200"
124
+ @@source_url = @@source_host + uri.request_uri
125
+ response.body
126
+ end
127
+
128
+ # Escapes CGI text
129
+ def self.escape text
130
+ text ? CGI.escape(text.to_s) : ''
131
+ end
132
+
133
+ private
134
+
135
+ def self.validate_host host
136
+ host = host.to_s
137
+ begin
138
+ URI::HTTP.build(:host => host)
139
+ host
140
+ rescue URI::InvalidComponentError
141
+ raise ArgumentError.new("Invalid host name specified (#{host}). Use something like 'api.evri.com'")
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,144 @@
1
+ require 'test/unit'
2
+ require 'lib/evri'
3
+ require 'mocha'
4
+
5
+ class TestEntity < Test::Unit::TestCase
6
+ BARACK_ID = "/person/barack-obama-0x16f69"
7
+ MICHELLE_ID = "person/michelle-obama-0x4c6e8" # Works without leading slash
8
+ MCCAIN_ID = "/person/john-mccain-0x2a2a7"
9
+
10
+ def setup
11
+ @obama = Evri::Entity.find BARACK_ID
12
+ @michelle = Evri::Entity.find MICHELLE_ID
13
+ @mccain = Evri::Entity.find MCCAIN_ID
14
+ end
15
+
16
+ def test_failed_http_get_raises_good_error
17
+ bad_response = stub(:code => "500")
18
+ Net::HTTP.expects(:get_response).returns(bad_response)
19
+ assert_raises(Evri::Error) { @obama.relations }
20
+ end
21
+
22
+ # Ensure that when we search for Barack, we get the @obama and @michelle objects returned
23
+ def test_class_find
24
+ results = Evri::Entity.search "obama"
25
+ [@obama, @michelle].each do |person|
26
+ assert results.include?(person), "Expected search to contain #{ person }"
27
+ end
28
+ end
29
+
30
+ def test_find_raises_for_missing_ids
31
+ assert_raises(Evri::EntityNotFound) { Evri::Entity.find "crap" }
32
+ end
33
+
34
+ def test_failed_search_returns_empty_array
35
+ assert Evri::Entity.search("asdfasdfasdfasdfjlskdjflkasdjfkljasdklfjkladsjfklajsdl;kfjlaksdjfadklsjfkladsjlfkjasdfkljas#").empty?
36
+ end
37
+
38
+ def test_class_find_with_prefix
39
+ results = Evri::Entity.search_by_prefix "ob"
40
+ assert results.include?(@obama), "Expected search to contain #{ @obama }"
41
+ end
42
+
43
+ def test_name
44
+ assert_equal @obama.name, "Barack Obama"
45
+ end
46
+
47
+ def test_id
48
+ assert_equal @obama.id, BARACK_ID
49
+ end
50
+
51
+ def test_properties
52
+ vandyk_parks = Evri::Entity.find "/person/van-dyke-parks-0x16b10"
53
+ assert vandyk_parks.info(:occupation).include?("Composer")
54
+ end
55
+
56
+ def test_properties_from_search
57
+ vandyk_parks = Evri::Entity.search_by_prefix("van dyke parks").first
58
+ assert vandyk_parks.info(:occupation).include?("Composer")
59
+ end
60
+
61
+ def test_properties_from_related_by
62
+ loaded_entity = @obama.related_by(:verb => :kill).first
63
+ assert loaded_entity.info(:name)
64
+ end
65
+
66
+ def test_relations
67
+ assert @obama.relations.find { |r| r.name == "US Politician" }
68
+ assert @obama.relations.find { |r| r.href == "#{@obama.href}/relations/facet/politician" }
69
+ end
70
+
71
+ def test_related_by_from_uri
72
+ # Sends right data, but bug in API prevents it from knowing about the URI
73
+ # assert !@obama.related_by(:uri => "www.boston.com/news/nation/articles/2008/10/23/obama_takes_campaign_break_to_visit_ill_grandmother/?rss_id=Boston.com+--+Latest+news")
74
+ end
75
+
76
+ def test_relations_from_domains
77
+ assert !@obama.relations(:from => "time.com").empty?
78
+ assert !@obama.relations(:from => ["time.com", "nytimes.com"]).empty?
79
+ end
80
+
81
+ def test_relations_with_type
82
+ # TODO tests
83
+ @obama.related_by(:verb => :kill, :type => :image)
84
+ end
85
+
86
+ def test_relations_related_to
87
+ # TODO tests
88
+ @obama.related_by(:facet => :musical_artist)
89
+ @obama.related_by(:qt => "joined-by-0x78")
90
+ @mccain.related_by(:verb => :kill, :entity => @obama)
91
+ @obama.related_by(:facet => :politician, :entity => @mccain)
92
+ end
93
+
94
+ def test_source_url
95
+ dude = @obama.related_by(:facet => :politician).first
96
+ assert_equal "#{Evri.source_host}#{@obama.uri}/relations/facet/politician.json", dude.source_url
97
+ end
98
+
99
+ def test_media_related_to_entities_about_an_entity
100
+ # articles takes either entities or entity URIs
101
+ # NOTE: the plural of 'media' is 'media'
102
+ medias = @obama.articles(:entities => [@mccain, "/person/bill-ayers-0x27a65"])
103
+ assert medias.size > 1
104
+ end
105
+
106
+ def test_medias_with_type_of_image
107
+ image = @obama.images.first
108
+ %w( size title article_href mime_type thumbnail date content width url click_url height).each do |field|
109
+ assert image.send(field), "Expected #{ image.inspect }'s #{ field } field to be larger than zero"
110
+ end
111
+ %w( size width height url).each do |field|
112
+ assert image.thumbnail.send(field), "Expected #{ image.thumbnail.inspect }'s #{ field } field to be larger than zero"
113
+ end
114
+ end
115
+
116
+ def test_relations_loading
117
+ politician_relation = @obama.relations.find { |r| r.name == "US Politician" }
118
+ assert politician_relation.entities.include?(@mccain)
119
+ end
120
+
121
+ def test_relations_with_verb
122
+ entities = @obama.related_by(:verb => :attack)
123
+ assert entities.first.target_href.include?("attack")
124
+
125
+ assert @obama.related_by(:qt => "joined-by-0x78").find { |e| e.name == "Joe Biden" }
126
+
127
+ assert @obama.related_by(:facet => :politician).include?(@mccain)
128
+ end
129
+
130
+ def test_media
131
+ media = @obama.articles.first
132
+ # check for media.title, media.uri, etc
133
+ %w( title author published_at content href uri).each do |field|
134
+ assert media.send(field).size > 0, "Expected #{ media.inspect }'s #{ field } field to be larger than zero"
135
+ end
136
+ end
137
+
138
+ def test_find_by_media
139
+ uri = "http://www.reuters.com/article/industryNews/idUSTRE4981RO20081009"
140
+ dreamworks = Evri::Entity.find "/organization/dreamworks-0x3c510"
141
+ entities = Evri::Entity.from_media(:uri => uri, :text => "Dreamworks")
142
+ assert entities.include?(dreamworks)
143
+ end
144
+ end
data/test/test_evri.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'test/unit'
2
+ require 'lib/evri'
3
+ require 'mocha'
4
+
5
+ class TestModuleEvri < Test::Unit::TestCase
6
+ def test_setting_invalid_new_api_host
7
+ remember_original_settings(:api_host) do
8
+ assert_raise(ArgumentError) { Evri.api_host = "http://slashdot.org" }
9
+ assert_raise(ArgumentError) { Evri.api_host = "Joe's Cat" }
10
+ assert_raise(ArgumentError) { Evri.api_host = 3 }
11
+ end
12
+ end
13
+
14
+ def test_setting_new_api_host
15
+ remember_original_settings(:api_host) do
16
+ Evri.api_host = "new.api.evri.com"
17
+ assert_equal Evri.api_host, "new.api.evri.com"
18
+ end
19
+ end
20
+
21
+ def test_source_host
22
+ remember_original_settings(:source_host) do
23
+ Evri.source_host = "new.api.evri.com"
24
+ assert_equal Evri.source_host, "new.api.evri.com"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def remember_original_settings method
31
+ original = Evri.send method
32
+ yield ensure Evri.send"#{method}=", original
33
+ end
34
+ end
35
+
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'lib/evri'
3
+
4
+ class TestMedia < Test::Unit::TestCase
5
+ BARACK_ID = "person/barack-obama-0x16f69"
6
+
7
+ def test_this
8
+ end
9
+
10
+ end
@@ -0,0 +1,19 @@
1
+ require 'test/unit'
2
+ require 'lib/evri'
3
+
4
+ class TestZeitgeist < Test::Unit::TestCase
5
+ BARACK_ID = "person/barack-obama-0x16f69"
6
+
7
+ def setup
8
+ @obama = Evri::Entity.find BARACK_ID
9
+ end
10
+
11
+ def test_popular_person
12
+ assert Evri::Zeitgeist.popular_person.include?(@obama)
13
+ end
14
+
15
+ def test_falling_product
16
+ # just check to see that the first falling product's name is not blank.
17
+ assert Evri::Zeitgeist.falling_product.first.name.size > 0
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evri
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.03"
5
+ platform: ruby
6
+ authors:
7
+ - Joe Van Dyk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-31 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: :json
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: :mocha
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hoe
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.8.2
44
+ version:
45
+ description: A beautiful API that wraps the RESTful services provided by evri.com.
46
+ email:
47
+ - joe@@fixieconsulting.com
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ extra_rdoc_files:
53
+ - History.txt
54
+ - Manifest.txt
55
+ - README.txt
56
+ files:
57
+ - History.txt
58
+ - Manifest.txt
59
+ - README.txt
60
+ - Rakefile
61
+ - TODO
62
+ - evri-api.gemspec
63
+ - lib/evri.rb
64
+ - lib/evri/entity.rb
65
+ - lib/evri/media.rb
66
+ - lib/evri/relation.rb
67
+ - lib/evri/zeitgeist.rb
68
+ - test/test_entity.rb
69
+ - test/test_evri.rb
70
+ - test/test_media.rb
71
+ - test/test_zeitgeist.rb
72
+ has_rdoc: true
73
+ homepage: http://github.com/joevandyk/evri-api
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --main
77
+ - README.txt
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ version:
92
+ requirements: []
93
+
94
+ rubyforge_project: evri-api
95
+ rubygems_version: 1.2.0
96
+ signing_key:
97
+ specification_version: 2
98
+ summary: A beautiful API that wraps the RESTful services provided by evri.com.
99
+ test_files:
100
+ - test/test_entity.rb
101
+ - test/test_evri.rb
102
+ - test/test_zeitgeist.rb
103
+ - test/test_media.rb