ken 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ === 0.0.1 / not released
2
+
3
+ * Birthday!
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Michael Aufreiter
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,264 @@
1
+ h1. Ken
2
+
3
+ h2. Introduction
4
+
5
+ Ken is a Data Layer for Knowledge Representation.
6
+
7
+ It's being built to access the Metaweb Services supplied by Freebase.com.
8
+ 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.
10
+
11
+ You can navigate the Freebase Graph using a rubyish syntax.
12
+ Also you can use this library as a Data Layer (instead of or in addition to ActiveRecord/DataMapper) for your Web Framework of choice (Merb, Rails).
13
+
14
+ h2. Installation
15
+
16
+ Use GitHub RubyGems:
17
+
18
+ <pre>
19
+ <code>
20
+ $ gem sources -a http://gems.github.com (you only have to do this once)
21
+ $ sudo gem install michael-ken
22
+ </code>
23
+ </pre>
24
+
25
+ In your Ruby files add:
26
+
27
+ <pre>
28
+ <code>
29
+ require 'rubygems'
30
+ gem 'michael-ken'
31
+ require 'ken'
32
+ </code>
33
+ </pre>
34
+
35
+
36
+ h2. Getting started
37
+
38
+ The first place to get started with Freebase is of course, Freebase. Try out their Browser at
39
+ "http://www.freebase.com":http://www.freebase.com.
40
+
41
+ The Freebase Database can be thought of as a huge graph of interconnected nodes that represent
42
+ knowledge (in a much more structured way than wikipedia does).
43
+ That graph can be viewed at a higher level through an object-oriented lens which leads to easier interaction.
44
+ To understand the fundamental Metaweb Architecture please read the official
45
+ "MQL Reference guide":http://download.freebase.com/MQLReferenceGuide.pdf (with focus on Chapter 2)
46
+ provided by Freebase.
47
+
48
+ In addition, you can learn a lot by employing the Freebase "Query Editor":http://www.freebase.com/tools/queryeditor/.
49
+
50
+ h3. Fetching a Resource
51
+
52
+ Let's ask Ken what he knows about the British Band New Order.
53
+
54
+ <pre>
55
+ <code>
56
+ resource = Ken.get('/en/new_order') # => <Resource id="/en/new_order" name="New Order">
57
+ </code>
58
+ </pre>
59
+
60
+ h3. Inspecting the Types
61
+
62
+ Every Resource can have multiple types.
63
+
64
+ <pre>
65
+ <code>
66
+ resource.types
67
+ # => [ #<Type id="/film/music_contributor" name="Film music contributor">, #<Type id="/music/artist" name="Musical Artist">,
68
+ #<Type id="/common/topic" name="Topic">, #<Type id="/music/musical_group" name="Musical Group">,
69
+ #<Type id="/broadcast/artist" name="Broadcast Artist">, #<Type id="/music/group_member" name="Musical Group Member"> ]
70
+ </code>
71
+ </pre>
72
+
73
+ We can see that New Order is a member of Music Artist, Film Music Contributor, Broadcast Artist and other types.
74
+
75
+ h3. Inspecting a Type's properties
76
+
77
+ A type defines a set of properties to describe a Resource.
78
+
79
+ <pre>
80
+ <code>
81
+ resource.types.each do |type|
82
+ type.properties # => e.g. [ #<Property id="/music/musical_group/member"> ]
83
+ end
84
+ </code>
85
+ </pre>
86
+
87
+ We get sets of Properties for each Type. The Type Musical Group has just one Property @/music/musical_group/member@
88
+ named Members Of Musical Group.
89
+
90
+ h3. Listing all Attributes
91
+
92
+ After inspecting a Resource's Types and Properties we now know what we could know. But actually we don't know nothing :)
93
+ So it's time to ask for the values of properties, the so called _Attributes_.
94
+
95
+ ~Note: In Ken's terminology we differ between _Properties_ and concrete Property instances, the _Attributes_, while
96
+ Freebase itself doesn't.~
97
+
98
+ <pre>
99
+ <code>
100
+ resource.attributes.each do |att|
101
+ att # => e.g. #<Attribute property="/music/artist/album">
102
+ att.property.name # => e.g. "Albums"
103
+
104
+ att.values
105
+ # e.g. => [ #<Resource id="/guid/9202a8c04000641f8000000002fa2556" name="Ceremony">,
106
+ #<Resource id="/guid/9202a8c04000641f8000000002fa24d5" name="Procession">,
107
+ #<Resource id="/guid/9202a8c04000641f8000000002fa20d3" name="Everything's Gone Green">, ... ]
108
+ # e.g. => ["1980"]
109
+ end
110
+ </code>
111
+ </pre>
112
+
113
+ Attributes are slightly more complicated to handle compared to Types and Properties.
114
+
115
+ There are four kinds of Attributes.
116
+ * Unique Value Type
117
+ * Unique Object Type
118
+ * Non-unique Value Type
119
+ * Non-unique Object
120
+
121
+ In order to be able to use unique and non-unique Attributes in the same manner we always wrap the value of an Attribute
122
+ in a Collection, no matter if there's one value or there are many.
123
+
124
+ h3. Group Attributes by their Type using Views
125
+
126
+
127
+ <pre>
128
+ <code>
129
+ resource.views.each do |view|
130
+ view # => e.g. #<View type="/music/artist">
131
+ view.type # => e.g #<Type id="/music/artist" name="Musical Artist">
132
+ view.attributes
133
+ # => [#<Attribute property="/music/artist/home_page">, #<Attribute property="/music/artist/genre">,
134
+ #<Attribute property="/music/artist/active_start">, #<Attribute property="/music/artist/similar_artist">,
135
+ #<Attribute property="/music/artist/album">, #<Attribute property="/music/artist/label">,
136
+ #<Attribute property="/music/artist/track">, #<Attribute property="/music/artist/origin">]
137
+
138
+ view.attributes.each do |att|
139
+ att.values
140
+ # e.g. => [ #<Resource id="/en/alternative_dance" name="Alternative dance">,
141
+ #<Resource id="/en/synthpop" name="Synthpop">,
142
+ #<Resource id="/en/house_music" name="House music">,
143
+ #<Resource id="/en/post-punk" name="Post-punk"> ]
144
+ # e.g. => ["1980"]
145
+ end
146
+ end
147
+ </code>
148
+ </pre>
149
+
150
+ h3. Fetching multiple Resources using a query
151
+
152
+ As of now you can ask for multiple Resources by specifying a query.
153
+
154
+ <pre>
155
+ <code>
156
+ resources = Ken.all(:name => "Apple", :type => "/music/album")
157
+ # => [#<Resource id="/guid/9202a8c04000641f80000000031dae7c" name="Apple">,
158
+ #<Resource id="/guid/9202a8c04000641f8000000007ce31ec" name="Apple">]
159
+ </code>
160
+ </pre>
161
+
162
+ Keep in mind that only the top level of the query is mapped to a Collection of Resource Objects.
163
+ So asking for values in a nested level does not make sense. Use nested statements just for
164
+ lowering the top level result.
165
+
166
+ However you can instead navigate the normal way to figure out that values.
167
+ _But won't that require another query to triggered? Certainly._
168
+
169
+ Let's look at a nested query:
170
+
171
+ <pre>
172
+ <code>
173
+ query = {
174
+ :directed_by => "George Lucas",
175
+ :starring => [
176
+ {
177
+ :actor => "Harrison Ford"
178
+ }
179
+ ],
180
+ :type => "/film/film"
181
+ }
182
+
183
+ resources = Ken.all(query)
184
+ # => [#<Resource id="/en/star_wars_episode_iv_a_new_hope" name="Star Wars Episode IV: A New Hope">,
185
+ #<Resource id="/en/american_graffiti" name="American Graffiti">,
186
+ #<Resource id="/en/the_star_wars_holiday_special" name="The Star Wars Holiday Special">]
187
+ </code>
188
+ </pre>
189
+
190
+ h3. Access properties attributes directly
191
+
192
+ Ken is primarily designed for inspecting resources in a generic way, what's ideal for domain independent browsing applications.
193
+ However, there are legitimate situations where you already know what you want to access.
194
+
195
+ That's why I now added direct Property/Attribute access, but only on a Type/View level:
196
+
197
+ <pre>
198
+ <code>
199
+ resource = Ken.get('/en/new_order')
200
+ type = resource.types[1] # => #<Type id="/music/artist" name="Musical Artist">
201
+ # because we know _/music/artist_ has a _genre_ property we can access that directly
202
+ type.genre # => #<Property id="/music/artist/genre" expected_type="/music/genre" unique="false" object_type="true">
203
+ </code>
204
+ </pre>
205
+
206
+ The same works for views:
207
+
208
+ <pre>
209
+ <code>
210
+ resource = Ken.get('/en/new_order')
211
+ view = resource.views[1] # => #<View type="/music/artist">
212
+ # because we know _/music/artist_ has a _genre_ property we can access attribute directly as well
213
+ view.genre # => #<Attribute property="/music/artist/genre">
214
+ </code>
215
+ </pre>
216
+
217
+ If you rather want to query based on Types and access Properties/Attributes directly you can consider using
218
+ Chris "Eppsteins Freebase Library":http://github.com/chriseppstein/freebase/tree/master as an alternative.
219
+
220
+
221
+ h3. Low Level API
222
+
223
+ Sometimes you may want to do specific queries instead of inspecting Resources as a whole.
224
+ In such a case you would want to use Ken's low level API.
225
+
226
+ _mqlread_ works like the regular _mqlread service_, except that you are able to pass ruby hashes instead of JSON.
227
+ And you don't have to deal with HTTP, parameter encoding and parsing JSON.
228
+
229
+ <pre>
230
+ <code>
231
+ artists = Ken.session.mqlread([{
232
+ :type => "/music/artist",
233
+ :id => nil,
234
+ :"/common/topic/webpage" => [{:uri => nil}],
235
+ :home_page => [{:uri => nil}],
236
+ :limit => 2
237
+ }])
238
+
239
+ # => [
240
+ {"type"=>"/music/artist", "home_page"=>[{"uri"=>"http://www.massiveattack.co.uk/"}], "id"=>"/en/massive_attack", "/common/topic/webpage"=>[{"uri"=>"http://musicmoz.org/Bands_and_Artists/M/Massive_Attack/"}, {"uri"=>"http://www.discogs.com/artist/Massive+Attack"}, {"uri"=>"http://www.massiveattackarea.com/"}, {"uri"=>"http://www.massiveattack.co.uk/"}, {"uri"=>"http://www.massiveattack.com/"}]},
241
+ {"type"=>"/music/artist", "home_page"=>[{"uri"=>"http://www.apartment26.com/"}], "id"=>"/en/apartment_26", "/common/topic/webpage"=>[{"uri"=>"http://www.discogs.com/artist/Apartment+26"}, {"uri"=>"http://musicmoz.org/Bands_and_Artists/A/Apartment_26/"}, {"uri"=>"http://www.apartment26.com/"}]}
242
+ ]
243
+ </code>
244
+ </pre>
245
+
246
+ h2. Project Status
247
+
248
+ h3. Features
249
+
250
+ * Fetching of single Resources
251
+ * Fetching of multiple Resources by specifying a query
252
+ * Accessing Properties/Attributes directly (on a type/view level)
253
+ * Type inspection
254
+ * Attribute inspection
255
+ * Low Level API (mqlread)
256
+ * Rails and Merb support
257
+ * Views on Resources to group Attributes based on the Resource's types
258
+
259
+ h3. Roadmap
260
+
261
+ # More tests
262
+ # Write-Support
263
+
264
+ Initial thoughts, obviously not up-to-date and not conforming to the current version, are available at "http://wiki.github.com/michael/ken":http://wiki.github.com/michael/ken.
@@ -0,0 +1,76 @@
1
+ = Ken
2
+
3
+ * http://www.github.com/michael/ken
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ken is a Data Layer for Knowledge Representation.
8
+
9
+ It's being built to access the Metaweb Services supplied by Freebase.com.
10
+ Just born, the project’s goals are the provision of a concise API for querying and writing.
11
+ Therefore it wraps the Metaweb Architecture to smart Ruby Objects (that represent the Metaweb Architecture).
12
+
13
+ You can navigate the Freebase Graph using a rubyish syntax.
14
+
15
+ You should be able to use this Library as a Data Layer (instead of or in addition to
16
+ ActiveRecord/DataMapper) for your Web Framework of choice (Merb, Rails).
17
+
18
+
19
+ == FEATURES/PROBLEMS:
20
+
21
+ Features
22
+
23
+ * Fetching of single Resources
24
+ * Type inspection
25
+ * Attributes inspection
26
+ * Views on Resources to group Attributes based on the Resource's types
27
+ * Some specs
28
+
29
+ Roadmap
30
+
31
+ 1. Much more specs
32
+ 2. Support for querying of multiple Resources
33
+ 3. Better Type Support
34
+ 4. API for Set Based Browsing (see http://mqlx.com/~david/parallax/)
35
+ 5. Accessing Properties/Attributes directly (e.g. resource.genres )
36
+ 6. Write-Support
37
+
38
+ == SYNOPSIS:
39
+
40
+ resource = Ken.get('/en/new_order') # => <Resource id="/en/new_order" name="New Order">
41
+
42
+ == REQUIREMENTS:
43
+
44
+ - Ruby >=1.8.x
45
+ - RubyGems >=1.2.x
46
+ - Extlib >=0.9.x
47
+
48
+ == INSTALL:
49
+
50
+ $ gem sources -a http://gems.github.com (you only have to do this once)
51
+ $ sudo gem install michael-ken
52
+
53
+ == LICENSE:
54
+
55
+ (The MIT License)
56
+
57
+ Copyright (c) 2009 Michael Aufreiter
58
+
59
+ Permission is hereby granted, free of charge, to any person obtaining
60
+ a copy of this software and associated documentation files (the
61
+ 'Software'), to deal in the Software without restriction, including
62
+ without limitation the rights to use, copy, modify, merge, publish,
63
+ distribute, sublicense, and/or sell copies of the Software, and to
64
+ permit persons to whom the Software is furnished to do so, subject to
65
+ the following conditions:
66
+
67
+ The above copyright notice and this permission notice shall be
68
+ included in all copies or substantial portions of the Software.
69
+
70
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
71
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
72
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
73
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
74
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
75
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
76
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
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.add_dependency('extlib')
13
+ gem.add_dependency('json')
14
+ gem.add_dependency('addressable')
15
+ # gem.files = FileList["[A-Z]*.*"]
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/**/*_test.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/*_test.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ if File.exist?('VERSION.yml')
48
+ config = YAML.load(File.read('VERSION.yml'))
49
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
50
+ else
51
+ version = ""
52
+ end
53
+
54
+ rdoc.rdoc_dir = 'rdoc'
55
+ rdoc.title = "ken #{version}"
56
+ rdoc.rdoc_files.include('README*')
57
+ rdoc.rdoc_files.include('lib/**/*.rb')
58
+ end
59
+
60
+ Jeweler::GemcutterTasks.new