michael-ken 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ test_log
2
+ pkg
3
+ pkg/*
4
+ */pkg/*
5
+ bundle
6
+ bundle/*
7
+ doc
8
+ *.log
9
+ log
10
+ !log*.rb
11
+ */log
12
+ log/*
13
+ */log/*
14
+ coverage
15
+ */coverage
16
+ lib/dm-more.rb
17
+ *.db
18
+ nbproject
19
+ .DS_Store
20
+ rspec_report.html
21
+ *.swp
22
+ _Yardoc
23
+ */ri
data/README.textile CHANGED
@@ -6,11 +6,11 @@ Ken is a Data Layer for Knowledge Representation.
6
6
 
7
7
  It's being built to access the Metaweb Services supplied by Freebase.com.
8
8
  Just born, the project’s goals are the provision of a concise API for querying and writing.
9
- Therefore it wraps the Metaweb Architecture to smart Ruby Objects (that represent the Metaweb Architecture).
9
+ Therefore it wraps the Metaweb Architecture to smart Ruby Objects.
10
10
 
11
11
  You can navigate the Freebase Graph using a rubyish syntax.
12
12
 
13
- You should be able to use this Library as a Data Layer (instead of or in addition to
13
+ If things go right, you should be able to use this library as a Data Layer (instead of or in addition to
14
14
  ActiveRecord/DataMapper) for your Web Framework of choice (Merb, Rails).
15
15
 
16
16
 
@@ -52,7 +52,7 @@ Let's ask Ken what he knows about the British Band New Order.
52
52
  </code>
53
53
  </pre>
54
54
 
55
- h3. Inspecting the types
55
+ h3. Inspecting the Types
56
56
 
57
57
  Every Resource can have multiple types.
58
58
 
@@ -67,7 +67,7 @@ Every Resource can have multiple types.
67
67
 
68
68
  We can see that New Order is a member of Music Artist, Film Music Contributor, Broadcast Artist and other types.
69
69
 
70
- h3. Inspecting a types properties
70
+ h3. Inspecting a Type's properties
71
71
 
72
72
  A type defines a set of properties to describe a Resource.
73
73
 
@@ -82,7 +82,7 @@ A type defines a set of properties to describe a Resource.
82
82
  We get sets of Properties for each Type. The Type Musical Group has just one Property @/music/musical_group/member@
83
83
  named Members Of Musical Group.
84
84
 
85
- h4. Listing all Attributes
85
+ h3. Listing all Attributes
86
86
 
87
87
  After inspecting a Resource's Types and Properties we now know what we could know. But actually we don't know nothing :)
88
88
  So it's time to ask for the values of properties, the so called _Attributes_.
@@ -116,7 +116,7 @@ There are four kinds of Attributes.
116
116
  In order to be able to use unique and non-unique Attributes in the same manner we always wrap the value of an Attribute
117
117
  in a Collection, no matter if there's one value or there are many.
118
118
 
119
- h4. Group Attributes by their Type using Views
119
+ h3. Group Attributes by their Type using Views
120
120
 
121
121
 
122
122
  <pre>
@@ -142,6 +142,46 @@ h4. Group Attributes by their Type using Views
142
142
  </code>
143
143
  </pre>
144
144
 
145
+ h3. Fetching multiple Resources using a query
146
+
147
+ As of now you can ask for multiple Resources by specifying a query.
148
+
149
+ <pre>
150
+ <code>
151
+ resources = Ken.all(:name => "Apple", :type => "/music/album")
152
+ # => [#<Resource id="/guid/9202a8c04000641f80000000031dae7c" name="Apple">,
153
+ #<Resource id="/guid/9202a8c04000641f8000000007ce31ec" name="Apple">]
154
+ </code>
155
+ </pre>
156
+
157
+ Keep in mind that only the top level of the query is mapped to a Collection of Resource Objects.
158
+ So asking for values in a nested level does not make sense. Use nested statements just for
159
+ lowering the top level result.
160
+
161
+ However you can instead navigate the normal way to figure out that values.
162
+ _But won't that require another query to triggered? Doubtful._
163
+
164
+ Let's look at a nested query:
165
+
166
+ <pre>
167
+ <code>
168
+ query = {
169
+ :directed_by => "George Lucas",
170
+ :starring => [
171
+ {
172
+ :actor => "Harrison Ford"
173
+ }
174
+ ],
175
+ :type => "/film/film"
176
+ }
177
+
178
+ resources = Ken.all(query)
179
+ # => [#<Resource id="/en/star_wars_episode_iv_a_new_hope" name="Star Wars Episode IV: A New Hope">,
180
+ #<Resource id="/en/american_graffiti" name="American Graffiti">,
181
+ #<Resource id="/en/the_star_wars_holiday_special" name="The Star Wars Holiday Special">]
182
+ </code>
183
+ </pre>
184
+
145
185
  h2. Status
