adamsalter-ken 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ken/view.rb ADDED
@@ -0,0 +1,56 @@
1
+ # provides an interface to view a resource as a specific type
2
+ # provides an interface for working with attributes, properties
3
+ module Ken
4
+ class View
5
+
6
+ include Extlib::Assertions
7
+
8
+ # initializes a resource by json result
9
+ def initialize(resource, type)
10
+ assert_kind_of 'resource', resource, Ken::Resource
11
+ assert_kind_of 'type', type, Ken::Type
12
+ @resource, @type = resource, type
13
+ end
14
+
15
+ # @api public
16
+ def to_s
17
+ @type.to_s
18
+ end
19
+
20
+ # return correspondent type
21
+ # @api public
22
+ def type
23
+ @type
24
+ end
25
+
26
+ # @api public
27
+ def inspect
28
+ result = "#<View type=\"#{type.id || "nil"}\">"
29
+ end
30
+
31
+ # returns attributes which are member of the view's type
32
+ # @api public
33
+ def attributes
34
+ @resource.attributes.select { |a| a.property.type == @type}
35
+ end
36
+
37
+ # search for an attribute by name and return it
38
+ # @api public
39
+ def attribute(name)
40
+ attributes.each { |a| return a if a.property.id =~ /\/#{name}$/ }
41
+ nil
42
+ end
43
+
44
+ # returns properties which are member of the view's type
45
+ # @api public
46
+ def properties
47
+ @resource.properties.select { |p| p.type == @type}
48
+ end
49
+
50
+ # delegate to attribute
51
+ def method_missing sym
52
+ attribute(sym.to_s)
53
+ end
54
+
55
+ end
56
+ end
data/lib/ken.rb ADDED
@@ -0,0 +1,124 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'extlib/assertions'
6
+ require 'addressable/uri'
7
+
8
+ dir = Pathname(__FILE__).dirname.expand_path + 'ken'
9
+
10
+ require dir + 'util'
11
+ require dir + 'resource'
12
+ require dir + 'type'
13
+ require dir + 'view'
14
+ require dir + 'property'
15
+ require dir + 'attribute'
16
+ require dir + 'collection'
17
+ require dir + 'session'
18
+ require dir + 'logger'
19
+
20
+ # init logger as soon as the library is required
21
+ Ken::Logger.new(STDOUT, :error)
22
+
23
+ # init default session
24
+ Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
25
+
26
+ module Ken
27
+ extend Extlib::Assertions
28
+
29
+ # store query as a constant here.
30
+ # if the hash gets updated using
31
+ # #merge! or #update, this will mean
32
+ # that it actually stores the last
33
+ # query used. there are 2 sides to this.
34
+ # on the one hand, it isn't really a
35
+ # constant anymore (ruby doesn't complain)?
36
+ # on the other hand, there is no need to
37
+ # create a new object everytime a query is
38
+ # executed. maybe this is fine, maybe not,
39
+ # this needs to be discussed.
40
+
41
+ FETCH_DATA_QUERY = {
42
+ # :id => id, # needs to be merge!d in instance method
43
+ :guid => nil,
44
+ :name => nil,
45
+ :"ken:type" => [{
46
+ :id => nil,
47
+ :name => nil,
48
+ :properties => [{
49
+ :id => nil,
50
+ :name => nil,
51
+ :expected_type => nil,
52
+ :unique => nil,
53
+ :reverse_property => nil,
54
+ :master_property => nil,
55
+ }]
56
+ }],
57
+ :"/type/reflect/any_master" => [
58
+ {
59
+ :id => nil,
60
+ :link => nil,
61
+ :name => nil,
62
+ :optional => true
63
+ }
64
+ ],
65
+ :"/type/reflect/any_reverse" => [
66
+ {
67
+ :id => nil,
68
+ :link => nil,
69
+ :name => nil,
70
+ :optional => true
71
+ }
72
+ ],
73
+ :"/type/reflect/any_value" => [
74
+ {
75
+ :link => nil,
76
+ :value => nil,
77
+ :optional => true
78
+ # TODO: support multiple language
79
+ # :lang => "/lang/en",
80
+ # :type => "/type/text"
81
+ }
82
+ ]
83
+ }
84
+
85
+
86
+ # Executes an Mql Query against the Freebase API and returns the result as
87
+ # a <tt>Collection</tt> of <tt>Resources</tt>.
88
+ #
89
+ # performs a cursored query unless there's a limit specified
90
+ # == Examples
91
+ #
92
+ # Ken.all(:name => "Apple", :type => "/music/album")
93
+ #
94
+ # Ken.all(
95
+ # :directed_by => "George Lucas",
96
+ # :starring => [{
97
+ # :actor => "Harrison Ford"
98
+ # }],
99
+ # :type => "/film/film"
100
+ # )
101
+ # @api public
102
+ def self.all(options = {})
103
+ assert_kind_of 'options', options, Hash
104
+ query = { :name => nil }.merge!(options).merge!(:id => nil)
105
+ result = Ken.session.mqlread([ query ], :cursor => !options[:limit])
106
+ Ken::Collection.new(result.map { |r| Ken::Resource.new(r) })
107
+ end
108
+
109
+
110
+ # Executes an Mql Query against the Freebase API and returns the result wrapped
111
+ # in a <tt>Resource</tt> Object.
112
+ #
113
+ # == Examples
114
+ #
115
+ # Ken.get('/en/the_police') => #<Resource id="/en/the_police" name="The Police">
116
+ # @api public
117
+ def self.get(id)
118
+ assert_kind_of 'id', id, String
119
+ result = Ken.session.mqlread(FETCH_DATA_QUERY.merge!(:id => id))
120
+ raise ResourceNotFound unless result
121
+ Ken::Resource.new(result)
122
+ end
123
+
124
+ end # module Ken
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # when used as a rails plugin
2
+ require 'ken'
data/tasks/ken.rb ADDED
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ken do
3
+ # # Task goes here
4
+ # 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
@@ -0,0 +1,103 @@
1
+
2
+ {
3
+ "id" : "/music/artist",
4
+ "name" : "Musical Artist",
5
+ "properties" : [
6
+ {
7
+ "expected_type" : "/location/location",
8
+ "id" : "/music/artist/origin",
9
+ "name" : "Place Musical Career Began",
10
+ "unique" :true
11
+ },
12
+ {
13
+ "expected_type" : "/type/datetime",
14
+ "id" : "/music/artist/active_start",
15
+ "name" : "Active as Musical Artist (start)",
16
+ "unique" : true
17
+ },
18
+ {
19
+ "expected_type" : "/type/datetime",
20
+ "id" : "/music/artist/active_end",
21
+ "name" : "Active as Musical Artist (end)",
22
+ "unique" : true
23
+ },
24
+ {
25
+ "expected_type" : "/music/genre",
26
+ "id" : "/music/artist/genre",
27
+ "name" : "Musical Genres",
28
+ "unique" : null
29
+ },
30
+ {
31
+ "expected_type" : "/music/record_label",
32
+ "id" : "/music/artist/label",
33
+ "name" : "Record Labels",
34
+ "unique" : null
35
+ },
36
+ {
37
+ "expected_type" : "/music/artist",
38
+ "id" : "/music/artist/similar_artist",
39
+ "name" : "Similar Artists",
40
+ "unique" : null
41
+ },
42
+ {
43
+ "expected_type" : "/common/webpage",
44
+ "id" : "/music/artist/home_page",
45
+ "name" : "Musical Artist Home Page",
46
+ "unique" : null
47
+ },
48
+ {
49
+ "expected_type" : "/common/webpage",
50
+ "id" : "/music/artist/acquire_webpage",
51
+ "name" : "Web Page for Music",
52
+ "unique" : null
53
+ },
54
+ {
55
+ "expected_type" : "/music/album",
56
+ "id" : "/music/artist/album",
57
+ "name" : "Albums",
58
+ "unique" : null
59
+ },
60
+ {
61
+ "expected_type" : "/music/recording_contribution",
62
+ "id" : "/music/artist/contribution",
63
+ "name" : "Album Contributions",
64
+ "unique" : null
65
+ },
66
+ {
67
+ "expected_type" : "/music/track",
68
+ "id" : "/music/artist/track",
69
+ "name" : "Tracks Recorded",
70
+ "unique" : null
71
+ },
72
+ {
73
+ "expected_type" : "/music/artist",
74
+ "id" : "/music/artist/artist_similar",
75
+ "name" : "Similar Musical Artists",
76
+ "unique" : null
77
+ },
78
+ {
79
+ "expected_type" : "/music/track_contribution",
80
+ "id" : "/music/artist/track_contributions",
81
+ "name" : "Track Contributions",
82
+ "unique" : null
83
+ },
84
+ {
85
+ "expected_type" : "/music/instrument",
86
+ "id" : "/music/artist/instruments_played",
87
+ "name" : "Instruments Played",
88
+ "unique" : null
89
+ },
90
+ {
91
+ "expected_type" : "/music/voice",
92
+ "id" : "/music/artist/vocal_range",
93
+ "name" : "Vocal Range",
94
+ "unique" : null
95
+ },
96
+ {
97
+ "expected_type" : "/music/concert_tour",
98
+ "id" : "/music/artist/concert_tours",
99
+ "name" : "Concert Tours",
100
+ "unique" : false
101
+ }
102
+ ]
103
+ }