nov-iknow 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/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
|