146
186
 
147
187
  Currently, the focus lies on inspecting Freebase Resources in a generic way. That's why
@@ -156,6 +196,7 @@ Chris "Eppsteins Freebase Library":http://github.com/chriseppstein/freebase/tree
156
196
  h3. Features
157
197
 
158
198
  * Fetching of single Resources
199
+ * Fetching of multiple Resources by specifying a query
159
200
  * Type inspection
160
201
  * Attributes inspection
161
202
  * Views on Resources to group Attributes based on the Resource's types
@@ -164,7 +205,6 @@ h3. Features
164
205
  h3. Roadmap
165
206
 
166
207
  # Much more specs
167
- # Support for querying of multiple Resources
168
208
  # Better Type Support
169
209
  # API for Set Based Browsing (see http://mqlx.com/~david/parallax/)
170
210
  # Accessing Properties/Attributes directly (e.g. resource.genres )
data/Rakefile CHANGED
@@ -1,30 +1,56 @@
1
- require 'pathname'
2
1
  require 'rubygems'
2
+ require 'rake'
3
3
 
4
- ROOT = Pathname(__FILE__).dirname.expand_path
5
- JRUBY = RUBY_PLATFORM =~ /java/
6
- WINDOWS = Gem.win_platform?
7
- SUDO = (WINDOWS || JRUBY) ? '' : ('sudo' unless ENV['SUDOLESS'])
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ken"
8
+ gem.summary = %Q{Ruby API for Accessing the Freebase}
9
+ gem.email = "ma[at]zive[dot]at"
10
+ gem.homepage = "http://github.com/michael/ken"
11
+ gem.authors = ["michael"]
12
+ # gem.files = FileList["[A-Z]*.*"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
8
15
 
9
- require ROOT + 'lib/ken/version'
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
10
19
 
11
- AUTHOR = 'Michael Aufreiter'
12
- EMAIL = 'ma[at]zive[dot]at'
13
- GEM_NAME = 'ken'
14
- GEM_VERSION = '0.0.2'# Ken::VERSION
15
- GEM_DEPENDENCIES = [
16
- [ 'extlib', '>=0.9.10' ]
17
- # [ 'addressable', '~>2.0.1' ]
18
- ]
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
19
26
 
20
- GEM_CLEAN = %w[ log pkg coverage ]
21
- GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO History.txt ] }
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
22
39
 
23
- PROJECT_NAME = 'ken'
24
- PROJECT_URL = "http://github.com/michael/#{GEM_NAME}"
25
- PROJECT_DESCRIPTION = PROJECT_SUMMARY = 'Ruby API for Accessing the Freebase'
26
40
 
27
- #[ ROOT, ROOT.parent ].each do |dir|
28
- [ ROOT ].each do |dir|
29
- Pathname.glob(dir.join('tasks/**/*.rb').to_s).each { |f| require f }
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION.yml')
46
+ config = YAML.load(File.read('VERSION.yml'))
47
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "ken #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
30
56
  end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
data/lib/ken.rb CHANGED
@@ -3,6 +3,7 @@ require 'rubygems'
3
3
  require 'net/http'
4
4
  require 'json'
5
5
  require 'extlib'
6
+ require 'extlib/assertions'
6
7
  require 'addressable/uri'
7
8
 
8
9
  dir = Pathname(__FILE__).dirname.expand_path + 'ken'
@@ -25,9 +26,59 @@ Ken::Logger.new(STDOUT, :error)
25
26
  Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
26
27
 
27
28
  module Ken
