smartfm 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/ChangeLog +38 -0
  2. data/README +45 -0
  3. data/Rakefile +155 -0
  4. data/examples/pure_ruby.rb +118 -0
  5. data/lib/ext/hash.rb +52 -0
  6. data/lib/smartfm.rb +16 -0
  7. data/lib/smartfm/core.rb +3 -0
  8. data/lib/smartfm/core/auth.rb +39 -0
  9. data/lib/smartfm/core/config.rb +51 -0
  10. data/lib/smartfm/core/version.rb +14 -0
  11. data/lib/smartfm/model.rb +5 -0
  12. data/lib/smartfm/model/base.rb +26 -0
  13. data/lib/smartfm/model/item.rb +174 -0
  14. data/lib/smartfm/model/list.rb +138 -0
  15. data/lib/smartfm/model/sentence.rb +118 -0
  16. data/lib/smartfm/model/user.rb +108 -0
  17. data/lib/smartfm/rest_client.rb +8 -0
  18. data/lib/smartfm/rest_client/base.rb +173 -0
  19. data/lib/smartfm/rest_client/item.rb +14 -0
  20. data/lib/smartfm/rest_client/list.rb +15 -0
  21. data/lib/smartfm/rest_client/sentence.rb +12 -0
  22. data/lib/smartfm/rest_client/user.rb +13 -0
  23. data/spec/ext/hash_spec.rb +11 -0
  24. data/spec/smartfm/core/auth_spec.rb +39 -0
  25. data/spec/smartfm/core/config_spec.rb +34 -0
  26. data/spec/smartfm/core/version_spec.rb +19 -0
  27. data/spec/smartfm/model/base_spec.rb +40 -0
  28. data/spec/smartfm/model/item_spec.rb +41 -0
  29. data/spec/smartfm/model/list_spec.rb +7 -0
  30. data/spec/smartfm/model/sentence_spec.rb +7 -0
  31. data/spec/smartfm/model/user_spec.rb +90 -0
  32. data/spec/smartfm/rest_client/base_spec.rb +9 -0
  33. data/spec/smartfm/rest_client/item_spec.rb +7 -0
  34. data/spec/smartfm/rest_client/list_spec.rb +7 -0
  35. data/spec/smartfm/rest_client/sentence_spec.rb +7 -0
  36. data/spec/smartfm/rest_client/user_spec.rb +7 -0
  37. data/spec/spec_helper.rb +18 -0
  38. data/test/smartfm_test.rb +8 -0
  39. data/test/test_helper.rb +3 -0
  40. 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
@@ -0,0 +1,3 @@
1
+ require 'smartfm/core/version'
2
+ require 'smartfm/core/config'
3
+ require 'smartfm/core/auth'
@@ -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