nov-iknow 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +4 -0
- data/README +56 -0
- data/Rakefile +146 -0
- data/examples/pure_ruby.rb +43 -0
- data/lib/ext/hash.rb +10 -0
- data/lib/iknow/core/config.rb +28 -0
- data/lib/iknow/core/version.rb +14 -0
- data/lib/iknow/core.rb +2 -0
- data/lib/iknow/model/base.rb +14 -0
- data/lib/iknow/model/item.rb +54 -0
- data/lib/iknow/model/list.rb +84 -0
- data/lib/iknow/model/sentence.rb +24 -0
- data/lib/iknow/model/user.rb +84 -0
- data/lib/iknow/model.rb +5 -0
- data/lib/iknow/rest_client/base.rb +128 -0
- data/lib/iknow/rest_client/item.rb +11 -0
- data/lib/iknow/rest_client/list.rb +12 -0
- data/lib/iknow/rest_client/sentence.rb +11 -0
- data/lib/iknow/rest_client/user.rb +12 -0
- data/lib/iknow/rest_client.rb +8 -0
- data/lib/iknow.rb +14 -0
- data/test/iknow_test.rb +5 -0
- data/test/test_helper.rb +3 -0
- metadata +100 -0
data/ChangeLog
ADDED
data/README
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
= iknow
|
3
|
+
|
4
|
+
A rubygem for iKnow! APIs
|
5
|
+
by nov <nmatake@cerego.co.jp>
|
6
|
+
|
7
|
+
== Description
|
8
|
+
|
9
|
+
## Set API Key (in environment.rb etc.)
|
10
|
+
Iknow::Config.init do |conf|
|
11
|
+
conf.api_key = YOUR_API_KEY
|
12
|
+
end
|
13
|
+
|
14
|
+
## User API
|
15
|
+
@user = Iknow::User.find('matake')
|
16
|
+
@user.items
|
17
|
+
@user.lists
|
18
|
+
@user.study_results
|
19
|
+
@matchied_users = Iknow::User.matching('matake')
|
20
|
+
|
21
|
+
## List API
|
22
|
+
@recent_lists = Iknow::List.recent
|
23
|
+
@list = @recent_lists.first
|
24
|
+
@list.items
|
25
|
+
@list.sentences
|
26
|
+
|
27
|
+
## Item API
|
28
|
+
@recent_items = Iknow::Item.recent
|
29
|
+
@matchied_items = Iknow::Item.matching('record')
|
30
|
+
|
31
|
+
## Sentence API
|
32
|
+
@recent_sentences = Iknow::Sentence.recent
|
33
|
+
@matchied_sentences = Iknow::Sentence.matching('record')
|
34
|
+
|
35
|
+
== Installation
|
36
|
+
|
37
|
+
=== Archive Installation
|
38
|
+
|
39
|
+
rake install
|
40
|
+
|
41
|
+
=== Gem Installation
|
42
|
+
|
43
|
+
gem install iknow
|
44
|
+
|
45
|
+
|
46
|
+
== Features/Problems
|
47
|
+
|
48
|
+
|
49
|
+
== Synopsis
|
50
|
+
|
51
|
+
|
52
|
+
== Copyright
|
53
|
+
|
54
|
+
Author:: nov <nmatake@cerego.co.jp>
|
55
|
+
Copyright:: Copyright (c) 2008 nov
|
56
|
+
License:: MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'rake/contrib/sshpublisher'
|
10
|
+
require 'fileutils'
|
11
|
+
include FileUtils
|
12
|
+
|
13
|
+
NAME = "iknow"
|
14
|
+
AUTHOR = "nov"
|
15
|
+
EMAIL = "developer@iknow.co.jp"
|
16
|
+
DESCRIPTION = "A rubygem for iKnow! APIs"
|
17
|
+
RUBYFORGE_PROJECT = "iknow"
|
18
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
19
|
+
BIN_FILES = %w( )
|
20
|
+
|
21
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/lib"
|
22
|
+
require 'lib/iknow'
|
23
|
+
VERS = Iknow::Version.to_version
|
24
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
25
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
26
|
+
RDOC_OPTS = [
|
27
|
+
'--title', "#{NAME} documentation",
|
28
|
+
"--charset", "utf-8",
|
29
|
+
"--opname", "index.html",
|
30
|
+
"--line-numbers",
|
31
|
+
"--main", "README",
|
32
|
+
"--inline-source",
|
33
|
+
]
|
34
|
+
|
35
|
+
task :default => [:test]
|
36
|
+
task :package => [:clean]
|
37
|
+
|
38
|
+
Rake::TestTask.new("test") do |t|
|
39
|
+
t.libs << "test"
|
40
|
+
t.pattern = "test/**/*_test.rb"
|
41
|
+
t.verbose = true
|
42
|
+
end
|
43
|
+
|
44
|
+
spec = Gem::Specification.new do |s|
|
45
|
+
s.name = NAME
|
46
|
+
s.version = VERS
|
47
|
+
s.platform = Gem::Platform::RUBY
|
48
|
+
s.has_rdoc = true
|
49
|
+
s.extra_rdoc_files = ["README", "ChangeLog"]
|
50
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
51
|
+
s.summary = DESCRIPTION
|
52
|
+
s.description = DESCRIPTION
|
53
|
+
s.author = AUTHOR
|
54
|
+
s.email = EMAIL
|
55
|
+
s.homepage = HOMEPATH
|
56
|
+
s.executables = BIN_FILES
|
57
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
58
|
+
s.bindir = "bin"
|
59
|
+
s.require_path = "lib"
|
60
|
+
#s.autorequire = ""
|
61
|
+
s.test_files = Dir["test/*_test.rb"]
|
62
|
+
|
63
|
+
#s.add_dependency('activesupport', '>=1.3.1')
|
64
|
+
s.add_dependency('json')
|
65
|
+
#s.required_ruby_version = '>= 1.8.2'
|
66
|
+
|
67
|
+
s.files = %w(README ChangeLog Rakefile) +
|
68
|
+
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
69
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
70
|
+
Dir.glob("examples/**/*.rb") +
|
71
|
+
Dir.glob("tools/*.rb") +
|
72
|
+
Dir.glob("rails/*.rb")
|
73
|
+
|
74
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
75
|
+
end
|
76
|
+
|
77
|
+
Rake::GemPackageTask.new(spec) do |p|
|
78
|
+
p.need_tar = true
|
79
|
+
p.gem_spec = spec
|
80
|
+
end
|
81
|
+
|
82
|
+
task :install do
|
83
|
+
name = "#{NAME}-#{VERS}.gem"
|
84
|
+
sh %{rake package}
|
85
|
+
sh %{sudo gem install pkg/#{name}}
|
86
|
+
end
|
87
|
+
|
88
|
+
task :uninstall => [:clean] do
|
89
|
+
sh %{sudo gem uninstall #{NAME}}
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
Rake::RDocTask.new do |rdoc|
|
94
|
+
rdoc.rdoc_dir = 'html'
|
95
|
+
rdoc.options += RDOC_OPTS
|
96
|
+
rdoc.template = "resh"
|
97
|
+
#rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
98
|
+
if ENV['DOC_FILES']
|
99
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
100
|
+
else
|
101
|
+
rdoc.rdoc_files.include('README', 'ChangeLog')
|
102
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
103
|
+
rdoc.rdoc_files.include('ext/**/*.c')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "Publish to RubyForge"
|
108
|
+
task :rubyforge => [:rdoc, :package] do
|
109
|
+
require 'rubyforge'
|
110
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'nov').upload
|
111
|
+
end
|
112
|
+
|
113
|
+
desc 'Package and upload the release to rubyforge.'
|
114
|
+
task :release => [:clean, :package] do |t|
|
115
|
+
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
116
|
+
abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
|
117
|
+
pkg = "pkg/#{NAME}-#{VERS}"
|
118
|
+
|
119
|
+
require 'rubyforge'
|
120
|
+
rf = RubyForge.new.configure
|
121
|
+
puts "Logging in"
|
122
|
+
rf.login
|
123
|
+
|
124
|
+
c = rf.userconfig
|
125
|
+
# c["release_notes"] = description if description
|
126
|
+
# c["release_changes"] = changes if changes
|
127
|
+
c["preformatted"] = true
|
128
|
+
|
129
|
+
files = [
|
130
|
+
"#{pkg}.tgz",
|
131
|
+
"#{pkg}.gem"
|
132
|
+
].compact
|
133
|
+
|
134
|
+
puts "Releasing #{NAME} v. #{VERS}"
|
135
|
+
rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
|
136
|
+
end
|
137
|
+
|
138
|
+
desc 'Show information about the gem.'
|
139
|
+
task :debug_gem do
|
140
|
+
puts spec.to_ruby
|
141
|
+
end
|
142
|
+
|
143
|
+
desc 'Update gem spec'
|
144
|
+
task :gemspec do
|
145
|
+
open("#{NAME}.gemspec", 'w').write spec.to_ruby
|
146
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'iknow'
|
3
|
+
|
4
|
+
Iknow::Config.init do |conf|
|
5
|
+
conf.api_key = "" # Set your iKnow! API key, here.
|
6
|
+
conf.host = "api.iknow.co.jp"
|
7
|
+
end
|
8
|
+
|
9
|
+
please_get_api_key =<<EOS
|
10
|
+
This example needs your own iKnow! API key.
|
11
|
+
(for only Iknow::Item.extract example)
|
12
|
+
|
13
|
+
You can get iKnow! API key at iKnow! Developers.
|
14
|
+
iKnow! Developers (http://developer.iknow.co.jp/)
|
15
|
+
|
16
|
+
Thanks!
|
17
|
+
EOS
|
18
|
+
|
19
|
+
raise ArgumentError.new(please_get_api_key) if Iknow::Config.instance.api_key == ''
|
20
|
+
|
21
|
+
## User API
|
22
|
+
@user = Iknow::User.find('matake')
|
23
|
+
@user.items
|
24
|
+
@user.lists
|
25
|
+
@user.friends
|
26
|
+
@user.study_results
|
27
|
+
@matchied_users = Iknow::User.matching('matake')
|
28
|
+
|
29
|
+
# ## List API
|
30
|
+
@recent_lists = Iknow::List.recent
|
31
|
+
@matchied_lists = Iknow::List.matching("遺伝的アルゴリズム")
|
32
|
+
@ga_list.first.items
|
33
|
+
@ga_list.first.sentences
|
34
|
+
|
35
|
+
# ## Item API
|
36
|
+
@recent_items = Iknow::Item.recent
|
37
|
+
@matchied_items = Iknow::Item.matching('record')
|
38
|
+
@items = Iknow::Item.extract("sometimes, often, electrical")
|
39
|
+
@items.first.sentences
|
40
|
+
|
41
|
+
## Sentence API
|
42
|
+
@recent_sentences = Iknow::Sentence.recent
|
43
|
+
@matchied_sentences = Iknow::Sentence.matching('record')
|
data/lib/ext/hash.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
class Iknow::Config
|
4
|
+
include Singleton
|
5
|
+
attr_accessor :protocol, :host, :port, :user_agent, :api_key, :application_name, :application_version, :application_url, :source
|
6
|
+
|
7
|
+
def self.init(&block)
|
8
|
+
conf = Iknow::Config.instance
|
9
|
+
{ :protocol => 'http',
|
10
|
+
:host => 'api.iknow.co.jp',
|
11
|
+
:port => 80,
|
12
|
+
:user_agent => 'default',
|
13
|
+
:api_key => '',
|
14
|
+
:application_name => 'iKnow! API',
|
15
|
+
:application_version => Iknow::Version.to_version,
|
16
|
+
:application_url => 'http://github.com/nov/iknow',
|
17
|
+
:source => 'iknow'
|
18
|
+
}.each do |key, value| conf.send("#{key}=", value) end
|
19
|
+
yield conf if block_given?
|
20
|
+
conf
|
21
|
+
end
|
22
|
+
|
23
|
+
def iknow_base_url
|
24
|
+
port = self.port==80 ? nil : ":#{self.port}"
|
25
|
+
"#{self.protocol}://#{self.host}#{port}"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/iknow/core.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Iknow::Base
|
2
|
+
# TODO: define self.attributes
|
3
|
+
def self.attributes; self::ATTRIBUTES end
|
4
|
+
def attributes; self.class.attributes end
|
5
|
+
|
6
|
+
def self.deserialize(response, params = {})
|
7
|
+
klass = params[:as] ? params[:as] : self
|
8
|
+
response.is_a?(Array) ? response.inject([]) { |results, params| results << klass.new(params) } : klass.new(response)
|
9
|
+
end
|
10
|
+
def deserialize(response, params = {})
|
11
|
+
self.class.deserialize(response, params)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Iknow::Item < Iknow::Base
|
2
|
+
ATTRIBUTES = [:sentences, :response, :cue, :id]
|
3
|
+
attr_reader *ATTRIBUTES
|
4
|
+
|
5
|
+
class Response
|
6
|
+
ATTRIBUTES = [:text]
|
7
|
+
attr_reader *ATTRIBUTES
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
@text = params['text']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Cue
|
15
|
+
ATTRIBUTES = [:sound, :part_of_speech, :text]
|
16
|
+
NOT_WRITABLE_ATTRIBUTES = [:text]
|
17
|
+
attr_accessor *(ATTRIBUTES - NOT_WRITABLE_ATTRIBUTES)
|
18
|
+
attr_reader *NOT_WRITABLE_ATTRIBUTES
|
19
|
+
|
20
|
+
def initialize(params = {})
|
21
|
+
@text = params['text']
|
22
|
+
@sound = params['sound']
|
23
|
+
@image = params['part_of_speech']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.recent(params = {})
|
28
|
+
response = Iknow::RestClient::Item.recent(params)
|
29
|
+
self.deserialize(response)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.matching(keyword, params = {})
|
33
|
+
params[:keyword] = keyword
|
34
|
+
response = Iknow::RestClient::Item.matching(params)
|
35
|
+
self.deserialize(response)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.extract(text, params = {})
|
39
|
+
params[:text] = text
|
40
|
+
response = Iknow::RestClient::Item.extract(params)
|
41
|
+
self.deserialize(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize(params = {})
|
45
|
+
@id = params['id'].to_i
|
46
|
+
@sentences = []
|
47
|
+
params['sentences'].each do |sentence|
|
48
|
+
@sentences << Iknow::Sentence.new(sentence)
|
49
|
+
end
|
50
|
+
@response = params['response'] ? Iknow::Item::Response.new(params['response']) : nil
|
51
|
+
@cue = Iknow::Item::Cue.new(params['cue'])
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Iknow::List < Iknow::Base
|
2
|
+
ATTRIBUTES = [:list_id, :title, :description, :link,
|
3
|
+
:language, :translation_language, :list_type, :transcript, :embed,
|
4
|
+
:tags, :media_entry, :author, :author_url, :attribution_license_id]
|
5
|
+
NOT_WRITABLE_ATTRIBUTES = [:list_id]
|
6
|
+
attr_accessor *(ATTRIBUTES - NOT_WRITABLE_ATTRIBUTES)
|
7
|
+
attr_reader *NOT_WRITABLE_ATTRIBUTES
|
8
|
+
|
9
|
+
def self.recent(params = {})
|
10
|
+
response = Iknow::RestClient::List.recent(params)
|
11
|
+
self.deserialize(response)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.matching(keyword, params = {})
|
15
|
+
params[:keyword] = keyword
|
16
|
+
response = Iknow::RestClient::List.matching(params)
|
17
|
+
self.deserialize(response)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create(params = {})
|
21
|
+
new_list = self.new(params)
|
22
|
+
new_list.save!
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(params = {})
|
26
|
+
@list_id = params['id'].to_i if params['id']
|
27
|
+
@title = params[:title] || params['title']
|
28
|
+
@description = params[:description] || params['description']
|
29
|
+
@link = params[:link] || params['link']
|
30
|
+
end
|
31
|
+
|
32
|
+
def items(params = {})
|
33
|
+
return @items if @items
|
34
|
+
|
35
|
+
response = Iknow::RestClient::List.items(params.merge(:id => self.list_id))
|
36
|
+
@items = self.deserialize(response, :as => Iknow::Item)
|
37
|
+
@items
|
38
|
+
end
|
39
|
+
|
40
|
+
def sentences(params = {})
|
41
|
+
return @sentences if @sentences
|
42
|
+
|
43
|
+
response = Iknow::RestClient::List.sentences(params.merge(:id => self.list_id))
|
44
|
+
@sentences = self.deserialize(response, :as => Iknow::Sentence)
|
45
|
+
@sentences
|
46
|
+
end
|
47
|
+
|
48
|
+
def save!
|
49
|
+
Iknow::RestClient::List.create(self.to_post_data)
|
50
|
+
end
|
51
|
+
|
52
|
+
def save
|
53
|
+
self.save!
|
54
|
+
true
|
55
|
+
rescue
|
56
|
+
false
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
def to_post_data
|
62
|
+
raise ArgumentError.new("List title is needed.") if self.title.nil? or self.title.empty?
|
63
|
+
|
64
|
+
post_data = {
|
65
|
+
'list[name]' => self.title,
|
66
|
+
'list[description]' => self.description,
|
67
|
+
'list[language]' => self.language || 'en',
|
68
|
+
'list[translation_language]' => self.translation_language || 'ja'
|
69
|
+
}
|
70
|
+
# Object#type should not be used
|
71
|
+
if self.list_type
|
72
|
+
post_data['list[type]'] = self.list_type
|
73
|
+
end
|
74
|
+
# Optional attributes
|
75
|
+
[ :transcript, :embed, :tags, :media_entry,
|
76
|
+
:author, :author_url, :attribution_license_id ].each do |key|
|
77
|
+
if self.send("#{key}")
|
78
|
+
post_data["list[#{key}]"] = self.send("#{key}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
post_data
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Iknow::Sentence < Iknow::Base
|
2
|
+
ATTRIBUTES = [:sound, :image, :text]
|
3
|
+
WRITABLE_ATTRIBUTES = [:sound, :image]
|
4
|
+
attr_accessor *WRITABLE_ATTRIBUTES
|
5
|
+
attr_reader *(ATTRIBUTES - WRITABLE_ATTRIBUTES)
|
6
|
+
|
7
|
+
def self.recent(params = {})
|
8
|
+
response = Iknow::RestClient::Sentence.recent(params)
|
9
|
+
self.deserialize(response)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.matching(keyword, params = {})
|
13
|
+
params[:keyword] = keyword
|
14
|
+
response = Iknow::RestClient::Sentence.matching(params)
|
15
|
+
self.deserialize(response)
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(params = {})
|
19
|
+
@sound = params['sound']
|
20
|
+
@image = params['image']
|
21
|
+
@text = params['text']
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class Iknow::User < Iknow::Base
|
2
|
+
ATTRIBUTES = [:username, :profile]
|
3
|
+
attr_reader *ATTRIBUTES
|
4
|
+
|
5
|
+
class Profile < Iknow::User
|
6
|
+
ATTRIBUTES = [:name, :gender, :birthday, :description, :blog_url, :profile_url, :foaf_url, :icon_url]
|
7
|
+
attr_reader *ATTRIBUTES
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
@name = params['name']
|
11
|
+
@gender = params['gender']
|
12
|
+
@birthday = (Date.parse(params['birthday']) rescue nil)
|
13
|
+
@description = params['description']
|
14
|
+
@blog_url = params['blog_url']
|
15
|
+
@profile_url = params['profile_url']
|
16
|
+
@foaf_url = params['foaf_url']
|
17
|
+
@icon_url = params['icon_url']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class StudyResult < Iknow::User
|
22
|
+
ATTRIBUTES = [:timestamp, :seconds, :totals, :seen, :completed, :date]
|
23
|
+
attr_reader *ATTRIBUTES
|
24
|
+
|
25
|
+
def initialize(params = {})
|
26
|
+
@timestamp = (params['timestamp'].to_i rescue nil)
|
27
|
+
@seconds = (params['seconds'].to_i rescue nil)
|
28
|
+
@totals = {
|
29
|
+
:seconds => (params['totals']['seconds'].to_i rescue nil),
|
30
|
+
:seen => (params['totals']['seen'].to_i rescue nil),
|
31
|
+
:completed => (params['totals']['completed'].to_i rescue nil)
|
32
|
+
}
|
33
|
+
@seen = (params['seen'].to_i rescue nil)
|
34
|
+
@completed = (params['completed'].to_i rescue nil)
|
35
|
+
@date = (Date.parse(params['date']) rescue nil)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.find(username)
|
40
|
+
response = Iknow::RestClient::User.find(:username => username)
|
41
|
+
self.deserialize(response)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.matching(keyword, params = {})
|
45
|
+
params[:keyword] = keyword
|
46
|
+
response = Iknow::RestClient::User.matching(params)
|
47
|
+
self.deserialize(response)
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize(params)
|
51
|
+
@profile = Profile.new(params['profile'])
|
52
|
+
@username = params['username']
|
53
|
+
end
|
54
|
+
|
55
|
+
def items(params = {})
|
56
|
+
return @items if @items
|
57
|
+
|
58
|
+
response = Iknow::RestClient::User.items(params.merge(:username => self.username))
|
59
|
+
self.deserialize(response, :as => Iknow::Item)
|
60
|
+
end
|
61
|
+
|
62
|
+
def lists(params = {})
|
63
|
+
return @lists if @lists
|
64
|
+
|
65
|
+
response = Iknow::RestClient::User.lists(params.merge(:username => self.username))
|
66
|
+
self.deserialize(response, :as => Iknow::List)
|
67
|
+
end
|
68
|
+
|
69
|
+
def friends(params = {})
|
70
|
+
return @friends if @friends
|
71
|
+
|
72
|
+
response = Iknow::RestClient::User.friends(params.merge(:username => self.username))
|
73
|
+
self.deserialize(response)
|
74
|
+
end
|
75
|
+
|
76
|
+
def study_results(params = {})
|
77
|
+
return @study_results if @study_results
|
78
|
+
|
79
|
+
params[:application] ||= :iknow
|
80
|
+
response = Iknow::RestClient::User.study_results(params.merge(:username => self.username))
|
81
|
+
self.deserialize(response, :as => Iknow::User::StudyResult)
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/lib/iknow/model.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
class Iknow::RestClient::Base
|
2
|
+
|
3
|
+
class RESTError < Exception
|
4
|
+
attr_accessor :code, :message, :uri
|
5
|
+
|
6
|
+
def initialize(params = {})
|
7
|
+
self.code = params[:code]
|
8
|
+
self.message = params[:message]
|
9
|
+
self.uri = params[:uri]
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"HTTP #{@code}: #{@message} at #{@uri}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class ResourceError < RESTError ; end
|
17
|
+
class ResourceNotFound < ResourceError ; end
|
18
|
+
class ResourceAccessDenied < ResourceError ; end
|
19
|
+
|
20
|
+
def self.valid_action?(action) ; self::ACTIONS.keys.include? action.to_sym end
|
21
|
+
def self.path(action) ; self::ACTIONS[action.to_sym][:path] end
|
22
|
+
def self.http_method(action) ; self::ACTIONS[action.to_sym][:http_method] || :get end
|
23
|
+
|
24
|
+
def self.method_missing(action, *args)
|
25
|
+
# GET methods are handled here
|
26
|
+
# POST and DELETE methods should be implemented in each class
|
27
|
+
super unless self.valid_action?(action)
|
28
|
+
uri, params = replace_uri_params(self.path(action), args[0])
|
29
|
+
http_connect do |conn|
|
30
|
+
case self.http_method(action)
|
31
|
+
when :get
|
32
|
+
http_get_request(uri, params)
|
33
|
+
when :post
|
34
|
+
http_post_request(uri, params)
|
35
|
+
when :delete
|
36
|
+
http_delete_request(uri, params)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.config; Iknow::Config.instance end
|
44
|
+
|
45
|
+
def self.api_key_required
|
46
|
+
raise ArgumentError.new("iKnow! API key is required") if self.config.api_key == ''
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.http_connect
|
50
|
+
connection = Net::HTTP.new(self.config.host, self.config.port)
|
51
|
+
connection.start do |conn|
|
52
|
+
request = yield connection
|
53
|
+
response = conn.request(request)
|
54
|
+
handle_rest_response(response)
|
55
|
+
json_response = JSON.parse(response.body)
|
56
|
+
handle_json_response(json_response)
|
57
|
+
json_response
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.raise_json_error(code, message, uri = nil)
|
62
|
+
case code
|
63
|
+
when 403
|
64
|
+
raise ResourceAccessDenied.new(:code => code, :message => message, :uri => uri)
|
65
|
+
when 404
|
66
|
+
raise ResourceNotFound.new(:code => code, :message => message, :uri => uri)
|
67
|
+
else
|
68
|
+
raise ResourceError.new(:code => code, :message => message, :uri => uri)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.raise_rest_error(response, uri = nil)
|
73
|
+
raise RESTError.new(:code => response.code, :message => response.message, :uri => uri)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.handle_json_response(json_response, uri = nil)
|
77
|
+
jsoon_error = json_response.is_a?(Hash) ? json_response['error'] : nil
|
78
|
+
raise_json_error(jsoon_error['code'], jsoon_error['message'], uri) unless jsoon_error.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.handle_rest_response(response, uri = nil)
|
82
|
+
raise_rest_error(response, uri) unless response.is_a?(Net::HTTPSuccess)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.http_header
|
86
|
+
@@http_header ||= {
|
87
|
+
'User-Agent' => "iKnow! API v#{Iknow::Version.to_version} [#{self.config.user_agent}]",
|
88
|
+
'Accept' => 'text/x-json',
|
89
|
+
'X-iKnow-Client' => self.config.application_name,
|
90
|
+
'X-iKnow-Client-Version' => self.config.application_version,
|
91
|
+
'X-iKnow-Client-URL' => self.config.application_url,
|
92
|
+
}
|
93
|
+
@@http_header
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.replace_uri_params(uri, params = {})
|
97
|
+
unless params.empty?
|
98
|
+
params.each do |key, value|
|
99
|
+
if uri=~/__#{key}__/
|
100
|
+
uri.sub!(/__#{key}__/, value.to_s)
|
101
|
+
params.delete(key)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
return uri, params
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.http_get_request(uri, params = {})
|
109
|
+
path = (params.size > 0) ? "#{uri}?#{params.to_http_str}" : uri
|
110
|
+
Net::HTTP::Get.new(path, http_header)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.http_post_request(uri, params = {})
|
114
|
+
self.api_key_required
|
115
|
+
request = Net::HTTP::Post.new(uri, http_header)
|
116
|
+
request.body = params.merge(:api_key => self.config.api_key).to_http_str
|
117
|
+
request
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.http_delete_request(uri, params = {})
|
121
|
+
path = (params.size > 0) ? "#{uri}?#{params.to_http_str}" : uri
|
122
|
+
Net::HTTP::Delete.new(path, http_header)
|
123
|
+
end
|
124
|
+
|
125
|
+
private_class_method :http_connect, :raise_rest_error, :handle_rest_response, :http_header,
|
126
|
+
:replace_uri_params, :http_get_request, :http_post_request, :http_delete_request
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Iknow::RestClient::Item < Iknow::RestClient::Base
|
2
|
+
|
3
|
+
ACTIONS = {
|
4
|
+
:recent => { :path => '/items' },
|
5
|
+
:matching => { :path => '/items/matching/__keyword__' },
|
6
|
+
:add_image => { :path => '/items/__id__/images', :http_method => :post },
|
7
|
+
:add_sound => { :path => '/items/__id__/sounds', :http_method => :post },
|
8
|
+
:extract => { :path => '/items/extract', :http_method => :post }
|
9
|
+
}
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Iknow::RestClient::List < Iknow::RestClient::Base
|
2
|
+
|
3
|
+
ACTIONS = {
|
4
|
+
:recent => { :path => '/lists' },
|
5
|
+
:items => { :path => '/lists/__id__/items' },
|
6
|
+
:sentences => { :path => '/lists/__id__/sentences' },
|
7
|
+
:matching => { :path => '/lists/matching/__keyword__' },
|
8
|
+
:create => { :path => '/lists', :http_method => :post },
|
9
|
+
:delete => { :path => '/lists/__id__', :http_method => :delete }
|
10
|
+
}
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Iknow::RestClient::Sentence < Iknow::RestClient::Base
|
2
|
+
|
3
|
+
ACTIONS = {
|
4
|
+
:recent => { :path => '/sentences' },
|
5
|
+
:matching => { :path => '/sentences/matching/__keyword__' },
|
6
|
+
:create => { :path => '/sentences', :http_method => :post },
|
7
|
+
:add_image => { :path => '/sentences/__id__/images', :http_method => :post },
|
8
|
+
:add_sound => { :path => '/sentences/__id__/sounds', :http_method => :post }
|
9
|
+
}
|
10
|
+
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Iknow::RestClient::User < Iknow::RestClient::Base
|
2
|
+
|
3
|
+
ACTIONS = {
|
4
|
+
:find => { :path => '/users/__username__' },
|
5
|
+
:lists => { :path => '/users/__username__/lists' },
|
6
|
+
:items => { :path => '/users/__username__/items' },
|
7
|
+
:friends => { :path => '/users/__username__/friends' },
|
8
|
+
:study_results => { :path => '/users/__username__/study_results/__application__' },
|
9
|
+
:matching => { :path => '/users/matching/__keyword__' }
|
10
|
+
}
|
11
|
+
|
12
|
+
end
|
data/lib/iknow.rb
ADDED
data/test/iknow_test.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nov-iknow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-16 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: A rubygem for iKnow! APIs
|
25
|
+
email: developer@iknow.co.jp
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- ChangeLog
|
33
|
+
files:
|
34
|
+
- README
|
35
|
+
- ChangeLog
|
36
|
+
- Rakefile
|
37
|
+
- test/iknow_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
- lib/ext
|
40
|
+
- lib/ext/hash.rb
|
41
|
+
- lib/iknow
|
42
|
+
- lib/iknow/core
|
43
|
+
- lib/iknow/core/config.rb
|
44
|
+
- lib/iknow/core/version.rb
|
45
|
+
- lib/iknow/core.rb
|
46
|
+
- lib/iknow/model
|
47
|
+
- lib/iknow/model/base.rb
|
48
|
+
- lib/iknow/model/item.rb
|
49
|
+
- lib/iknow/model/list.rb
|
50
|
+
- lib/iknow/model/sentence.rb
|
51
|
+
- lib/iknow/model/user.rb
|
52
|
+
- lib/iknow/model.rb
|
53
|
+
- lib/iknow/rest_client
|
54
|
+
- lib/iknow/rest_client/base.rb
|
55
|
+
- lib/iknow/rest_client/item.rb
|
56
|
+
- lib/iknow/rest_client/list.rb
|
57
|
+
- lib/iknow/rest_client/sentence.rb
|
58
|
+
- lib/iknow/rest_client/user.rb
|
59
|
+
- lib/iknow/rest_client.rb
|
60
|
+
- lib/iknow.rb
|
61
|
+
- examples/pure_ruby.rb
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: http://iknow.rubyforge.org
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options:
|
66
|
+
- --title
|
67
|
+
- iknow documentation
|
68
|
+
- --charset
|
69
|
+
- utf-8
|
70
|
+
- --opname
|
71
|
+
- index.html
|
72
|
+
- --line-numbers
|
73
|
+
- --main
|
74
|
+
- README
|
75
|
+
- --inline-source
|
76
|
+
- --exclude
|
77
|
+
- ^(examples|extras)/
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
requirements: []
|
93
|
+
|
94
|
+
rubyforge_project: iknow
|
95
|
+
rubygems_version: 1.2.0
|
96
|
+
signing_key:
|
97
|
+
specification_version: 2
|
98
|
+
summary: A rubygem for iKnow! APIs
|
99
|
+
test_files:
|
100
|
+
- test/iknow_test.rb
|