29
+
30
+ extend Extlib::Assertions
31
+
32
+
33
+ # store query as a constant here.
34
+ # if the hash gets updated using
35
+ # #merge! or #update, this will mean
36
+ # that it actually stores the last
37
+ # query used. there are 2 sides to this.
38
+ # on the one hand, it isn't really a
39
+ # constant anymore (ruby doesn't complain)?
40
+ # on the other hand, there is no need to
41
+ # create a new object everytime a query is
42
+ # executed. maybe this is fine, maybe not,
43
+ # this needs to be discussed.
44
+
45
+ QUERY = query = {
46
+ # :id => id, # needs to be updated in instance mehtod
47
+ :name => nil,
48
+ :"ken:type" => [{
49
+ :id => nil,
50
+ :name => nil,
51
+ :properties => [{
52
+ :id => nil,
53
+ :name => nil,
54
+ :expected_type => nil,
55
+ :unique => nil,
56
+ :reverse_property => nil,
57
+ :master_property => nil,
58
+ }]
59
+ }]
60
+ }
61
+
62
+ # Executes an Mql Query against the Freebase API and returns the result as
63
+ # a <tt>Collection</tt> of <tt>Resources</tt>.
64
+ #
65
+ # == Examples
66
+ #
67
+ # Ken.all(:name => "Apple", :type => "/music/album")
68
+ #
69
+ # Ken.all(
70
+ # :directed_by => "George Lucas",
71
+ # :starring => [{
72
+ # :actor => "Harrison Ford"
73
+ # }],
74
+ # :type => "/film/film"
75
+ # )
76
+ # @api public
28
77
  def self.all(options = {})
29
- # raise ArgumentError.new("must be a hash") unless options.is_a(::Hash)
30
- raise NotImplementedError
78
+ assert_kind_of 'options', options, Hash
79
+ query = { :name => nil }.merge!(options).merge!(:id => nil) # collection queries MUST have :id => nil, no?
80
+ result = Ken.session.mqlread([ query ])
81
+ Ken::Collection.new(result.map { |r| Ken::Resource.new(r) })
31
82
  end
32
83
 
33
84
 
@@ -37,28 +88,16 @@ module Ken
37
88
  # == Examples
38
89
  #
39
90
  # Ken.get('/en/the_police') => #<Resource id="/en/the_police" name="The Police">
91
+ # @api public
40
92
  def self.get(id)
41
- # TODO check if it has a correct /type/object/id syntax
42
- raise ArgumentError.new("must be a string") unless id.is_a?(::String)
43
-
44
- query = {
45
- :id => id,
46
- :name => nil,
47
- :type => [{
48
- :id => nil,
49
- :name => nil,
50
- :properties => [{
51
- :id => nil,
52
- :name => nil,
53
- :expected_type => nil,
54
- :unique => nil,
55
- :reverse_property => nil,
56
- :master_property => nil,
57
- }]
58
- }]
59
- }
60
-
61
- result = Ken.session.mqlread(query)
62
- return Ken::Resource.new(result)
93
+ assert_kind_of 'id', id, String
94
+ raise ArgumentError, "id must be in /type/object/id format" unless valid_id_attribute?(id)
95
+ result = Ken.session.mqlread(QUERY.merge!(:id => id))
96
+ Ken::Resource.new(result)
63
97
  end
98
+
99
+ def self.valid_id_attribute?(id)
100
+ id =~ /\/\w+/
101
+ end
102
+
64
103
  end # module Ken
data/lib/ken/attribute.rb CHANGED
@@ -1,14 +1,15 @@
1
1
  module Ken
2
2
  class Attribute
3
+
4
+ include Extlib::Assertions
5
+
3
6
  attr_reader :property
4
7
 
5
8
  # initializes a resource by json result
6
9
  def initialize(data, property)
7
- raise "error" unless data.kind_of?(Array)
8
-
9
- @data = data
10
- @property = property # belongs to a property
11
- self
10
+ assert_kind_of 'data', data, Array
11
+ assert_kind_of 'property', property, Ken::Property
12
+ @data, @property = data, property
12
13
  end
13
14
 
14
15
  def self.create(data, property)
data/lib/ken/property.rb CHANGED
@@ -1,12 +1,25 @@
1
1
  module Ken
2
2
  class Property
3
3
 
4
+ include Extlib::Assertions
5
+
6
+ VALUE_TYPES = %w{
7
+ /type/id
8
+ /type/int
9
+ /type/float
10
+ /type/boolean
11
+ /type/text
12
+ /type/rawstring
13
+ /type/uri
14
+ /type/datetime
15
+ /type/key
16
+ }
17
+
4
18
  # initializes a resource by json result
5
19
  def initialize(data, type)
