smartfm 0.3.0
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 +38 -0
- data/README +45 -0
- data/Rakefile +155 -0
- data/examples/pure_ruby.rb +118 -0
- data/lib/ext/hash.rb +52 -0
- data/lib/smartfm.rb +16 -0
- data/lib/smartfm/core.rb +3 -0
- data/lib/smartfm/core/auth.rb +39 -0
- data/lib/smartfm/core/config.rb +51 -0
- data/lib/smartfm/core/version.rb +14 -0
- data/lib/smartfm/model.rb +5 -0
- data/lib/smartfm/model/base.rb +26 -0
- data/lib/smartfm/model/item.rb +174 -0
- data/lib/smartfm/model/list.rb +138 -0
- data/lib/smartfm/model/sentence.rb +118 -0
- data/lib/smartfm/model/user.rb +108 -0
- data/lib/smartfm/rest_client.rb +8 -0
- data/lib/smartfm/rest_client/base.rb +173 -0
- data/lib/smartfm/rest_client/item.rb +14 -0
- data/lib/smartfm/rest_client/list.rb +15 -0
- data/lib/smartfm/rest_client/sentence.rb +12 -0
- data/lib/smartfm/rest_client/user.rb +13 -0
- data/spec/ext/hash_spec.rb +11 -0
- data/spec/smartfm/core/auth_spec.rb +39 -0
- data/spec/smartfm/core/config_spec.rb +34 -0
- data/spec/smartfm/core/version_spec.rb +19 -0
- data/spec/smartfm/model/base_spec.rb +40 -0
- data/spec/smartfm/model/item_spec.rb +41 -0
- data/spec/smartfm/model/list_spec.rb +7 -0
- data/spec/smartfm/model/sentence_spec.rb +7 -0
- data/spec/smartfm/model/user_spec.rb +90 -0
- data/spec/smartfm/rest_client/base_spec.rb +9 -0
- data/spec/smartfm/rest_client/item_spec.rb +7 -0
- data/spec/smartfm/rest_client/list_spec.rb +7 -0
- data/spec/smartfm/rest_client/sentence_spec.rb +7 -0
- data/spec/smartfm/rest_client/user_spec.rb +7 -0
- data/spec/spec_helper.rb +18 -0
- data/test/smartfm_test.rb +8 -0
- data/test/test_helper.rb +3 -0
- metadata +132 -0
data/ChangeLog
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
== 0.0.1 / 2008-10-13
|
2
|
+
|
3
|
+
* initial release
|
4
|
+
|
5
|
+
== 0.0.2
|
6
|
+
|
7
|
+
== 0.0.3
|
8
|
+
|
9
|
+
== 0.0.4
|
10
|
+
|
11
|
+
* add new API calls
|
12
|
+
* add new attributes
|
13
|
+
|
14
|
+
== 0.1.0
|
15
|
+
|
16
|
+
* add Smartfm::Auth (supports basic_auth and oauth)
|
17
|
+
* add List#create, List#delete, List#add_item, List#delete_item
|
18
|
+
|
19
|
+
== 0.1.1
|
20
|
+
|
21
|
+
* remove Mechanize
|
22
|
+
|
23
|
+
== 0.2.0
|
24
|
+
|
25
|
+
* support almost all API calls
|
26
|
+
|
27
|
+
== 0.2.1
|
28
|
+
|
29
|
+
* maintenance release
|
30
|
+
|
31
|
+
== 0.2.2
|
32
|
+
|
33
|
+
* add attribution support for add_image & add_sound APIs
|
34
|
+
|
35
|
+
== 0.3.0
|
36
|
+
|
37
|
+
* iKnow! => smart.fm
|
38
|
+
* now, iKnow! is the name of Flash study application
|
data/README
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
= smart.fm
|
2
|
+
|
3
|
+
by nov <nov@cerego.com>
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
This rubygem is a wrapper of smart.fm API.
|
8
|
+
You can get pure-ruby example at examples/pure_ruby.rb.
|
9
|
+
http://github.com/nov/smartfm/tree/master/examples/pure_ruby.rb
|
10
|
+
|
11
|
+
It shows all API calls you can use with this gem.
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
git clone http://github.com/nov/smartfm.git
|
16
|
+
cd smartfm
|
17
|
+
rake install
|
18
|
+
|
19
|
+
=== Archive Installation
|
20
|
+
|
21
|
+
rake install
|
22
|
+
|
23
|
+
=== Gem Installation
|
24
|
+
|
25
|
+
gem install smartfm
|
26
|
+
|
27
|
+
== Features/Problems
|
28
|
+
|
29
|
+
Test! Test!! Test!!!
|
30
|
+
|
31
|
+
Create/Add/Delete APIs are not implemented.
|
32
|
+
They will be implemented in a few weeks.
|
33
|
+
|
34
|
+
smart.fm OAuth is still pre-alpha.
|
35
|
+
|
36
|
+
== Synopsis
|
37
|
+
|
38
|
+
See examples and smart.fm Developers, please.
|
39
|
+
smart.fm Developers (http://developer.smart.fm)
|
40
|
+
|
41
|
+
== Copyright
|
42
|
+
|
43
|
+
Author:: nov <nov@cerego.com>
|
44
|
+
Copyright:: Copyright (c) 2009 nov
|
45
|
+
License:: MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,155 @@
|
|
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 = "smartfm"
|
14
|
+
AUTHOR = "nov"
|
15
|
+
EMAIL = "developer@smart.fm"
|
16
|
+
DESCRIPTION = "A rubygem for smart.fm APIs"
|
17
|
+
RUBYFORGE_PROJECT = NAME
|
18
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
19
|
+
BIN_FILES = %w( )
|
20
|
+
|
21
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/lib"
|
22
|
+
require 'lib/smartfm'
|
23
|
+
VERS = Smartfm::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
|
+
Rake::TestTask.new("spec") do |t|
|
45
|
+
t.libs << "spec"
|
46
|
+
t.pattern = "spec/**/*_spec.rb"
|
47
|
+
t.verbose = true
|
48
|
+
end
|
49
|
+
|
50
|
+
spec = Gem::Specification.new do |s|
|
51
|
+
s.name = NAME
|
52
|
+
s.version = VERS
|
53
|
+
s.platform = Gem::Platform::RUBY
|
54
|
+
s.has_rdoc = true
|
55
|
+
s.extra_rdoc_files = ["README", "ChangeLog"]
|
56
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
57
|
+
s.summary = DESCRIPTION
|
58
|
+
s.description = DESCRIPTION
|
59
|
+
s.author = AUTHOR
|
60
|
+
s.email = EMAIL
|
61
|
+
s.homepage = HOMEPATH
|
62
|
+
s.executables = BIN_FILES
|
63
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
64
|
+
s.bindir = "bin"
|
65
|
+
s.require_path = "lib"
|
66
|
+
#s.autorequire = ""
|
67
|
+
s.test_files = Dir["test/*_test.rb"]
|
68
|
+
|
69
|
+
s.add_dependency('json')
|
70
|
+
s.add_dependency('oauth')
|
71
|
+
# s.required_ruby_version = '>= 1.8.6'
|
72
|
+
|
73
|
+
s.files = %w(README ChangeLog Rakefile) +
|
74
|
+
Dir.glob("{bin,doc,test,spec,lib,templates,extras,website,script}/**/*") +
|
75
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
76
|
+
Dir.glob("examples/**/*.rb") +
|
77
|
+
Dir.glob("tools/*.rb") +
|
78
|
+
Dir.glob("rails/*.rb")
|
79
|
+
|
80
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
81
|
+
end
|
82
|
+
|
83
|
+
Rake::GemPackageTask.new(spec) do |p|
|
84
|
+
p.need_tar = true
|
85
|
+
p.gem_spec = spec
|
86
|
+
end
|
87
|
+
|
88
|
+
desc "Install"
|
89
|
+
task :install do
|
90
|
+
name = "#{NAME}-#{VERS}.gem"
|
91
|
+
sh %{rake package}
|
92
|
+
sh %{sudo gem install pkg/#{name}}
|
93
|
+
end
|
94
|
+
|
95
|
+
desc "Uninstall"
|
96
|
+
task :uninstall => [:clean] do
|
97
|
+
sh %{sudo gem uninstall #{NAME}}
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
Rake::RDocTask.new do |rdoc|
|
102
|
+
rdoc.rdoc_dir = 'html'
|
103
|
+
rdoc.options += RDOC_OPTS
|
104
|
+
rdoc.template = "resh"
|
105
|
+
#rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
106
|
+
if ENV['DOC_FILES']
|
107
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
108
|
+
else
|
109
|
+
rdoc.rdoc_files.include('README', 'ChangeLog')
|
110
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
111
|
+
rdoc.rdoc_files.include('ext/**/*.c')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Publish to RubyForge"
|
116
|
+
task :rubyforge => [:rdoc, :package] do
|
117
|
+
require 'rubyforge'
|
118
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'nov').upload
|
119
|
+
end
|
120
|
+
|
121
|
+
# rake release VERSION=x.y.z
|
122
|
+
desc 'Package and upload the release to rubyforge.'
|
123
|
+
task :release => [:clean, :package] do |t|
|
124
|
+
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
125
|
+
abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
|
126
|
+
pkg = "pkg/#{NAME}-#{VERS}"
|
127
|
+
|
128
|
+
require 'rubyforge'
|
129
|
+
rf = RubyForge.new.configure
|
130
|
+
puts "Logging in"
|
131
|
+
rf.login
|
132
|
+
|
133
|
+
c = rf.userconfig
|
134
|
+
# c["release_notes"] = description if description
|
135
|
+
# c["release_changes"] = changes if changes
|
136
|
+
c["preformatted"] = true
|
137
|
+
|
138
|
+
files = [
|
139
|
+
"#{pkg}.tgz",
|
140
|
+
"#{pkg}.gem"
|
141
|
+
].compact
|
142
|
+
|
143
|
+
puts "Releasing #{NAME} v. #{VERS}"
|
144
|
+
rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
|
145
|
+
end
|
146
|
+
|
147
|
+
desc 'Show information about the gem.'
|
148
|
+
task :debug_gem do
|
149
|
+
puts spec.to_ruby
|
150
|
+
end
|
151
|
+
|
152
|
+
desc 'Update gem spec'
|
153
|
+
task :gemspec do
|
154
|
+
open("#{NAME}.gemspec", 'w').write spec.to_ruby
|
155
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'smartfm'
|
3
|
+
require 'oauth/consumer'
|
4
|
+
|
5
|
+
Smartfm::Config.init do |conf|
|
6
|
+
conf.api_host = 'api.smart.fm'
|
7
|
+
conf.api_key = '' # 'SET_YOUR_API_KEY'
|
8
|
+
conf.oauth_consumer_key = '' # 'SET_YOUR_OAUTH_CONSUMER_KEY'
|
9
|
+
conf.oauth_consumer_secret = '' # 'SET_YOUR_OAUTH_CONSUMER_SECRET'
|
10
|
+
conf.oauth_http_method = :post
|
11
|
+
conf.oauth_scheme = :header
|
12
|
+
conf.timeout = 15
|
13
|
+
end
|
14
|
+
|
15
|
+
# Edit here
|
16
|
+
OAUTH_ACCESS_TOKEN = ''
|
17
|
+
OAUTH_ACCESS_TOKEN_SECRET = ''
|
18
|
+
|
19
|
+
# Edit here
|
20
|
+
SMARTFM_USERNAME = ''
|
21
|
+
SMARTFM_PASSWORD = ''
|
22
|
+
|
23
|
+
please_get_api_key =<<EOS
|
24
|
+
This example needs your own smart.fm API key.
|
25
|
+
(for only Smartfm::Item.extract example)
|
26
|
+
|
27
|
+
You can get smart.fm API key at smart.fm Developers.
|
28
|
+
smart.fm Developers (http://developer.smart.fm/)
|
29
|
+
|
30
|
+
Thanks!
|
31
|
+
EOS
|
32
|
+
|
33
|
+
if Smartfm::Config.api_key == ''
|
34
|
+
raise ArgumentError.new(please_get_api_key)
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
###########################
|
39
|
+
## WITHOUT AUTHORIZATION ##
|
40
|
+
###########################
|
41
|
+
|
42
|
+
puts "WITHOUT AUTHORIZATION"
|
43
|
+
|
44
|
+
## User API
|
45
|
+
puts "# User API Calls"
|
46
|
+
@user = Smartfm::User.find('kirk')
|
47
|
+
@user.items(:include_sentences => true)
|
48
|
+
@user.lists
|
49
|
+
@user.friends
|
50
|
+
@user.study.results
|
51
|
+
@user.study.total_summary
|
52
|
+
@matched_users = Smartfm::User.matching('matake')
|
53
|
+
|
54
|
+
## List API
|
55
|
+
puts "# List API Calls"
|
56
|
+
@recent_lists = Smartfm::List.recent
|
57
|
+
@list = Smartfm::List.find(31509, :include_sentences => true, :include_items => true)
|
58
|
+
@list.items
|
59
|
+
@list.sentences
|
60
|
+
@matched_lists = Smartfm::List.matching("イタリア語であいさつ")
|
61
|
+
|
62
|
+
## Item API
|
63
|
+
puts "# Item API Calls"
|
64
|
+
@recent_items = Smartfm::Item.recent(:include_sentences => true)
|
65
|
+
@item = Smartfm::Item.find(437525)
|
66
|
+
@matched_items = Smartfm::Item.matching('record', :include_sentences => true)
|
67
|
+
@items = Smartfm::Item.extract("sometimes, often, electrical")
|
68
|
+
@items.first.sentences
|
69
|
+
|
70
|
+
## Sentence API
|
71
|
+
puts "# Sentence API Calls"
|
72
|
+
@recent_sentences = Smartfm::Sentence.recent
|
73
|
+
@sentence = Smartfm::Sentence.find(312271)
|
74
|
+
@matched_sentences = Smartfm::Sentence.matching('record')
|
75
|
+
|
76
|
+
|
77
|
+
########################
|
78
|
+
## WITH AUTHORIZATION ##
|
79
|
+
########################
|
80
|
+
|
81
|
+
auth = case
|
82
|
+
when !OAUTH_ACCESS_TOKEN.empty?
|
83
|
+
if Smartfm::Config.oauth_consumer_key.empty? or Smartfm::Config.oauth_consumer_secret.empty?
|
84
|
+
raise ArgumentError.new("oauth_consumer_key and oauth_consumer_secret are required")
|
85
|
+
end
|
86
|
+
Smartfm::Auth.new(:token => OAUTH_ACCESS_TOKEN, :secret => OAUTH_ACCESS_TOKEN_SECRET)
|
87
|
+
when SMARTFM_USERNAME != ''
|
88
|
+
Smartfm::Auth.new(:username => SMARTFM_USERNAME, :password => SMARTFM_PASSWORD)
|
89
|
+
else
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
unless auth
|
93
|
+
puts "Skip calls which require authentication"
|
94
|
+
exit
|
95
|
+
else
|
96
|
+
puts "## WITH AUTHORIZATION :: #{auth.mode}"
|
97
|
+
end
|
98
|
+
|
99
|
+
## List API
|
100
|
+
puts "# List API"
|
101
|
+
@list = Smartfm::List.create(auth, :title => 'smart.fm gem test', :description => 'A list for smart.fm gem test')
|
102
|
+
@list.add_item(auth, Smartfm::Item.find(437525))
|
103
|
+
@list.delete_item(auth, @list.items.first)
|
104
|
+
@list.delete(auth)
|
105
|
+
|
106
|
+
## Item API
|
107
|
+
puts "# Item API"
|
108
|
+
@item = Smartfm::Item.create(auth, :cue => {:text => 'hello world! 2', :language => 'en', :part_of_speech => 'E'},
|
109
|
+
:response => {:text => 'ハローワールド!', :language => 'ja'})
|
110
|
+
@item.add_image(auth, 'http://farm4.static.flickr.com/3276/3102381796_a33c1ffdf1.jpg')
|
111
|
+
@item.add_sound(auth, 'http://matake.jp/download/hello_world.mp3')
|
112
|
+
@item.add_tags(auth, 'sample', 'programming')
|
113
|
+
|
114
|
+
## Sentence API
|
115
|
+
puts "# Sentence API"
|
116
|
+
@sentence = Smartfm::Sentence.create(auth, :text => 'Hello World!', :item => Smartfm::Item.matching('hello world').first)
|
117
|
+
@sentence.add_image(auth, 'http://farm4.static.flickr.com/3276/3102381796_a33c1ffdf1.jpg')
|
118
|
+
@sentence.add_sound(auth, 'http://matake.jp/download/hello_world.mp3')
|
data/lib/ext/hash.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def to_http_str
|
4
|
+
result = ''
|
5
|
+
return result if self.empty?
|
6
|
+
self.each do |key, val|
|
7
|
+
result << "#{key}=#{URI.encode(val.to_s)}&"
|
8
|
+
end
|
9
|
+
result.chop
|
10
|
+
end
|
11
|
+
|
12
|
+
def symbolize_keys!
|
13
|
+
self.each do |key, value|
|
14
|
+
unless self.delete(key.to_s).nil?
|
15
|
+
if value.is_a?(Hash)
|
16
|
+
value.symbolize_keys!
|
17
|
+
elsif value.is_a?(Array)
|
18
|
+
value.map!{ |v| v.symbolize_keys! if v.is_a?(Hash) }
|
19
|
+
end
|
20
|
+
self[key.to_sym] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def stringfy_keys!
|
27
|
+
self.each do |key, value|
|
28
|
+
unless self.delete(key.to_sym).nil?
|
29
|
+
if value.is_a?(Hash)
|
30
|
+
value.stringfy_keys!
|
31
|
+
elsif value.is_a?(Array)
|
32
|
+
value.map!{ |v| v.stringfy_keys! if v.is_a?(Hash) }
|
33
|
+
end
|
34
|
+
self[key.to_s] = value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def stringfy_values!
|
41
|
+
self.each do |key, value|
|
42
|
+
if value.is_a?(Hash)
|
43
|
+
value.stringfy_values!
|
44
|
+
elsif value.is_a?(Array)
|
45
|
+
value.map!{ |v| v.stringfy_values! if v.is_a?(Hash) }
|
46
|
+
end
|
47
|
+
self[key] = value.to_s
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
data/lib/smartfm.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Smartfm
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'date'
|
5
|
+
require 'net/https'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
require 'ext/hash'
|
12
|
+
require 'smartfm/core'
|
13
|
+
require 'smartfm/rest_client'
|
14
|
+
require 'smartfm/model'
|
15
|
+
|
16
|
+
Smartfm::Config.init
|
data/lib/smartfm/core.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'oauth/consumer'
|
2
|
+
|
3
|
+
class Smartfm::Auth
|
4
|
+
attr_accessor :mode, :auth_token
|
5
|
+
|
6
|
+
class Basic
|
7
|
+
attr_reader :username, :password
|
8
|
+
|
9
|
+
def initialize(username, password)
|
10
|
+
@username = username
|
11
|
+
@password = password
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(options = {})
|
16
|
+
if options[:username] && options[:password]
|
17
|
+
@mode = :basic_auth
|
18
|
+
@auth_token = Basic.new(options[:username], options[:password])
|
19
|
+
elsif options[:token] && options[:secret]
|
20
|
+
@mode = :oauth
|
21
|
+
@auth_token = OAuth::AccessToken.new(Smartfm::Auth.consumer, options[:token], options[:secret])
|
22
|
+
else
|
23
|
+
raise ArgumentError.new('{:auth => "oauth_access_token", :secret => "oauth_access_token_secret"} or {:username "smartfm_username", :password => "smartfm_password"} is needed')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.consumer
|
28
|
+
@@consumer ||= OAuth::Consumer.new(
|
29
|
+
Smartfm::Config.oauth_consumer_key,
|
30
|
+
Smartfm::Config.oauth_consumer_secret,
|
31
|
+
:http_method => Smartfm::Config.oauth_http_method,
|
32
|
+
:scheme => Smartfm::Config.oauth_scheme,
|
33
|
+
:site => Smartfm::Config.api_base_url,
|
34
|
+
:authorize_url => "#{Smartfm::Config.base_url}/oauth/authorize"
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method :account, :auth_token
|
39
|
+
end
|