michael-ken 0.0.1

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