6
- raise "error" unless data.kind_of?(Hash)
7
- @data = data
8
- @type = type
9
- self
20
+ assert_kind_of 'data', data, Hash
21
+ assert_kind_of 'type', type, Ken::Type
22
+ @data, @type = data, type
10
23
  end
11
24
 
12
25
  # @api public
@@ -56,23 +69,13 @@ module Ken
56
69
  # returns true if the property is an object type
57
70
  # @api public
58
71
  def object_type?
59
- !%w{
60
- /type/id
61
- /type/int
62
- /type/float
63
- /type/boolean
64
- /type/text
65
- /type/rawstring
66
- /type/uri
67
- /type/datetime
68
- /type/key
69
- }.include?(expected_type)
72
+ !value_type?
70
73
  end
71
74
 
72
75
  # returns true if the property is a value type
73
76
  # @api public
74
77
  def value_type?
75
- !object_type?
78
+ VALUE_TYPES.include?(expected_type)
76
79
  end
77
80
 
78
81
  # @api public
data/lib/ken/resource.rb CHANGED
@@ -1,107 +1,56 @@
1
1
  module Ken
2
2
  class Resource
3
- # initializes a resource by json result
4
- def initialize(data)
5
- return nil unless data
6
- raise "error" unless data.kind_of?(Hash)
7
-
8
- # intialize lazy if there is no type supplied
9
- @schema_loaded = false
10
- @attributes_loaded = false
11
- @data = data
12
-
13
- self
14
- end
15
-
16
- def schema_loaded?
17
- @schema_loaded
18
- end
19
-
20
- def attributes_loaded?
21
- @attributes_loaded
22
- end
23
3
 
24
- def fetch_attributes
25
- # fetching all objects regardless of the type
26
- # check this http://lists.freebase.com/pipermail/developers/2007-December/001022.html
27
-
28
- query = {
29
- :"/type/reflect/any_master" => [
30
- {
31
- :id => nil,
32
- :link => nil,
33
- :name => nil
34
- }
35
- ],
36
- :"/type/reflect/any_reverse" => [
37
- {
38
- :id => nil,
39
- :link => nil,
40
- :name => nil
41
- }
42
- ],
43
- :"/type/reflect/any_value" => [
44
- {
45
- :link => nil,
46
- :value => nil
47
- # :lang => "/lang/en",
48
- # :type => "/type/text"
49
- }
50
- ],
51
- :id => id
52
- }
53
-
54
- Ken.session.mqlread(query)
55
- end
4
+ include Extlib::Assertions
56
5
 
