michael-ken 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ *.log
2
+ log/*
3
+ pkg/*
4
+ doc
5
+ cov
6
+ pkg
7
+ .DS_Store
8
+ coverage.html
9
+ coverage/*
10
+ *.db
11
+ \#*
12
+ _Yardoc
13
+ .yardoc
14
+ tmp/*
data/History.txt ADDED
@@ -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.
data/Manifest.txt ADDED
@@ -0,0 +1,27 @@
1
+ .gitignore
2
+ History.txt
3
+ LICENSE
4
+ Manifest.txt
5
+ README.txt
6
+ README.textile
7
+ Rakefile
8
+ TODO
9
+ ken.gemspec
10
+ lib/ken.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/version.rb
18
+ spec/mql_spec.rb
19
+ spec/property_spec.rb
20
+ spec/resource_spec.rb
21
+ spec/session_spec.rb
22
+ spec/type_spec.rb
23
+ spec/spec.opts
24
+ spec/spec_helper.rb
25
+ tasks/hoe.rb
26
+ tasks/install.rb
27
+ tasks/spec.rb
data/README.txt ADDED
@@ -0,0 +1,48 @@
1
+ = Mql
2
+
3
+ * http://www.github.com/michael/ken
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 Michael Aufreiter
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,30 @@
1
+ require 'pathname'
2
+ require 'rubygems'
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'])
8
+
9
+ require ROOT + 'lib/ken/version'
10
+
11
+ AUTHOR = 'Michael Aufreiter'
12
+ EMAIL = 'ma[at]zive[dot]at'
13
+ GEM_NAME = 'ken'
14
+ GEM_VERSION = '0.0.1'# Ken::VERSION
15
+ GEM_DEPENDENCIES = [
16
+ [ 'extlib', '>=0.9.10' ]
17
+ # [ 'addressable', '~>2.0.1' ]
18
+ ]
19
+
20
+ GEM_CLEAN = %w[ log pkg coverage ]
21
+ GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO History.txt ] }
22
+
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
+
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 }
30
+ end
data/TODO ADDED
File without changes
data/ken.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{ken}
3
+ s.version = "0.0.1"
4
+
5
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
+ s.authors = ["Michael Aufreiter"]
7
+ s.date = %q{2009-02-10}
8
+ s.description = %q{Ruby API for accessing Freebase}
9
+ s.email = ["ma [a] zive [d] at"]
10
+ s.extra_rdoc_files = ["README.txt", "LICENSE", "TODO", "History.txt"]
11
+ s.files = [".gitignore", "History.txt", "LICENSE", "Manifest.txt", "README.txt", "Rakefile", "TODO", "ken.gemspec", "lib/ken.rb", "lib/ken/collection.rb", "lib/ken/logger.rb", "lib/ken/property.rb", "lib/ken/resource.rb", "lib/ken/session.rb", "lib/ken/type.rb", "lib/ken/version.rb", "spec/mql_spec.rb", "spec/property_spec.rb", "spec/resource_spec.rb", "spec/session_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/hoe.rb", "tasks/install.rb", "tasks/spec.rb"]
12
+ s.has_rdoc = true
13
+ s.homepage = %q{http://github.com/michael/ken}
14
+ s.rdoc_options = ["--main", "README.txt"]
15
+ s.require_paths = ["lib"]
16
+ s.rubyforge_project = %q{ken}
17
+ s.rubygems_version = %q{1.3.1}
18
+ s.summary = %q{Ruby API for accessing Freebase}
19
+
20
+ if s.respond_to? :specification_version then
21
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
22
+ s.specification_version = 2
23
+
24
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
25
+ s.add_runtime_dependency(%q<extlib>, [">= 0"])
26
+ else
27
+ s.add_dependency(%q<extlib>, [">= 0"])
28
+ end
29
+ else
30
+ s.add_dependency(%q<extlib>, [">= 0"])
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ module Ken
2
+ class Collection < Array
3
+ # def initialize(data = [])
4
+ # @data = data
5
+ # end
6
+
7
+ # def method_missing(name, *args, &blk)
8
+ # @data.send name, *args, &blk
9
+ # end
10
+ end
11
+ end
data/lib/ken/logger.rb ADDED
@@ -0,0 +1,233 @@
1
+ require "time"
2
+
3
+ # ==== Public Ken Logger API
4
+ #
5
+ # Logger taken from Merb/Datamapper :)
6
+ #
7
+ # To replace an existing logger with a new one:
8
+ # Ken.logger.set_log(log{String, IO},level{Symbol, String})
9
+ #
10
+ # Available logging levels are:
11
+ # :off, :fatal, :error, :warn, :info, :debug
12
+ #
13
+ # Logging via:
14
+ # Ken.logger.fatal(message<String>)
15
+ # Ken.logger.error(message<String>)
16
+ # Ken.logger.warn(message<String>)
17
+ # Ken.logger.info(message<String>)
18
+ # Ken.logger.debug(message<String>)
19
+ #
20
+ # Flush the buffer to
21
+ # Ken.logger.flush
22
+ #
23
+ # Remove the current log object
24
+ # Ken.logger.close
25
+ #
26
+ # ==== Private Ken Logger API
27
+ #
28
+ # To initialize the logger you create a new object, proxies to set_log.
29
+ # ken::Logger.new(log{String, IO}, level{Symbol, String})
30
+ #
31
+ # Logger will not create the file until something is actually logged
32
+ # This avoids file creation on Ken init when it creates the
33
+ # default logger.
34
+ module Ken
35
+
36
+ class << self #:nodoc:
37
+ attr_accessor :logger
38
+ end
39
+
40
+ class Logger
41
+ attr_accessor :aio
42
+ attr_accessor :delimiter
43
+ attr_reader :level
44
+ attr_reader :buffer
45
+ attr_reader :log
46
+
47
+ # @note
48
+ # Ruby (standard) logger levels:
49
+ # off: absolutely nothing
50
+ # fatal: an unhandleable error that results in a program crash
51
+ # error: a handleable error condition
52
+ # warn: a warning
53
+ # info: generic (useful) information about system operation
54
+ # debug: low-level information for developers
55
+ #
56
+ # Ken::Logger::LEVELS[:off, :fatal, :error, :warn, :info, :debug]
57
+
58
+ LEVELS =
59
+ {
60
+ :off => 99999,
61
+ :fatal => 7,
62
+ :error => 6,
63
+ :warn => 4,
64
+ :info => 3,
65
+ :debug => 0
66
+ }
67
+
68
+ def level=(new_level)
69
+ @level = LEVELS[new_level.to_sym]
70
+ reset_methods(:close)
71
+ end
72
+
73
+ private
74
+
75
+ # The idea here is that instead of performing an 'if' conditional check on
76
+ # each logging we do it once when the log object is setup
77
+ def set_write_method
78
+ @log.instance_eval do
79
+
80
+ # Determine if asynchronous IO can be used
81
+ def aio?
82
+ @aio = !RUBY_PLATFORM.match(/java|mswin/) &&
83
+ !(@log == STDOUT) &&
84
+ @log.respond_to?(:write_nonblock)
85
+ end
86
+
87
+ # Define the write method based on if aio an be used
88
+ undef write_method if defined? write_method
89
+ if aio?
90
+ alias :write_method :write_nonblock
91
+ else
92
+ alias :write_method :write
93
+ end
94
+ end
95
+ end
96
+
97
+ def initialize_log(log)
98
+ close if @log # be sure that we don't leave open files laying around.
99
+ @log = log || "log/dm.log"
100
+ end
101
+
102
+ def reset_methods(o_or_c)
103
+ if o_or_c == :open
104
+ alias internal_push push_opened
105
+ elsif o_or_c == :close
106
+ alias internal_push push_closed
107
+ end
108
+ end
109
+
110
+ def push_opened(string)
111
+ message = Time.now.httpdate
112
+ message << delimiter
113
+ message << string
114
+ message << "\n" unless message[-1] == ?\n
115
+ @buffer << message
116
+ flush # Force a flush for now until we figure out where we want to use the buffering.
117
+ end
118
+
119
+ def push_closed(string)
120
+ unless @log.respond_to?(:write)
121
+ log = Pathname(@log)
122
+ log.dirname.mkpath
123
+ @log = log.open('a')
124
+ @log.sync = true
125
+ end
126
+ set_write_method
127
+ reset_methods(:open)
128
+ push(string)
129
+ end
130
+
131
+ alias internal_push push_closed
132
+
133
+ def prep_msg(message, level)
134
+ level << delimiter << message
135
+ end
136
+
137
+ public
138
+
139
+ # To initialize the logger you create a new object, proxies to set_log.
140
+ # Ken::Logger.new(log{String, IO},level{Symbol, String})
141
+ #
142
+ # @param log<IO,String> either an IO object or a name of a logfile.
143
+ # @param log_level<String> the message string to be logged
144
+ # @param delimiter<String> delimiter to use between message sections
145
+ # @param log_creation<Boolean> log that the file is being created
146
+ def initialize(*args)
147
+ set_log(*args)
148
+ end
149
+
150
+ # To replace an existing logger with a new one:
151
+ # Ken.logger.set_log(log{String, IO},level{Symbol, String})
152
+ #
153
+ # @param log<IO,String> either an IO object or a name of a logfile.
154
+ # @param log_level<Symbol> a symbol representing the log level from
155
+ # {:off, :fatal, :error, :warn, :info, :debug}
156
+ # @param delimiter<String> delimiter to use between message sections
157
+ # @param log_creation<Boolean> log that the file is being created
158
+ def set_log(log, log_level = :off, delimiter = " ~ ", log_creation = false)
159
+ delimiter ||= " ~ "
160
+
161
+ if log_level && LEVELS[log_level.to_sym]
162
+ self.level = log_level.to_sym
163
+ else
164
+ self.level = :debug
165
+ end
166
+
167
+ @buffer = []
168
+ @delimiter = delimiter
169
+
170
+ initialize_log(log)
171
+
172
+ Ken.logger = self
173
+
174
+ self.info("Logfile created") if log_creation
175
+ end
176
+
177
+ # Flush the entire buffer to the log object.
178
+ # Ken.logger.flush
179
+ #
180
+ def flush
181
+ return unless @buffer.size > 0
182
+ @log.write_method(@buffer.slice!(0..-1).join)
183
+ end
184
+
185
+ # Close and remove the current log object.
186
+ # Ken.logger.close
187
+ #
188
+ def close
189
+ flush
190
+ @log.close if @log.respond_to?(:close)
191
+ @log = nil
192
+ end
193
+
194
+ # Appends a string and log level to logger's buffer.
195
+
196
+ # @note
197
+ # Note that the string is discarded if the string's log level less than the
198
+ # logger's log level.
199
+ # @note
200
+ # Note that if the logger is aio capable then the logger will use
201
+ # non-blocking asynchronous writes.
202
+ #
203
+ # @param level<Fixnum> the logging level as an integer
204
+ # @param string<String> the message string to be logged
205
+ def push(string)
206
+ internal_push(string)
207
+ end
208
+ alias << push
209
+
210
+ # Generate the following logging methods for Ken.logger as described
211
+ # in the API:
212
+ # :fatal, :error, :warn, :info, :debug
213
+ # :off only gets a off? method
214
+ LEVELS.each_pair do |name, number|
215
+ unless name.to_s == 'off'
216
+ class_eval <<-EOS, __FILE__, __LINE__
217
+ # DOC
218
+ def #{name}(message)
219
+ self.<<( prep_msg(message, "#{name}") ) if #{name}?
220
+ end
221
+ EOS
222
+ end
223
+
224
+ class_eval <<-EOS, __FILE__, __LINE__
225
+ # DOC
226
+ def #{name}?
227
+ #{number} >= level
228
+ end
229
+ EOS
230
+ end
231
+
232
+ end # class Logger
233
+ end # module Ken
@@ -0,0 +1,29 @@
1
+ module Ken
2
+ class Property
3
+
4
+ # initializes a resource by json result
5
+ def initialize(data, type)
6
+ raise "error" unless data.kind_of?(Hash)
7
+
8
+ @data = data
9
+ @type = type
10
+ self
11
+ end
12
+
13
+ def id
14
+ @data["id"]
15
+ end
16
+
17
+ def name
18
+ @data["name"]
19
+ end
20
+
21
+ def type
22
+ @type
23
+ end
24
+
25
+ def expected_type
26
+ @data["expected_type"]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,60 @@
1
+ module Ken
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
+ @data = data
9
+ self
10
+ end
11
+
12
+ # access type info
13
+ # api public
14
+ def types
15
+ Ken::Collection.new(@data["type"].map { |type| Ken::Type.new(type) })
16
+ end
17
+
18
+ # api public
19
+ def id
20
+ @data["id"]
21
+ end
22
+
23
+ # api public
24
+ def name
25
+ @data["name"] if @data["name"]
26
+ end
27
+
28
+ # returns all the properties from all assigned types
29
+ def properties
30
+ @properties = Ken::Collection.new
31
+ types.each do |type|
32
+ @properties.concat(type.properties)
33
+ end
34
+ @properties
35
+ end
36
+
37
+ # eg. read_attribute("/music/artist/origin")
38
+ # or the shurtcut version read_attribute("origin")
39
+ # api public
40
+ def read_attribute(attr_name)
41
+ properties.each do |prop|
42
+ if prop.id == attr_name || prop.id.split('/').last == attr_name
43
+ # query the value
44
+ query = {
45
+ :id => id,
46
+ prop.id.to_sym => nil
47
+ }
48
+
49
+ # fetch attribute
50
+ result = Ken.session.mqlread(query)
51
+
52
+ # TODO: return either a simple type ruby equivalent or an object type -> Ken::Resource
53
+ return result[prop.id]
54
+ else
55
+ return nil
56
+ end
57
+ end # properties.each
58
+ end # read_attrribute
59
+ end # class Resource
60
+ end # module Ken
@@ -0,0 +1,110 @@
1
+ module Ken
2
+ class << self #:nodoc:
3
+ attr_accessor :session
4
+ end
5
+
6
+ # A class for returing errors from the freebase api.
7
+ # For more infomation see the freebase documentation:
8
+ class ReadError < ArgumentError
9
+ attr_accessor :code, :msg
10
+ def initialize(code,msg)
11
+ self.code = code
12
+ self.msg = msg
13
+ end
14
+ def message
15
+ "#{code}: #{msg}"
16
+ end
17
+ end
18
+
19
+
20
+ # partially taken from chris eppstein's freebase api
21
+ # http://github.com/chriseppstein/freebase/tree
22
+ class Session
23
+ # include Singleton
24
+
25
+ public
26
+ # Initialize a new Ken Session
27
+ # Ken::Session.new(host{String, IO}, username{String}, password{String})
28
+ #
29
+ # @param host<String> the API host
30
+ # @param username<String> freebase username
31
+ # @param password<String> user password
32
+ def initialize(host, username, password)
33
+ @host = host
34
+ @username = username
35
+ @password = password
36
+
37
+ Ken.session = self
38
+
39
+ # TODO: check connection
40
+ Ken.logger.info("connection established.")
41
+ end
42
+
43
+ SERVICES = {
44
+ :mqlread => '/api/service/mqlread',
45
+ :mqlwrite => '/api/service/mqlwrite',
46
+ :login => '/api/account/login',
47
+ :upload => '/api/service/upload'
48
+ }
49
+
50
+ # get the service url for the specified service.
51
+ def service_url(svc)
52
+ #"http://#{Configuration.instance[:host]}#{SERVICES[svc]}"
53
+ "#{@host}#{SERVICES[svc]}"
54
+ end
55
+
56
+ SERVICES.each_key do |k|
57
+ define_method("#{k}_service_url") do
58
+ service_url(k)
59
+ end
60
+ end
61
+
62
+ # raise an error if the inner response envelope is encoded as an error
63
+ def handle_read_error(inner)
64
+ unless inner['code'][0, '/api/status/ok'.length] == '/api/status/ok'
65
+ Ken.logger.error "Read Error #{inner.inspect}"
66
+ error = inner['messages'][0]
67
+ raise ReadError.new(error['code'], error['message'])
68
+ end
69
+ end # handle_read_error
70
+
71
+ # perform a mqlread and return the results
72
+ # TODO: should support multiple queries
73
+ # you should be able to pass an array of queries
74
+ def mqlread(query, options = {})
75
+ Ken.logger.info ">>> Sending Query: #{query.to_json}"
76
+
77
+ envelope = { :qname => {:query => query }}
78
+
79
+ response = http_request mqlread_service_url, :queries => envelope.to_json
80
+ result = JSON.parse response
81
+ inner = result['qname']
82
+ handle_read_error(inner)
83
+
84
+ Ken.logger.info "<<< Received Response: #{inner['result'].inspect}"
85
+
86
+ # will always return the converted ruby hash (from json)
87
+ inner['result']
88
+
89
+ end # mqlread
90
+
91
+ protected
92
+ def params_to_string(parameters)
93
+ parameters.keys.map {|k| "#{URI.encode(k.to_s)}=#{URI.encode(parameters[k])}" }.join('&')
94
+ end
95
+
96
+ def http_request(url, parameters = {})
97
+ params = params_to_string(parameters)
98
+ url << '?'+params unless params !~ /\S/
99
+
100
+ return Net::HTTP.get_response(::URI.parse(url)).body
101
+
102
+ fname = "#{MD5.md5(params)}.mql"
103
+ open(fname,"w") do |f|
104
+ f << response
105
+ end
106
+ Ken.logger.info("Wrote response to #{fname}")
107
+ end
108
+
109
+ end # class Session
110
+ end # module Ken
data/lib/ken/type.rb ADDED
@@ -0,0 +1,25 @@
1
+ module Ken
2
+ class Type
3
+
4
+ # initializes a resource by json result
5
+ def initialize(data)
6
+ raise "error" unless data.kind_of?(Hash)
7
+
8
+ @data = data
9
+ self
10
+ end
11
+
12
+ # access property info
13
+ def properties
14
+ Ken::Collection.new(@data["properties"].map { |property| Ken::Property.new(property, self) })
15
+ end
16
+
17
+ def id
18
+ @data["id"]
19
+ end
20
+
21
+ def name
22
+ @data["name"]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Ken
2
+ VERSION = '0.0.1'
3
+ end
data/lib/ken.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'extlib'
6
+ require 'addressable/uri'
7
+
8
+ dir = Pathname(__FILE__).dirname.expand_path + 'ken'
9
+
10
+ require dir + 'version'
11
+ require dir + 'resource'
12
+ require dir + 'type'
13
+ require dir + 'property'
14
+ require dir + 'collection'
15
+ require dir + 'session'
16
+ require dir + 'logger'
17
+
18
+ # init logger as soon as the library is required
19
+ Ken::Logger.new(STDOUT, :error)
20
+
21
+
22
+ module Ken
23
+ def self.all(options = {})
24
+ #raise ArgumentError.new("must be a hash") unless options.is_a(::Hash)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def self.get(id)
29
+ # TODO check if it has a correct /type/object/id syntax
30
+ raise ArgumentError.new("must be a string") unless id.is_a?(::String)
31
+
32
+ query = {
33
+ :id => id,
34
+ :name => nil,
35
+ :type => [{
36
+ :id => nil,
37
+ :name => nil,
38
+ :properties => [{
39
+ :id => nil,
40
+ :name => nil,
41
+ :expected_type => nil
42
+ }]
43
+ }]
44
+ }
45
+
46
+ result = Ken.session.mqlread(query)
47
+ return Ken::Resource.new(result)
48
+ end
49
+ end # module Ken
data/spec/mql_spec.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'pathname'
2
+
3
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
4
+
5
+ describe Ken do
6
+ before :all do
7
+ # Ken::Logger.new(STDOUT, :info)
8
+ Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
9
+ end
10
+
11
+ it 'should return a Ken::Resource' do
12
+ the_police = Ken.get("/en/the_police")
13
+ the_police.should be_kind_of(Ken::Resource)
14
+ end
15
+
16
+ end
File without changes
@@ -0,0 +1,28 @@
1
+ require 'pathname'
2
+
3
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
4
+
5
+ describe Ken::Resource do
6
+ before :all do
7
+ Ken::Logger.new(STDOUT, :info)
8
+ Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
9
+
10
+ # fetch a resource
11
+ @the_police = Ken.get("/en/the_police")
12
+ end
13
+
14
+ it 'should have types' do
15
+ @the_police.types.should have_at_least(1).items
16
+ @the_police.types.first.should be_kind_of(Ken::Type)
17
+ end
18
+
19
+ it 'should have an id and a name' do
20
+ @the_police.id.should be_kind_of(::String)
21
+ @the_police.name.should be_kind_of(::String)
22
+ end
23
+
24
+ it 'should get known attributes' do
25
+ # expected London
26
+ @the_police.read_attribute('origin').should == "London"
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ require 'pathname'
2
+
3
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
4
+
5
+ describe Ken::Session do
6
+
7
+ before :all do
8
+ Ken::Logger.new(STDOUT, :info)
9
+ Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
10
+ end
11
+
12
+ it 'should return the types of the_police' do
13
+ result = Ken.session.mqlread({:id => "/en/the_police", :type => []})
14
+ result['type'].length.should == 6
15
+ end
16
+
17
+ it 'should raise an Ken::MqlReadError if node does not exist' do
18
+ lambda { Ken.session.mqlread({:id => "/en/the_police", :evil_property => []}) }.should raise_error(Ken::ReadError)
19
+ end
20
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --loadby random
3
+ --backtrace
@@ -0,0 +1,13 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+ require 'spec'
4
+
5
+ SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
6
+ require SPEC_ROOT.parent + 'lib/ken'
7
+
8
+
9
+ Spec::Runner.configure do |config|
10
+ config.after(:all) do
11
+
12
+ end
13
+ end
data/tasks/hoe.rb ADDED
@@ -0,0 +1,47 @@
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 ADDED
@@ -0,0 +1,13 @@
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
data/tasks/spec.rb ADDED
@@ -0,0 +1,25 @@
1
+ begin
2
+ gem 'rspec', '~>1.1.12'
3
+ require 'spec'
4
+ require 'spec/rake/spectask'
5
+
6
+ task :default => [ :spec ]
7
+
8
+ desc 'Run specifications'
9
+ Spec::Rake::SpecTask.new(:spec) do |t|
10
+ t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
11
+ t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s).map { |f| f.to_s }
12
+
13
+ begin
14
+ gem 'rcov', '~>0.8'
15
+ t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
16
+ t.rcov_opts << '--exclude' << 'spec'
17
+ t.rcov_opts << '--text-summary'
18
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
19
+ rescue LoadError
20
+ # rcov not installed
21
+ end
22
+ end
23
+ rescue LoadError
24
+ # rspec not installed
25
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: michael-ken
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Aufreiter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-10 00:00:00 -08:00
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
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - README.txt
34
+ - LICENSE
35
+ - TODO
36
+ - History.txt
37
+ files:
38
+ - .gitignore
39
+ - History.txt
40
+ - LICENSE
41
+ - Manifest.txt
42
+ - README.txt
43
+ - Rakefile
44
+ - TODO
45
+ - ken.gemspec
46
+ - lib/ken.rb
47
+ - lib/ken/collection.rb
48
+ - lib/ken/logger.rb
49
+ - lib/ken/property.rb
50
+ - lib/ken/resource.rb
51
+ - lib/ken/session.rb
52
+ - lib/ken/type.rb
53
+ - lib/ken/version.rb
54
+ - spec/mql_spec.rb
55
+ - spec/property_spec.rb
56
+ - spec/resource_spec.rb
57
+ - spec/session_spec.rb
58
+ - spec/spec.opts
59
+ - spec/spec_helper.rb
60
+ - tasks/hoe.rb
61
+ - tasks/install.rb
62
+ - tasks/spec.rb
63
+ has_rdoc: true
64
+ homepage: http://github.com/michael/ken
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --main
68
+ - README.txt
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project: ken
86
+ rubygems_version: 1.2.0
87
+ signing_key:
88
+ specification_version: 2
89
+ summary: Ruby API for accessing Freebase
90
+ test_files: []
91
+