michael-ken 0.0.2 → 0.0.3

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 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