57
- def load_attributes!
58
- data = @data["attribute"] || fetch_attributes
59
-
60
- # master & value attributes
61
- raw_attributes = Ken::Util.convert_hash(data["/type/reflect/any_master"])
62
- raw_attributes.merge!(Ken::Util.convert_hash(data["/type/reflect/any_value"]))
63
- @attributes = {}
64
- raw_attributes.each_pair do |a, d|
65
- properties.select { |p| p.id == a}.each do |p|
66
- @attributes[p.id] = Ken::Attribute.create(d, p)
67
- end
68
- end
69
-
70
- # reverse properties
71
- raw_attributes = Ken::Util.convert_hash(data["/type/reflect/any_reverse"])
72
- raw_attributes.each_pair do |a, d|
73
- properties.select { |p| p.master_property == a}.each do |p|
74
- @attributes[p.id] = Ken::Attribute.create(d, p)
75
- end
76
- end
77
-
78
- @attributes_loaded = true
79
- end
80
-
81
- def fetch_schema
82
- query = {
83
- :id => id,
6
+ FETCH_SCHEMA_QUERY = {
7
+ # :id => id, # needs to be merge!d in instance method
8
+ :name => nil,
9
+ :"ken:type" => [{
10
+ :id => nil,
84
11
  :name => nil,
85
- :type => [{
12
+ :properties => [{
86
13
  :id => nil,
87
14
  :name => nil,
88
- :properties => [{
89
- :id => nil,
90
- :name => nil,
91
- :expected_type => nil,
92
- :unique => nil
93
- }]
15
+ :expected_type => nil,
16
+ :unique => nil
94
17
  }]
95
- }
18
+ }]
19
+ }
20
+
21
+ FETCH_ATTRIBUTES_QUERY = {
22
+ :"/type/reflect/any_master" => [
23
+ {
24
+ :id => nil,
25
+ :link => nil,
26
+ :name => nil
27
+ }
28
+ ],
29
+ :"/type/reflect/any_reverse" => [
30
+ {
31
+ :id => nil,
32
+ :link => nil,
33
+ :name => nil
34
+ }
35
+ ],
36
+ :"/type/reflect/any_value" => [
37
+ {
38
+ :link => nil,
39
+ :value => nil
40
+ # :lang => "/lang/en",
41
+ # :type => "/type/text"
42
+ }
43
+ ],
96
44
 
97
- Ken.session.mqlread(query)["type"]
98
- end
45
+ # :id => id # needs to be merg!d in instance method
46
+ }
99
47
 
100
- # loads the resources metainfo
101
- def load_schema!
102
- @data["type"] ||= fetch_schema
103
- @types = Ken::Collection.new(@data["type"].map { |type| Ken::Type.new(type) })
104
- @schema_loaded = true
48
+
49
+ # initializes a resource by json result
50
+ def initialize(data)
51
+ assert_kind_of 'data', data, Hash
52
+ # intialize lazy if there is no type supplied
53
+ @schema_loaded, @attributes_loaded, @data = false, false, data
105
54
  end
106
55
 
107
56
  # @api public
@@ -153,6 +102,62 @@ module Ken
153
102
  load_attributes! unless attributes_loaded?
154
103
  @attributes.values
155
104
  end
105
+
106
+ # returns true if type information is already loaded
107
+ # @api public
108
+ def schema_loaded?
109
+ @schema_loaded
110
+ end
111
+
112
+ # returns true if attributes are already loaded
113
+ # @api public
114
+ def attributes_loaded?
115
+ @attributes_loaded
116
+ end
117
+
118
+ private
119
+ def fetch_attributes
120
+ # fetching all objects regardless of the type
121
+ # check this http://lists.freebase.com/pipermail/developers/2007-December/001022.html
122
+ Ken.session.mqlread(FETCH_ATTRIBUTES_QUERY.merge!(:id => id))
123
+ end
124
+
125
+ def load_attributes!
126
+ data = @data["ken:attribute"] || fetch_attributes
127
+
128
+ # master & value attributes
129
+ raw_attributes = Ken::Util.convert_hash(data["/type/reflect/any_master"])
130
+ raw_attributes.merge!(Ken::Util.convert_hash(data["/type/reflect/any_value"]))
131
+ @attributes = {}
132
+ raw_attributes.each_pair do |a, d|
133
+ properties.select { |p| p.id == a}.each do |p|
134
+ @attributes[p.id] = Ken::Attribute.create(d, p)
135
+ end
136
+ end
137
+
138
+ # reverse properties
139
+ raw_attributes = Ken::Util.convert_hash(data["/type/reflect/any_reverse"])
140
+ raw_attributes.each_pair do |a, d|
141
+ properties.select { |p| p.master_property == a}.each do |p|
142
+ @attributes[p.id] = Ken::Attribute.create(d, p)
143
+ end
144
+ end
145
+
146
+ @attributes_loaded = true
147
+ end
148
+
149
+ def fetch_schema
150
+ Ken.session.mqlread(FETCH_SCHEMA_QUERY.merge!(:id => id))["ken:type"]
151
+ end
152
+
153
+ # loads the resources metainfo
154
+ # @api private
155
+ def load_schema!
156
+ @data["ken:type"] ||= fetch_schema
157
+ @types = Ken::Collection.new(@data["ken:type"].map { |type| Ken::Type.new(type) })
158
+ @schema_loaded = true
159
+ end
160
+
156
161
 
157
162
  end # class Resource
158
163
  end # module Ken
data/lib/ken/type.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  module Ken
2
2
  class Type
3
3
 
4
+ include Extlib::Assertions
5
+
4
6
  # initializes a resource by json result
5
7
  def initialize(data)
6
- raise "error" unless data.kind_of?(Hash)
7
-
8
+ assert_kind_of 'data', data, Hash
8
9
  @data = data
9
- self
10
10
  end
11
11
 
12
12
  # access property info
data/lib/ken/util.rb CHANGED
@@ -2,11 +2,15 @@ module Ken
2
2
  module Util
3
3
  # magic hash conversion
4
4
  def convert_hash(source)
5
- result = {}
6
- source.each do |item|
7
- result[item["link"]] ? result[item["link"]] << { "id" => item["id"], "name" => item["name"], "value" => item["value"] } : result[item["link"]] = [] << { "id" => item["id"], "name" => item["name"], "value" => item["value"] }
5
+ source.inject({}) do |result, item|
6
+ if result[item["link"]]
7
+ result[item["link"]] << { "id" => item["id"], "name" => item["name"], "value" => item["value"] }
8
+ else
9
+ result[item["link"]] = []
10
+ result[item["link"]] << { "id" => item["id"], "name" => item["name"], "value" => item["value"] }
11
+ end
12
+ result
8
13
  end
9
- result
10
14
  end
11
15
  module_function :convert_hash
12
16
  end
data/lib/ken/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ken
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.2'
3
3
  end
data/lib/ken/view.rb CHANGED
@@ -1,15 +1,15 @@
1
1
  # provides an interface to view a resource as a specific type
2
2
  # provides an interface for working with attributes, properties
3
3
  module Ken
4
- class View
4
+ class View
5
+
6
+ include Extlib::Assertions
7
+
5
8
  # initializes a resource by json result
6
9
  def initialize(resource, type)
7
- raise "error" unless resource.kind_of?(Ken::Resource)
8
- raise "error" unless type.kind_of?(Ken::Type)
9
-
10
- @resource = resource # belongs to a resource
11
- @type = type # belongs to a type
12
- self
10
+ assert_kind_of 'resource', resource, Ken::Resource
11
+ assert_kind_of 'type', type, Ken::Type
12
+ @resource, @type = resource, type
13
13
  end
14
14
 
15
15
  # @api public
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id" : "/en/the_police",
3
3
  "name" : "The Police",
4
- "type" : [
4
+ "ken:type" : [
5
5
  {
6
6
  "id" : "/music/artist",
7
7
  "name" : "Musical Artist",
@@ -189,7 +189,7 @@
189
189
  ]
190
190
  }
191
191
  ],
192
- "attribute" : {
192
+ "ken:attribute" : {
193
193
  "/type/reflect/any_master" : [
194
194
  {
195
195
  "id" : "/boot/all_permission",
@@ -9,12 +9,48 @@ describe Ken do
9
9
  end
10
10
 
11
11
  describe "Ken.get('/en/the_police')" do
12
- it 'should return a Ken::Resource' do
12
+ it "should return a Ken::Resource" do
13
13
  the_police = Ken.get("/en/the_police")
14
14
  the_police.should be_kind_of(Ken::Resource)
15
15
  end
16
16
  end
17
17
 
18
+ describe "Ken.all" do
19
+ it "should return a Ken::Collection of Ken::Resources" do
20
+ resources = Ken.all(:name => "Apple")
21
+ resources.should be_kind_of(Ken::Collection)
22
+ resources.first.should be_kind_of(Ken::Resource)
23
+ end
24
+
25
+ it "should work with a limit specified" do
26
+ resources = Ken.all(:name => "Apple", :limit => 3)
27
+ resources.should have(3).items
28
+ end
29
+
30
+ it "should work with a type specified" do
31
+ resources = Ken.all(:name => "Apple", :type => "/music/album")
32
+ resources.should have_at_least(1).items
33
+ resources.each {|r| r.types.select {|t| t.id == "/music/album"}.should have(1).items }
34
+ end
35
+
36
+ it "should understand nested queries" do
37
+ query = {
38
+ :directed_by => "George Lucas",
39
+ :starring => [
40
+ {
41
+ :actor => "Harrison Ford"
42
+ }
43
+ ],
44
+ :type => "/film/film"
45
+ }
46
+
47
+ resources = Ken.all(query)
48
+ resources.should have(3).items
49
+ resources.first.name.should == "Star Wars Episode IV: A New Hope"
50
+ resources.last.name.should == "The Star Wars Holiday Special"
51
+ end
52
+ end
53
+
18
54
  describe "Ken::Resource" do
19
55
  before :all do
20
56
  @the_police = Ken.get("/en/the_police")
@@ -5,7 +5,7 @@ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
5
5
  describe Ken::Resource do
6
6
 
7
7
  before :each do
8
- Ken::Logger.new(STDOUT, :info)
8
+ # Ken::Logger.new(STDOUT, :info)
9
9
  # Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
10
10
  data = load_fixture('the_police')
11
11
  @the_police = Ken::Resource.new(data)
@@ -7,20 +7,22 @@ describe Ken::View do
7
7
  Ken::Logger.new(STDOUT, :info)
8
8
  data = load_fixture('the_police')
9
9
  @the_police = Ken::Resource.new(data)
10
-
11
10
  @view = @the_police.views.first
12
11
  end
13
12
 
14
13
  it "should have a type" do
15
14
  @view.type.should_not be_nil
15
+ @view.type.should be_kind_of(Ken::Type)
16
16
  end
17
17
 
18
18
  it "should have properties" do
19
19
  @view.properties.should_not be_nil
20
+ @view.properties.each { |p| p.should be_kind_of(Ken::Property)}
20
21
  end
21
22
 
22
23
  it "should have attributes" do
23
- @view.properties.should_not be_nil
24
+ @view.attributes.should_not be_nil
25
+ @view.attributes.each { |p| p.should be_kind_of(Ken::Attribute)}
24
26
  end
25
27
  end
26
28
 
metadata CHANGED
@@ -1,47 +1,37 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: michael-ken
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
- - Michael Aufreiter
7
+ - michael
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-10 00:00:00 -08:00
12
+ date: 2009-05-14 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: extlib
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
- description: Ruby API for accessing Freebase
26
- email:
27
- - ma [a] zive [d] at
14
+ dependencies: []
15
+
16
+ description:
17
+ email: ma[at]zive[dot]at
28
18
  executables: []
29
19
 
30
20
  extensions: []
31
21
 
32
22
  extra_rdoc_files:
33
- - README.txt
34
23
  - LICENSE
35
- - TODO
36
- - History.txt
24
+ - README.textile
25
+ - README.txt
37
26
  files:
27
+ - .gitignore
38
28
  - History.txt
39
29
  - LICENSE
40
- - Manifest.txt
41
- - README.txt
42
30
  - README.textile
31
+ - README.txt
43
32
  - Rakefile
44
33
  - TODO
34
+ - VERSION
45
35
  - examples/artist.rb
46
36
  - lib/ken.rb
47
37
  - lib/ken/attribute.rb
@@ -54,27 +44,23 @@ files:
54
44
  - lib/ken/util.rb
55
45
  - lib/ken/version.rb
56
46
  - lib/ken/view.rb
47
+ - spec/fixtures/music_artist.json
48
+ - spec/fixtures/the_police.json
49
+ - spec/integration/ken_spec.rb
50
+ - spec/spec.opts
51
+ - spec/spec_helper.rb
57
52
  - spec/unit/attribute_spec.rb
58
53
  - spec/unit/property_spec.rb
59
54
  - spec/unit/resource_spec.rb
60
55
  - spec/unit/session_spec.rb
61
56
  - spec/unit/type_spec.rb
62
57
  - spec/unit/view_spec.rb
63
- - spec/integration/ken_spec.rb
64
- - spec/fixtures/music_artist.json
65
- - spec/fixtures/the_police.json
66
- - spec/spec.opts
67
- - spec/spec_helper.rb
68
- - tasks/hoe.rb
69
- - tasks/install.rb
70
58
  - tasks/spec.rb
71
- - tasks/gemspec.rb
72
59
  has_rdoc: true
73
60
  homepage: http://github.com/michael/ken
74
61
  post_install_message:
75
62
  rdoc_options:
76
- - --main
77
- - README.txt
63
+ - --charset=UTF-8
78
64
  require_paths:
79
65
  - lib
80
66
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -91,10 +77,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
77
  version:
92
78
  requirements: []
93
79
 
94
- rubyforge_project: ken
80
+ rubyforge_project:
95
81
  rubygems_version: 1.2.0
96
82
  signing_key:
97
83
  specification_version: 2
98
- summary: Ruby API for accessing Freebase
99
- test_files: []
100
-
84
+ summary: Ruby API for Accessing the Freebase
85
+ test_files:
86
+ - spec/integration/ken_spec.rb
87
+ - spec/spec_helper.rb
88
+ - spec/unit/attribute_spec.rb
89
+ - spec/unit/property_spec.rb
90
+ - spec/unit/resource_spec.rb
91
+ - spec/unit/session_spec.rb
92
+ - spec/unit/type_spec.rb
93
+ - spec/unit/view_spec.rb
94
+ - examples/artist.rb
data/Manifest.txt DELETED
@@ -1,34 +0,0 @@
1
- History.txt
2
- LICENSE
3
- Manifest.txt
4
- README.textile
5
- README.txt
6
- Rakefile
7
- TODO
8
- examples/artist.rb
9
- lib/ken.rb
10
- lib/ken/attribute.rb
11
- lib/ken/collection.rb
12
- lib/ken/logger.rb
13
- lib/ken/property.rb
14
- lib/ken/resource.rb
15
- lib/ken/session.rb
16
- lib/ken/type.rb
17
- lib/ken/util.rb
18
- lib/ken/version.rb
19
- lib/ken/view.rb
20
- spec/fixtures/music_artist.json
21
- spec/fixtures/the_police.json
22
- spec/integration/ken_spec.rb
23
- spec/spec.opts
24
- spec/spec_helper.rb
25
- spec/unit/attribute_spec.rb
26
- spec/unit/property_spec.rb
27
- spec/unit/resource_spec.rb
28
- spec/unit/session_spec.rb
29
- spec/unit/type_spec.rb
30
- spec/unit/view_spec.rb
31
- tasks/gemspec.rb
32
- tasks/hoe.rb
33
- tasks/install.rb
34
- tasks/spec.rb
data/tasks/gemspec.rb DELETED
@@ -1,23 +0,0 @@
1
- desc "Generate gemspec"
2
- task :gemspec do |x|
3
- # Clean up extraneous files before checking manifest
4
- %x[rake clean]
5
-
6
- # Check the manifest before generating the gemspec
7
- manifest = %x[rake check_manifest]
8
- manifest.gsub!("(in /usr/local/projects/dm/dm-core)\n", "")
9
-
10
- unless manifest.empty?
11
- print "\n", "#"*68, "\n"
12
- print <<-EOS
13
- Manifest.txt is not up-to-date. Please review the changes below.
14
- If the changes are correct, run 'rake check_manifest | patch'
15
- and then run this command again.
16
- EOS
17
- print "#"*68, "\n\n"
18
- puts manifest
19
- else
20
- %x[rake debug_gem > #{GEM_NAME}.gemspec]
21
- puts "Successfully created gemspec for #{GEM_NAME}!"
22
- end
23
- end
data/tasks/hoe.rb DELETED
@@ -1,47 +0,0 @@
1
- require 'hoe'
2
-
3
- @config_file = "~/.rubyforge/user-config.yml"
4
- @config = nil
5
- RUBYFORGE_USERNAME = "unknown"
6
- def rubyforge_username
7
- unless @config
8
- begin
9
- @config = YAML.load(File.read(File.expand_path(@config_file)))
10
- rescue
11
- puts <<-EOS
12
- ERROR: No rubyforge config file found: #{@config_file}
13
- Run 'rubyforge setup' to prepare your env for access to Rubyforge
14
- - See http://newgem.rubyforge.org/rubyforge.html for more details
15
- EOS
16
- exit
17
- end
18
- end
19
- RUBYFORGE_USERNAME.replace @config["username"]
20
- end
21
-
22
- # Remove hoe dependency
23
- class Hoe
24
- def extra_dev_deps
25
- @extra_dev_deps.reject! { |dep| dep[0] == "hoe" }
26
- @extra_dev_deps
27
- end
28
- end
29
-
30
- hoe = Hoe.new(GEM_NAME, GEM_VERSION) do |p|
31
-
32
- p.developer(AUTHOR, EMAIL)
33
-
34
- p.description = PROJECT_DESCRIPTION
35
- p.summary = PROJECT_SUMMARY
36
- p.url = PROJECT_URL
37
-
38
- p.rubyforge_name = PROJECT_NAME if PROJECT_NAME
39
-
40
- p.clean_globs |= GEM_CLEAN
41
- p.spec_extras = GEM_EXTRAS if GEM_EXTRAS
42
-
43
- GEM_DEPENDENCIES.each do |dep|
44
- p.extra_deps << dep
45
- end
46
-
47
- end
data/tasks/install.rb DELETED
@@ -1,13 +0,0 @@
1
- def sudo_gem(cmd)
2
- sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
3
- end
4
-
5
- desc "Install #{GEM_NAME} #{GEM_VERSION}"
6
- task :install => [ :package ] do
7
- sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
8
- end
9
-
10
- desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
11
- task :uninstall => [ :clobber ] do
12
- sudo_gem "uninstall #{GEM_NAME} -v#{GEM_VERSION} -Ix"
13
- end