evri 0.03

Sign up to get free protection for your applications and to get access to all the features.
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