njacobeus-tokboxer 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ == 0.1.1 2008-11-26
2
+
3
+ * Fixed config problem causing missing files in the gem
4
+
5
+ == 0.1.0 2008-11-13
6
+
7
+ * First gem release
8
+
9
+ == 0.0.2 2008-11-05
10
+
11
+ * Added classes VMail and Call
12
+ * Corrected bug with url encoding (didn't deal properly with spaces in params)
13
+ * Some stupid bugs removed
14
+ * Added some documentation and cleaned the gem
15
+ * Removed useless dependency on rest-client (just using Net::HTTP now)
16
+
17
+ == 0.0.1 2008-11-03
18
+
19
+ * Initial release with all the methods implemented
@@ -0,0 +1,24 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ config/website.yml.sample
7
+ lib/TokBoxer.rb
8
+ lib/TokBoxer/Api.rb
9
+ lib/TokBoxer/Call.rb
10
+ lib/TokBoxer/User.rb
11
+ lib/TokBoxer/VMail.rb
12
+ script/console
13
+ script/destroy
14
+ script/generate
15
+ script/txt2html
16
+ spec/TokBoxer_spec.rb
17
+ spec/spec.opts
18
+ spec/spec_helper.rb
19
+ tasks/rspec.rake
20
+ website/index.html
21
+ website/index.txt
22
+ website/javascripts/rounded_corners_lite.inc.js
23
+ website/stylesheets/screen.css
24
+ website/template.html.erb
@@ -0,0 +1,7 @@
1
+
2
+ For more information on TokBoxer, see http://TokBoxer.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
@@ -0,0 +1,109 @@
1
+ = TokBoxer
2
+
3
+ * http://github.com/njacobeus/tokboxer/
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is a ruby implementation of the TokBox API. Tokbox is a free video calling / video mailing platform (see http://www.tokbox.com).
8
+
9
+ All API methods specified in the Tokbox Developer API wiki (http://developers.tokbox.com/index.php/API) are implemented but not all objects yet. So you may have to dig into the hash returned by the call (XML converted to a Ruby hash).
10
+
11
+ For the moment, this gem currently specifically serves our needs for the implementation of video conversations and video mails on iStockCV (www.istockcv.com), an online recruitment network which we are developing. Your needs may vary so feel free to contact me (nj@belighted.com).
12
+
13
+ == FEATURES/PROBLEMS:
14
+
15
+ * Features currently available:
16
+
17
+ * Create a guest user or register a user on TokBox
18
+
19
+ * Get information about a user
20
+
21
+ * Create a call
22
+
23
+ * Retrieve the list of vmails for a user
24
+
25
+ * Generate embed codes for a player, a recorder, and a call
26
+
27
+ * Limitations:
28
+
29
+ * For the moment, the Call and VMail objects are quite simple (they only hold an id)
30
+
31
+ * No tests yet (ouch)
32
+
33
+ == SYNOPSIS:
34
+
35
+ # To create an instance of the API object:
36
+
37
+ api = TokBoxer::Api.new(partner_key, partner_secret, api_server_url) # defaults to "http://sandbox.tokbox.com/"
38
+
39
+ # To create a user instance:
40
+
41
+ user = api.create_guest_user
42
+ # or
43
+ user = api.register_user(firstname, lastname, email)
44
+ # or if you have already created a user previously on TokBox
45
+ user = api.create_user(user_jabber_id, user_secret)
46
+
47
+ # To get info about the user object:
48
+
49
+ user.access_token_valid? # returns true or false whether the secret of the user is correct or not
50
+ user.is_online?
51
+ user.display_name
52
+ user.username
53
+ user.userid
54
+ user.show
55
+
56
+ # To embed a player or a recorder:
57
+
58
+ user.recorder_embed_code(width, height) # returns the HTML for embedding a recorder
59
+ user.player_embed_code(message_id, width, height) # returns the HTML for embedding a player for a specific message
60
+
61
+ # To create a call:
62
+
63
+ call = user.create_call("My full name") # set "true" as 2nd param if you want it persistent
64
+ call.embed_code # returns the HTML for embedding the call in a web page
65
+
66
+ # To manipulate vmails:
67
+
68
+ user.vmails # returns an array of VMail objects for all the vmails in the user's feed
69
+ user.sent_vmails # returns an array of VMail objects for sent vmails only
70
+ user.received_vmails # returns an array of VMail objects for received vmails only
71
+
72
+ == REQUIREMENTS:
73
+
74
+ * xml-simple
75
+ * A partner key and a partner secret at Tokbox (you can get those here: http://developers.tokbox.com/index.php/Main_Page)
76
+
77
+ == INSTALL:
78
+
79
+ * gem sources -a http://gems.github.com
80
+ * sudo gem install njacobeus-tokboxer
81
+
82
+ OR (from RubyForge)
83
+
84
+ * sudo gem install tokboxer
85
+
86
+ == LICENSE:
87
+
88
+ (The MIT License)
89
+
90
+ Copyright (c) 2008 Nicolas Jacobeus - Belighted SPRL (http://www.belighted.com/)
91
+
92
+ Permission is hereby granted, free of charge, to any person obtaining
93
+ a copy of this software and associated documentation files (the
94
+ 'Software'), to deal in the Software without restriction, including
95
+ without limitation the rights to use, copy, modify, merge, publish,
96
+ distribute, sublicense, and/or sell copies of the Software, and to
97
+ permit persons to whom the Software is furnished to do so, subject to
98
+ the following conditions:
99
+
100
+ The above copyright notice and this permission notice shall be
101
+ included in all copies or substantial portions of the Software.
102
+
103
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
104
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
105
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
106
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
107
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
108
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
109
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/TokBoxer'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('tokboxer', TokBoxer::VERSION) do |p|
7
+ p.developer('Nicolas Jacobeus', 'nj@belighted.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ #p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ p.extra_deps = [
12
+ ['xml-simple','>= 1.0.11'],
13
+ ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
@@ -0,0 +1,2 @@
1
+ host: unknown@rubyforge.org
2
+ remote_dir: /var/www/gforge-projects/TokBoxer
@@ -0,0 +1,28 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'net/http'
6
+ require 'uri'
7
+ require 'digest/md5'
8
+ #require 'rest_client'
9
+ require 'cgi'
10
+ require 'xmlsimple'
11
+ require 'pp' # just for debugging purposes
12
+
13
+ module TokBoxer
14
+ VERSION = '0.1.1'
15
+
16
+ API_SERVER_LOGIN_URL = "view/oauth&"
17
+ API_SERVER_METHODS_URL = "a/v0"
18
+ API_SERVER_CALL_WIDGET = "vc/"
19
+ API_SERVER_RECORDER_WIDGET = "vr/"
20
+ API_SERVER_PLAYER_WIDGET = "vp/"
21
+ API_VERSION = "1.0.0"
22
+ API_SIGNATURE_METHOD = "SIMPLE-MD5"
23
+ end
24
+
25
+ require 'TokBoxer/Api'
26
+ require 'TokBoxer/User'
27
+ require 'TokBoxer/Call'
28
+ require 'TokBoxer/VMail'
@@ -0,0 +1,290 @@
1
+ module TokBoxer
2
+
3
+ class Api
4
+
5
+ attr_reader :api_server_url, :api_key
6
+
7
+ # Call API actions =================================================================================
8
+
9
+ def create_call(callerJabberId, callerName, persistent=false, features="")
10
+ method = "POST"
11
+ call = "/calls/create"
12
+ params = { :callerJabberId => callerJabberId, :callerName => callerName, :persistent => persistent, :features => features }
13
+ result = request(method, call, params)
14
+ end
15
+
16
+ def create_invite(callerJabberId, calleeJabberId, call_id)
17
+ method = "POST"
18
+ call = "/calls/invite"
19
+ params = { :callerJabberId => callerJabberId, :calleeJabberId => calleeJabberId, :call_id => call_id }
20
+ result = request(method, call, params)
21
+ end
22
+
23
+ def join_call(invite_id)
24
+ method = "POST"
25
+ call = "/calls/join"
26
+ params = { :invite_id => invite_id }
27
+ result = request(method, call, params)
28
+ end
29
+
30
+ # Contacts API Actions =============================================================================
31
+
32
+ def add_contact(jabberId, remoteJabberId)
33
+ method = "POST"
34
+ call = "/contacts/request"
35
+ params = { :jabberId => jabberId, :remoteJabberId => remoteJabberId }
36
+ result = request(method, call, params)
37
+ end
38
+
39
+ def is_friend(jabberId, remoteJabberId)
40
+ method = "POST"
41
+ call = "/contacts/getRelation"
42
+ params = { :jabberId => jabberId, :remoteJabberId => remoteJabberId }
43
+ result = request(method, call, params)
44
+ end
45
+
46
+ def remove_contact(jabberId, remoteJabberId)
47
+ method = "POST"
48
+ call = "/contacts/remove"
49
+ params = { :jabberId => jabberId, :remoteJabberId => remoteJabberId }
50
+ result = request(method, call, params)
51
+ end
52
+
53
+ def reject_contact(jabberId, remoteJabberId)
54
+ method = "POST"
55
+ call = "/contacts/reject"
56
+ params = { :jabberId => jabberId, :remoteJabberId => remoteJabberId }
57
+ result = request(method, call, params)
58
+ end
59
+
60
+ # Feed API actions =================================================================================
61
+
62
+ def add_comment(posterjabberId, vmailmessageid, commenttext, vmailcontentid)
63
+ method = "POST"
64
+ call = "/vmail/addcomment"
65
+ params = { :posterjabberId => posterjabberId, :vmailmessageid => vmailmessageid, :commenttext => commenttext, :vmailcontentid => vmailcontentid }
66
+ result = request(method, call, params)
67
+ end
68
+
69
+ def delete_missed_call_from_feed(jabberId, invite_id)
70
+ method = "POST"
71
+ call = "/callevent/delete"
72
+ params = { :jabberId => jabberId, :invite_id => invite_id }
73
+ result = request(method, call, params)
74
+ end
75
+
76
+ def delete_vmail_from_feed(message_id, type)
77
+ method = "POST"
78
+ call = "/vmail/delete"
79
+ params = { :message_id => message_id, :type => type }
80
+ result = request(method, call, params)
81
+ end
82
+
83
+ def get_all_of_the_comments_on_a_post(message_id, start = nil, count = nil)
84
+ method = "POST"
85
+ call = "/vmail/getcomments"
86
+ params = { :message_id => message_id, :start => start, :count => count }
87
+ result = request(method, call, params)
88
+ end
89
+
90
+ def get_feed(jabberId, filter=nil, start=nil, count=nil, sort=nil, dateRange=nil)
91
+ method = "POST"
92
+ call = "/feed/getFeed"
93
+ params = { :jabberId => jabberId, :filter => filter, :start => start, :count => count, :sort => sort, :dateRange => nil }
94
+ result = request(method, call, params)
95
+ end
96
+
97
+ def get_feed_unread_count(jabberId)
98
+ method = "POST"
99
+ call = "/feed/unreadCount"
100
+ params = { :jabberId => jabberId }
101
+ result = request(method, call, params)
102
+ end
103
+
104
+ def mark_missed_call_as_read_in_feed(jabberId, invite_id)
105
+ method = "POST"
106
+ call = "/callevent/markasviewed"
107
+ params = { :jabberId => jabberId, :invite_id => invite_id }
108
+ result = request(method, call, params)
109
+ end
110
+
111
+ def mark_vmail_as_read(message_id)
112
+ method = "POST"
113
+ call = "/vmail/markasviewed"
114
+ params = { :message_id => message_id }
115
+ result = request(method, call, params)
116
+ end
117
+
118
+ # Token API actions ================================================================================
119
+
120
+ def get_access_token(jabberId, password)
121
+ method = "POST"
122
+ call = "/auth/getAccessToken"
123
+ params = { :jabberId => jabberId, :password => password }
124
+ result = request(method, call, params, @api_secret)
125
+ end
126
+
127
+ def get_request_token(callbackUrl)
128
+ method = "POST"
129
+ call = "/auth/getRequestToken"
130
+ params = { :callbackUrl => callbackUrl }
131
+ result = request(method, call, params, @api_secret)
132
+ end
133
+
134
+ def validate_access_token(jabberId, accessSecret)
135
+ method = "POST"
136
+ call = "/auth/validateAccessToken"
137
+ params = { :jabberId => jabberId, :accessSecret => accessSecret }
138
+ result = request(method, call, params, @api_secret)
139
+ end
140
+
141
+ # User API actions =================================================================================
142
+
143
+ def login_user(jabberId, secret)
144
+ @jabberId = jabberId
145
+ @secret = secret
146
+ end
147
+
148
+ def create_user(jabberId, secret)
149
+ TokBoxer::User.new(jabberId, secret, self)
150
+ end
151
+
152
+ def create_guest_user
153
+ method = "POST"
154
+ call = "/users/createGuest"
155
+ params = { :partnerKey => @api_key }
156
+ result = request(method, call, params, @api_secret)
157
+ if result['error']
158
+ return nil # error
159
+ else
160
+ return create_user(result["createGuest"].first["jabberId"].first, result["createGuest"].first["secret"].first)
161
+ end
162
+ end
163
+
164
+ def register_user(firstname,lastname,email)
165
+ method = "POST"
166
+ call = "/users/register"
167
+ params = { :firstname => firstname, :lastname => lastname, :email => email }
168
+ result = request(method, call, params, @api_secret)
169
+ if result['error']
170
+ return nil # error
171
+ else
172
+ return create_user(result["registerUser"].first["jabberId"].first, result["registerUser"].first["secret"].first)
173
+ end
174
+ end
175
+
176
+ def get_user_profile(jabberId)
177
+ @jabberId = jabberId
178
+ method = "POST"
179
+ call = "/users/getProfile"
180
+ params = { :jabberId => jabberId }
181
+ result = request(method, call, params)
182
+ end
183
+
184
+ # VMail API actions ================================================================================
185
+
186
+ def forward_vmail(vmail_id, senderJabberId, text="", tokboxRecipients="", emailRecipients="")
187
+ method = "POST"
188
+ call = "/vmail/forward"
189
+ params = { :vmail_id => vmail_id, :senderJabberId => senderJabberId, :text => text, :tokboxRecipients => tokboxRecipients, :emailRecipients => emailRecipients }
190
+ result = request(method, call, params)
191
+ end
192
+
193
+ def forward_vmail_to_all_friends(vmail_id, senderJabberId, text="")
194
+ method = "POST"
195
+ call = "/vmail/forwardToFriends"
196
+ params = { :vmail_id => vmail_id, :senderJabberId => senderJabberId, :text => text }
197
+ result = request(method, call, params)
198
+ end
199
+
200
+ def get_vmail(message_id)
201
+ method = "POST"
202
+ call = "/vmail/getVmail"
203
+ params = { :message_id => message_id }
204
+ result = request(method, call, params)
205
+ end
206
+
207
+ def post_public_vmail(vmail_id, scope, senderJabberId, text)
208
+ method = "POST"
209
+ call = "/vmail/postPublic"
210
+ params = { :vmail_id => vmail_id, :scope => scope, :senderJabberId => senderJabberId, :text => text }
211
+ result = request(method, call, params)
212
+ end
213
+
214
+ def send_vmail(vmail_id, senderJabberId, text="", tokboxRecipients="", emailRecipients="")
215
+ method = "POST"
216
+ call = "/vmail/send"
217
+ params = { :vmail_id => vmail_id, :senderJabberId => senderJabberId, :text => text, :tokboxRecipients => tokboxRecipients, :emailRecipients => emailRecipients }
218
+ result = request(method, call, params)
219
+ end
220
+
221
+ def send_vmail_to_alL_friends(vmail_id, senderJabberId, text="")
222
+ method = "POST"
223
+ call = "/vmail/sendToFriends"
224
+ params = { :vmail_id => vmail_id, :senderJabberId => senderJabberId, :text => text }
225
+ result = request(method, call, params)
226
+ end
227
+
228
+ private # ==========================================================================================
229
+
230
+ def initialize(api_key, api_secret, api_server_url = 'http://sandbox.tokbox.com/')
231
+ @api_key = api_key
232
+ @api_secret = api_secret
233
+ @api_server_url = api_server_url
234
+ end
235
+
236
+ def generate_nonce
237
+ (0...16).map { "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[rand(62)] }.join
238
+ end
239
+
240
+ def generate_request_string(hash)
241
+ hash.reject{ |k,v| k=~/^_/ or v.nil? or v.to_s == "" }.
242
+ map{|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}".gsub("+","%20")}.sort.join("&")
243
+ end
244
+
245
+ def build_signed_request(method, uri, nonce, timestamp, paramList, secret)
246
+ signed_auth_fields = { 'oauth_partner_key' => @api_key,
247
+ 'oauth_signature_method' => API_SIGNATURE_METHOD,
248
+ 'oauth_timestamp' => timestamp,
249
+ 'oauth_version' => API_VERSION,
250
+ 'oauth_nonce' => nonce,
251
+ 'tokbox_jabberid' => @jabberId }.merge(paramList)
252
+ request_string = method + "&" + uri + "&" + generate_request_string(signed_auth_fields)
253
+ Digest::MD5.hexdigest(request_string + secret)
254
+ end
255
+
256
+ def request(method, apiURL, paramList, secret = nil)
257
+ nonce = generate_nonce
258
+ timestamp = Time.now.to_i
259
+ request_url = @api_server_url + API_SERVER_METHODS_URL + apiURL
260
+ authfields = { 'oauth_partner_key' => @api_key,
261
+ 'oauth_signature_method' => API_SIGNATURE_METHOD,
262
+ 'oauth_timestamp' => timestamp,
263
+ 'oauth_version' => API_VERSION,
264
+ 'oauth_nonce' => nonce,
265
+ 'oauth_signature' => build_signed_request(method,request_url,nonce,timestamp,paramList, secret || @secret),
266
+ 'tokbox_jabberid' => @jabberId }
267
+ datastring = generate_request_string(paramList)+"&"+generate_request_string(authfields)
268
+ datastring += '&_AUTHORIZATION='
269
+ datastring += authfields.map{|k,v|"#{CGI.escape(k.to_s)}=\"#{CGI.escape(v.to_s)}\""}.join(",").gsub("+","%20")
270
+ if @debug
271
+ puts "=========================v"
272
+ puts "Call : #{method} #{request_url}"
273
+ puts "Params : #{paramList.inspect}"
274
+ puts "-------------------------"
275
+ end
276
+ url = URI.parse(request_url)
277
+ request = Net::HTTP.new(url.host,url.port)
278
+ response = request.post(url.path,datastring)
279
+ result = response.body
280
+ xml_result = XmlSimple.xml_in(result)
281
+ if @debug
282
+ pp xml_result
283
+ puts "=========================^"
284
+ end
285
+ xml_result
286
+ end
287
+
288
+ end
289
+
290
+ end