opentok 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +11 -1
- data/LICENSE +7 -0
- data/README.md +57 -51
- data/Rakefile +5 -0
- data/lib/open_tok/archive.rb +13 -34
- data/lib/open_tok/open_tok_sdk.rb +36 -62
- data/lib/open_tok/request.rb +57 -0
- data/lib/open_tok/utils.rb +19 -0
- data/lib/open_tok/version.rb +1 -1
- data/lib/opentok.rb +6 -12
- data/opentok.gemspec +8 -3
- data/spec/cassettes/archives.yml +83 -0
- data/spec/cassettes/invalidSession.yml +41 -0
- data/spec/cassettes/session.yml +46 -0
- data/spec/cassettes/stitchArchive.yml +42 -0
- data/spec/opentok_spec.rb +85 -126
- data/spec/spec_helper.rb +14 -1
- metadata +86 -11
- data/LICENCE +0 -19
- data/lib/monkey_patches.rb +0 -34
data/CHANGES
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= Change Log
|
2
2
|
|
3
|
+
== Version 0.0.8
|
4
|
+
|
5
|
+
* Removed references to the staging environment as it no longer exists
|
6
|
+
|
7
|
+
== Version 0.0.73
|
8
|
+
|
9
|
+
* Added stitchArchive functionality
|
10
|
+
* Updated Test Cases ( thanks to https://github.com/rlivsey )
|
11
|
+
* Download Archive duplication and error catching ( thanks to https://github.com/muescha )
|
12
|
+
|
3
13
|
== Version 0.0.5
|
4
14
|
|
5
15
|
* Added connection_data to generate token method (thanks to https://github.com/jonmumm)
|
@@ -20,4 +30,4 @@
|
|
20
30
|
|
21
31
|
== Version 0.0.1
|
22
32
|
|
23
|
-
Initial version
|
33
|
+
Initial version
|
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 TokBox, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
The software complies with Terms of Service for the OpenTok platform described in http://www.tokbox.com/termsofservice
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Opentok
|
2
2
|
|
3
|
-
OpenTok is
|
4
|
-
|
5
|
-
This is the official Opentok rubygem.
|
3
|
+
OpenTok is an API from TokBox that enables websites to weave live group video communication into their online experience. Check out <http://www.tokbox.com/> for more information.
|
4
|
+
This is the official OpenTok Ruby Server SDK for generating Sessions, Tokens, and retriving Archives. Please visit our [getting started page](http://www.tokbox.com/opentok/tools/js/gettingstarted) if you are unfamiliar with these concepts.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -13,96 +12,103 @@ gem 'opentok'
|
|
13
12
|
|
14
13
|
To install as a regular gem just type `gem install opentok`
|
15
14
|
|
16
|
-
##
|
17
|
-
|
18
|
-
### API-key and secret
|
15
|
+
## Requirements
|
19
16
|
|
20
|
-
|
17
|
+
You need an api-key and secret. Request them at <http://www.tokbox.com/opentok/tools/js/apikey>.
|
21
18
|
|
22
|
-
|
19
|
+
# OpenTokSDK
|
23
20
|
|
24
21
|
In order to use any of the server side functions, you must first create an `OpenTokSDK` object with your developer credentials.
|
25
|
-
|
26
|
-
|
22
|
+
`OpenTokSDK` takes 2-3 parameters:
|
23
|
+
> key (string) - Given to you when you register
|
24
|
+
> secret (string) - Given to you when you register
|
27
25
|
|
28
|
-
Example: ( Staging )
|
29
26
|
<pre>
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
# Creating an OpenTok Object
|
28
|
+
API_KEY = '' # should be a string
|
29
|
+
API_SECRET = '' # should be a string
|
30
|
+
OTSDK = OpenTok::OpenTokSDK.new API_KEY, API_SECRET
|
33
31
|
</pre>
|
34
32
|
|
35
|
-
Example: ( Production )
|
36
|
-
<pre>
|
37
|
-
@opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret, :api_url => 'https://api.opentok.com/hl'
|
38
|
-
</pre>
|
39
33
|
|
40
|
-
|
34
|
+
# Creating Sessions
|
41
35
|
Use your `OpenTokSDK` object to create `session_id`
|
42
|
-
`
|
36
|
+
`createSession` takes 1-2 parameters:
|
43
37
|
> location (string) - give Opentok a hint on where you are running your application
|
44
|
-
> properties (object) - OPTIONAL. Set peer to peer as `enabled` or `disabled
|
38
|
+
> properties (object) - OPTIONAL. Set peer to peer as `enabled` or `disabled`. Disabled by default
|
45
39
|
|
46
|
-
Example: P2P disabled by default
|
47
40
|
<pre>
|
48
|
-
|
49
|
-
session_id =
|
50
|
-
</pre>
|
41
|
+
# Creating Session object, passing request IP address to determine closest production server
|
42
|
+
session_id = OTSDK.createSession( request.ip )
|
51
43
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
session_id = @opentok.create_session( @location, session_properties )
|
44
|
+
# Creating Session object with p2p enabled
|
45
|
+
sessionProperties = {OpenTok::SessionPropertyConstants::P2P_PREFERENCE => "enabled"} # or disabled
|
46
|
+
sessionId = OTSDK.createSession( @location, sessionProperties )
|
56
47
|
</pre>
|
57
48
|
|
58
|
-
|
59
|
-
With the generated
|
49
|
+
# Generating Token
|
50
|
+
With the generated sessionId, you can start generating tokens for each user.
|
60
51
|
`generate_token` takes in hash with 1-4 properties:
|
61
52
|
> session_id (string) - REQUIRED
|
62
53
|
> role (string) - OPTIONAL. subscriber, publisher, or moderator
|
63
54
|
> expire_time (int) - OPTIONAL. Time when token will expire in unix timestamp
|
64
55
|
> connection_data (string) - OPTIONAL. Metadata to store data (names, user id, etc)
|
65
56
|
|
66
|
-
Example:
|
67
57
|
<pre>
|
68
|
-
|
58
|
+
# Generating a token
|
59
|
+
token = OTSDK.generateToken :session_id => session, :role => OpenTok::RoleConstants::PUBLISHER, :connection_data => "username=Bob,level=4"
|
69
60
|
</pre>
|
70
61
|
|
71
|
-
|
72
|
-
To Download archived video, you must have an Archive ID which you get from the javascript library
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
62
|
+
# Downloading Archive Videos
|
63
|
+
To Download archived video, you must have an Archive ID which you get from the javascript library. If you are unfamiliar with archiving concepts, please visit our [archiving tutorial](http://www.tokbox.com/opentok/api/documentation/gettingstartedarchiving)
|
64
|
+
|
65
|
+
# Stitching Archives
|
66
|
+
OpenTok SDK allows you to stich up to 4 videos together in an archive.
|
67
|
+
Use your `OpenTokSDK` object to call stitchArchive
|
68
|
+
stitchArchive takes in 1 parameter and returns a hash object with code, message, and location if stitch is successful.
|
69
|
+
> archive_id (string) - REQUIRED
|
70
|
+
> **returns**:
|
71
|
+
{:code=>201, :message=>"Successfully Created", :location=>response["location"]}
|
72
|
+
{:code=>202, :message=>"Processing"}
|
73
|
+
{:code=>403, :message=>"Invalid Credentials"}
|
74
|
+
{:code=>404, :message=>"Archive Does Not Exist"}
|
75
|
+
{:code=>500, :message=>"Server Error"}
|
76
|
+
|
77
|
+
Example:
|
78
|
+
<pre>
|
79
|
+
result = OTSDK.stitchArchive archive_id
|
80
|
+
if result[:code] == 201
|
81
|
+
return result[:location]
|
82
|
+
end
|
83
|
+
</pre>
|
80
84
|
|
81
|
-
|
85
|
+
# Get Archive Manifest
|
82
86
|
With your **moderator token** and OpentokSDK Object, you can generate OpenTokArchive Object, which contains information for all videos in the Archive
|
83
|
-
`
|
87
|
+
`getArchiveManifest()` takes in 2 parameters: **archiveId** and **moderator token**
|
84
88
|
> archive_id (string) - REQUIRED.
|
85
|
-
>
|
89
|
+
> token (string) - REQUIRED.
|
90
|
+
> **returns** an `OpenTokArchive` object.
|
91
|
+
The *resources* property of this object is array of `OpenTokArchiveVideoResource` objects, and each `OpenTokArchiveVideoResource` object represents a video in the archive.
|
86
92
|
|
87
93
|
Example:(Make sure you have the OpentokSDK Object)
|
88
94
|
<pre>
|
89
|
-
@token = '
|
95
|
+
@token = '...' # token generated with corresponding session
|
90
96
|
@archiveId = '5f74aee5-ab3f-421b-b124-ed2a698ee939' #Obtained from Javascript Library
|
91
|
-
otArchive =
|
97
|
+
otArchive = OTSDK.getArchiveManifest(@archiveId, @token)
|
92
98
|
</pre>
|
93
99
|
|
94
|
-
|
95
|
-
`OpenTokArchive.resources` is an array of `OpenTokArchiveVideoResource` objects. OpenTokArchiveVideoResource has `getId()` method that returns the
|
100
|
+
# Get video ID
|
101
|
+
`OpenTokArchive.resources` is an array of `OpenTokArchiveVideoResource` objects. OpenTokArchiveVideoResource has `getId()` method that returns the video_id
|
96
102
|
`getId()` will return the video ID (a String)
|
97
103
|
|
98
104
|
Example:
|
99
105
|
<pre>
|
100
|
-
otArchive =
|
106
|
+
otArchive = OTSDK.getArchiveManifest(@archiveId, @token)
|
101
107
|
otVideoResource = otArchive.resources[0]
|
102
108
|
videoId = otVideoResource.getId()
|
103
109
|
</pre>
|
104
110
|
|
105
|
-
|
111
|
+
# Get Download Url
|
106
112
|
`OpenTokArchive` has `downloadArchiveURL` that will return an url string for downloading the video in the archive. You must call this function every time you want the file, because this url expires after 24 hours
|
107
113
|
> video_id (string) - REQUIRED
|
108
114
|
> token (string) - REQUIRED
|
data/Rakefile
CHANGED
data/lib/open_tok/archive.rb
CHANGED
@@ -9,53 +9,32 @@ module OpenTok
|
|
9
9
|
class Archive
|
10
10
|
attr_accessor :archive_id, :archive_title, :resources, :timeline
|
11
11
|
|
12
|
-
def initialize(archive_id, archive_title, resources, timeline,
|
12
|
+
def initialize(archive_id, archive_title, resources, timeline, api_url, token)
|
13
13
|
@archive_id = archive_id
|
14
14
|
@archive_title = archive_title
|
15
15
|
@resources = resources
|
16
16
|
@timeline = timeline
|
17
|
-
@
|
17
|
+
@api_url = api_url
|
18
18
|
@token = token
|
19
19
|
end
|
20
20
|
|
21
|
-
def do_request(
|
22
|
-
|
23
|
-
req = Net::HTTP::Get.new(url.path)
|
24
|
-
|
25
|
-
req.add_field 'X-TB-TOKEN-AUTH', token
|
26
|
-
|
27
|
-
http = Net::HTTP.new(url.host, url.port)
|
28
|
-
http.use_ssl = true if @apiUrl.start_with?("https")
|
29
|
-
res = http.start {|http| http.request(req)}
|
30
|
-
case res
|
31
|
-
when Net::HTTPSuccess, Net::HTTPRedirection
|
32
|
-
return res.read_body
|
33
|
-
else
|
34
|
-
res.error!
|
35
|
-
end
|
36
|
-
rescue Net::HTTPExceptions
|
37
|
-
raise
|
38
|
-
raise OpenTokException.new 'Unable to create fufill request: ' + $!
|
39
|
-
rescue NoMethodError
|
40
|
-
raise
|
41
|
-
raise OpenTokException.new 'Unable to create a fufill request at this time: ' + $1
|
42
|
-
end
|
43
|
-
|
44
|
-
def download_archive_url(video_id)
|
45
|
-
doc = do_request "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}"
|
46
|
-
if not doc.get_elements('Errors').empty?
|
47
|
-
raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s
|
48
|
-
end
|
49
|
-
doc
|
21
|
+
def do_request(path, token)
|
22
|
+
OpenTok::Request.new(@api_url, token).fetch(path)
|
50
23
|
end
|
51
24
|
|
52
|
-
def
|
25
|
+
def download_archive_url(video_id, token="")
|
53
26
|
if token==""
|
54
|
-
|
27
|
+
# this token check supports previous implementation of download_archive_url
|
28
|
+
return "#{@api_url}/archive/url/#{@archive_id}/#{video_id}"
|
55
29
|
else
|
56
|
-
|
30
|
+
doc = do_request "/archive/url/#{@archive_id}/#{video_id}", token
|
31
|
+
if doc.split("http").length < 2
|
32
|
+
raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s
|
33
|
+
end
|
34
|
+
return doc
|
57
35
|
end
|
58
36
|
end
|
37
|
+
alias_method :downloadArchiveURL, :download_archive_url
|
59
38
|
|
60
39
|
def self.parse_manifest(manifest, apiUrl, token)
|
61
40
|
archive_id = manifest.attributes['archiveid']
|
@@ -6,11 +6,8 @@
|
|
6
6
|
|
7
7
|
=end
|
8
8
|
|
9
|
-
require 'cgi'
|
10
9
|
require 'openssl'
|
11
10
|
require 'base64'
|
12
|
-
require 'uri'
|
13
|
-
require 'net/https'
|
14
11
|
require 'rexml/document'
|
15
12
|
|
16
13
|
DIGEST = OpenSSL::Digest::Digest.new('sha1')
|
@@ -24,7 +21,7 @@ module OpenTok
|
|
24
21
|
# * +MULTIPLEXER_SWITCHTYPE+ integer
|
25
22
|
# * +MULTIPLEXER_SWITCHTIMEOUT+ integer
|
26
23
|
# * +P2P_PREFERENCE+ string
|
27
|
-
|
24
|
+
module SessionPropertyConstants
|
28
25
|
ECHOSUPPRESSION_ENABLED = "echoSuppression.enabled" #Boolean
|
29
26
|
MULTIPLEXER_NUMOUTPUTSTREAMS = "multiplexer.numOutputStreams" #Integer
|
30
27
|
MULTIPLEXER_SWITCHTYPE = "multiplexer.switchType" #Integer
|
@@ -37,7 +34,7 @@ module OpenTok
|
|
37
34
|
# * +SUBSCRIBER+ Can only subscribe
|
38
35
|
# * +PUBLISHER+ Can publish, subscribe, and signal
|
39
36
|
# * +MODERATOR+ Can do the above along with forceDisconnect and forceUnpublish
|
40
|
-
|
37
|
+
module RoleConstants
|
41
38
|
SUBSCRIBER = "subscriber" #Can only subscribe
|
42
39
|
PUBLISHER = "publisher" #Can publish, subscribe, and signal
|
43
40
|
MODERATOR = "moderator" #Can do the above along with forceDisconnect and forceUnpublish
|
@@ -52,25 +49,15 @@ module OpenTok
|
|
52
49
|
#
|
53
50
|
# The first two attributes are required; +parnter_id+ and +partner_secret+ are the api-key and secret
|
54
51
|
# that are provided to you.
|
55
|
-
|
56
|
-
# You can also pass in optional options;
|
57
|
-
# * +:api_url+ sets the location of the api (staging or production)
|
58
|
-
def initialize(partner_id, partner_secret, options = nil)
|
52
|
+
def initialize(partner_id, partner_secret, backSupport="")
|
59
53
|
@partner_id = partner_id
|
60
54
|
@partner_secret = partner_secret.strip
|
61
|
-
|
62
|
-
if options.is_a?(::Hash)
|
63
|
-
@api_url = options[:api_url] || API_URL
|
64
|
-
end
|
65
|
-
|
66
|
-
unless @api_url
|
67
|
-
@api_url = API_URL
|
68
|
-
end
|
55
|
+
@api_url = API_URL
|
69
56
|
end
|
70
57
|
|
71
58
|
# Generate token for the given session_id. The options you can provide are;
|
72
59
|
# * +:session_id+ (required) generate a token for the provided session
|
73
|
-
# * +:create_time+
|
60
|
+
# * +:create_time+
|
74
61
|
# * +:expire_time+ (optional) The time when the token will expire, defined as an integer value for a Unix timestamp (in seconds). If you do not specify this value, tokens expire in 24 hours after being created.
|
75
62
|
# * +:role+ (optional) Added in OpenTok v0.91.5. This defines the role the user will have. There are three roles: subscriber, publisher, and moderator.
|
76
63
|
# * +:connection_data+ (optional) Added in OpenTok v0.91.20. A string containing metadata describing the connection.
|
@@ -97,7 +84,7 @@ module OpenTok
|
|
97
84
|
if not opts[:expire_time].nil?
|
98
85
|
raise OpenTokException.new 'Expire time must be a number' if not opts[:expire_time].is_a?(Numeric)
|
99
86
|
raise OpenTokException.new 'Expire time must be in the future' if opts[:expire_time] < Time.now.to_i
|
100
|
-
raise OpenTokException.new 'Expire time must be in the next
|
87
|
+
raise OpenTokException.new 'Expire time must be in the next 30 days' if opts[:expire_time] > (Time.now.to_i + 2592000)
|
101
88
|
data_params[:expire_time] = opts[:expire_time].to_i
|
102
89
|
end
|
103
90
|
|
@@ -106,16 +93,14 @@ module OpenTok
|
|
106
93
|
data_params[:connection_data] = opts[:connection_data]
|
107
94
|
end
|
108
95
|
|
109
|
-
data_string = data_params
|
96
|
+
data_string = OpenTok::Utils.urlencode_hash(data_params)
|
110
97
|
|
111
98
|
sig = sign_string(data_string, @partner_secret)
|
112
|
-
meta_string =
|
113
|
-
:partner_id => @partner_id,
|
114
|
-
:sig => sig
|
115
|
-
}.urlencode
|
99
|
+
meta_string = OpenTok::Utils.urlencode_hash(:partner_id => @partner_id, :sig => sig)
|
116
100
|
|
117
101
|
@@TOKEN_SENTINEL + Base64.encode64(meta_string + ":" + data_string).gsub("\n", '')
|
118
102
|
end
|
103
|
+
alias_method :generateToken, :generate_token
|
119
104
|
|
120
105
|
# Generates a new OpenTok::Session and set it's session_id, situating it in TokBox's global network near the IP of the specified @location@.
|
121
106
|
#
|
@@ -128,16 +113,12 @@ module OpenTok
|
|
128
113
|
end
|
129
114
|
OpenTok::Session.new(doc.root.get_elements('Session')[0].get_elements('session_id')[0].children[0].to_s)
|
130
115
|
end
|
116
|
+
alias_method :createSession, :create_session
|
131
117
|
|
132
118
|
# This method takes two parameters. The first parameter is the +archive_id+ of the archive that contains the video (a String). The second parameter is the +token+ (a String)
|
133
119
|
# The method returns an +OpenTok::Archive+ object. The resources property of this object is an array of OpenTok::ArchiveVideoResource objects. Each OpenTok::ArchiveVideoResource object represents a video in the archive.
|
134
120
|
def get_archive_manifest(archive_id, token)
|
135
|
-
# verify that token is MODERATOR token
|
136
|
-
decoder = token[4..token.length]
|
137
|
-
tokenInfo = Base64.decode64(decoder)
|
138
|
-
if not (tokenInfo.split('role=')[1].split('&')[0]==OpenTok::RoleConstants::MODERATOR)
|
139
|
-
raise OpenTokException.new("Token must be assigned role of MODERATROR")
|
140
|
-
end
|
121
|
+
# TODO: verify that token is MODERATOR token
|
141
122
|
|
142
123
|
doc = do_request("/archive/getmanifest/#{archive_id}", {}, token)
|
143
124
|
if not doc.get_elements('Errors').empty?
|
@@ -145,44 +126,37 @@ module OpenTok
|
|
145
126
|
end
|
146
127
|
OpenTok::Archive.parse_manifest(doc.get_elements('manifest')[0], @api_url, token)
|
147
128
|
end
|
129
|
+
alias_method :getArchiveManifest, :get_archive_manifest
|
130
|
+
|
131
|
+
def stitchArchive(aid)
|
132
|
+
stitchURL = "/hl/archive/#{aid}/stitch"
|
133
|
+
request = OpenTok::Request.new(@api_url, nil, @partner_id, @partner_secret)
|
134
|
+
response = request.sendRequest(stitchURL, {test:'none'})
|
135
|
+
case response.code
|
136
|
+
when '201'
|
137
|
+
return {:code=>201, :message=>"Successfully Created", :location=>response["location"]}
|
138
|
+
when '202'
|
139
|
+
return {:code=>202, :message=>"Processing"}
|
140
|
+
when '403'
|
141
|
+
return {:code=>403, :message=>"Invalid Credentials"}
|
142
|
+
when '404'
|
143
|
+
return {:code=>404, :message=>"Archive Does Not Exist"}
|
144
|
+
else
|
145
|
+
return {:code=>500, :message=>"Server Error"}
|
146
|
+
end
|
147
|
+
return {}
|
148
|
+
end
|
149
|
+
alias_method :stitch, :stitchArchive
|
148
150
|
|
149
151
|
protected
|
150
152
|
def sign_string(data, secret)
|
151
153
|
OpenSSL::HMAC.hexdigest(DIGEST, secret, data)
|
152
154
|
end
|
153
155
|
|
154
|
-
def do_request(
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
req.set_form_data(params)
|
159
|
-
else
|
160
|
-
req = Net::HTTP::Get.new(url.path)
|
161
|
-
end
|
162
|
-
|
163
|
-
if not token.nil?
|
164
|
-
req.add_field 'X-TB-TOKEN-AUTH', token
|
165
|
-
else
|
166
|
-
req.add_field 'X-TB-PARTNER-AUTH', "#{@partner_id}:#{@partner_secret}"
|
167
|
-
end
|
168
|
-
http = Net::HTTP.new(url.host, url.port)
|
169
|
-
http.use_ssl = true if @api_url.start_with?("https")
|
170
|
-
res = http.start {|http| http.request(req)}
|
171
|
-
case res
|
172
|
-
when Net::HTTPSuccess, Net::HTTPRedirection
|
173
|
-
# OK
|
174
|
-
doc = REXML::Document.new(res.read_body)
|
175
|
-
return doc
|
176
|
-
else
|
177
|
-
res.error!
|
178
|
-
end
|
179
|
-
rescue Net::HTTPExceptions
|
180
|
-
raise
|
181
|
-
raise OpenTokException.new 'Unable to create fufill request: ' + $!
|
182
|
-
rescue NoMethodError
|
183
|
-
raise
|
184
|
-
raise OpenTokException.new 'Unable to create a fufill request at this time: ' + $1
|
156
|
+
def do_request(path, params, token=nil)
|
157
|
+
request = OpenTok::Request.new(@api_url, token, @partner_id, @partner_secret)
|
158
|
+
body = request.fetch(path, params)
|
159
|
+
REXML::Document.new(body)
|
185
160
|
end
|
186
161
|
end
|
187
162
|
end
|
188
|
-
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
Net::HTTP.version_1_2 # to make sure version 1.2 is used
|
6
|
+
|
7
|
+
module OpenTok
|
8
|
+
class Request
|
9
|
+
|
10
|
+
def initialize(api_host, token, partner_id=nil, partner_secret=nil)
|
11
|
+
@api_host = api_host
|
12
|
+
@token = token
|
13
|
+
@partner_id = partner_id
|
14
|
+
@partner_secret = partner_secret
|
15
|
+
end
|
16
|
+
|
17
|
+
def sendRequest(path, params)
|
18
|
+
url = URI.parse(@api_host + path)
|
19
|
+
|
20
|
+
if params.empty?
|
21
|
+
req = Net::HTTP::Get.new(url.path)
|
22
|
+
else
|
23
|
+
req = Net::HTTP::Post.new(url.path)
|
24
|
+
req.set_form_data(params)
|
25
|
+
end
|
26
|
+
|
27
|
+
if @token
|
28
|
+
req.add_field 'X-TB-TOKEN-AUTH', @token
|
29
|
+
elsif @partner_id && @partner_secret
|
30
|
+
req.add_field 'X-TB-PARTNER-AUTH', "#{@partner_id}:#{@partner_secret}"
|
31
|
+
end
|
32
|
+
|
33
|
+
http = Net::HTTP.new(url.host, url.port)
|
34
|
+
http.use_ssl = @api_host.start_with?("https")
|
35
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
36
|
+
|
37
|
+
res = http.start {|h| h.request(req) }
|
38
|
+
return res
|
39
|
+
end
|
40
|
+
|
41
|
+
def fetch(path, params={})
|
42
|
+
res = sendRequest(path, params)
|
43
|
+
|
44
|
+
case res
|
45
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
46
|
+
return res.read_body
|
47
|
+
else
|
48
|
+
res.error!
|
49
|
+
end
|
50
|
+
|
51
|
+
rescue Net::HTTPExceptions => e
|
52
|
+
raise OpenTokException.new "Unable to create fufill request: #{e}"
|
53
|
+
rescue NoMethodError => e
|
54
|
+
raise OpenTokException.new "Unable to create a fufill request at this time: #{e}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module OpenTok
|
4
|
+
module Utils
|
5
|
+
# would recommend using `addressable` gem instead
|
6
|
+
def self.urlencode_hash(hash)
|
7
|
+
hash.to_a.map do |name_value|
|
8
|
+
if name_value[1].is_a? Array
|
9
|
+
name_value[0] = CGI.escape name_value[0].to_s
|
10
|
+
name_value[1].map { |e| CGI.escape e.to_s }
|
11
|
+
name_value[1] = name_value[1].join "&" + name_value[0] + "="
|
12
|
+
name_value.join '='
|
13
|
+
else
|
14
|
+
name_value.map { |e| CGI.escape e.to_s }.join '='
|
15
|
+
end
|
16
|
+
end.join '&'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/open_tok/version.rb
CHANGED
data/lib/opentok.rb
CHANGED
@@ -2,26 +2,20 @@
|
|
2
2
|
OpenTok Ruby Library
|
3
3
|
http://www.tokbox.com/
|
4
4
|
|
5
|
-
Copyright 2010 -
|
5
|
+
Copyright 2010 - 2012, TokBox, Inc.
|
6
6
|
|
7
|
-
Last modified:
|
7
|
+
Last modified: 2012-08-28
|
8
8
|
=end
|
9
9
|
|
10
10
|
module OpenTok
|
11
11
|
require 'rubygems'
|
12
|
-
require 'net/http'
|
13
|
-
require 'uri'
|
14
|
-
require 'digest/md5'
|
15
|
-
require 'cgi'
|
16
|
-
#require 'pp' # just for debugging purposes
|
17
12
|
|
18
|
-
|
13
|
+
VERSION = "tbrb-v0.91.2012-08-28"
|
14
|
+
API_URL = "https://api.opentok.com"
|
19
15
|
|
20
|
-
VERSION = "tbrb-v0.91.2011-02-17"
|
21
|
-
API_URL = "https://staging.tokbox.com/hl"
|
22
|
-
|
23
|
-
require 'monkey_patches'
|
24
16
|
require 'open_tok/exception'
|
17
|
+
require 'open_tok/utils'
|
18
|
+
require 'open_tok/request'
|
25
19
|
require 'open_tok/open_tok_sdk'
|
26
20
|
require 'open_tok/session'
|
27
21
|
require 'open_tok/archive'
|
data/opentok.gemspec
CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "opentok"
|
7
7
|
s.version = Opentok::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Stijn Mathysen", "Karmen Blake"]
|
10
|
-
s.email = ["stijn@skylight.be", "karmenblake@gmail.com"]
|
9
|
+
s.authors = ["Stijn Mathysen", "Karmen Blake", "Song Zheng"]
|
10
|
+
s.email = ["stijn@skylight.be", "karmenblake@gmail.com", "song@tokbox.com"]
|
11
11
|
s.homepage = "https://github.com/opentok/Opentok-Ruby-SDK"
|
12
12
|
s.summary = %q{OpenTok gem}
|
13
|
-
s.description = %q{OpenTok is
|
13
|
+
s.description = %q{OpenTok is an API from TokBox that enables websites to weave live group video communication into their online experience. With OpenTok you have the freedom and flexibility to create the most engaging web experience for your users. OpenTok is currently available as a JavaScript and ActionScript 3.0 library. This gem allows you to connect to the API from within Ruby (and Rails)}
|
14
14
|
|
15
15
|
s.rubyforge_project = "opentok"
|
16
16
|
|
@@ -18,4 +18,9 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rake"
|
23
|
+
s.add_development_dependency "rspec"
|
24
|
+
s.add_development_dependency "webmock"
|
25
|
+
s.add_development_dependency "vcr"
|
21
26
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://api.opentok.com/archive/getmanifest/200567af-0726-4e93-883b-fe0426d6310a
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*'
|
12
|
+
User-Agent:
|
13
|
+
- Ruby
|
14
|
+
X-Tb-Token-Auth:
|
15
|
+
- T1==cGFydG5lcl9pZD00NTk3ODImc2lnPWVjNjA1YTZhNzI5MDk5MzU5NTI1YWM2ZTczNDY1ZTQ3MzEwMWFkY2Q6cm9sZT1tb2RlcmF0b3Imc2Vzc2lvbl9pZD0xX01YNDBOVGszT0RKLU1USTNMakF1TUM0eGZsUjFaU0JUWlhBZ01EUWdNVFE2TlRNNk1ESWdVRVJVSURJd01USi1NQzQxTWpFeE9ERXpmZyZjcmVhdGVfdGltZT0xMzQ2ODAxMjQ1Jm5vbmNlPTAuMjUwMTIwMTEyNzkzODkwMjQ=
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Server:
|
22
|
+
- nginx
|
23
|
+
Date:
|
24
|
+
- Tue, 04 Sep 2012 23:27:13 GMT
|
25
|
+
Content-Type:
|
26
|
+
- text/xml; charset=utf-8
|
27
|
+
Connection:
|
28
|
+
- keep-alive
|
29
|
+
Pragma:
|
30
|
+
- no-cache
|
31
|
+
Cache-Control:
|
32
|
+
- no-cache
|
33
|
+
Content-Length:
|
34
|
+
- '510'
|
35
|
+
body:
|
36
|
+
encoding: US-ASCII
|
37
|
+
string: ! "<manifest version=\"0.1\" archiveid=\"200567af-0726-4e93-883b-fe0426d6310a\"
|
38
|
+
title=\"1346797109799\">\n <resources>\n <video id=\"bbf108c9-7237-49ae-9057-2ccdb71cf675\"
|
39
|
+
length=\"18734\" name=\"\"/>\n <video id=\"3f0d3ec6-4a41-4cc5-9e38-f9e6375ba5fd\"
|
40
|
+
length=\"18743\" name=\"\"/>\n </resources>\n <timeline>\n <event
|
41
|
+
type=\"PLAY\" id=\"3f0d3ec6-4a41-4cc5-9e38-f9e6375ba5fd\" offset=\"1255\"
|
42
|
+
data=\"\" />\n <event type=\"PLAY\" id=\"bbf108c9-7237-49ae-9057-2ccdb71cf675\"
|
43
|
+
offset=\"1263\" data=\"\" />\n </timeline>\n</manifest>\n\n\n"
|
44
|
+
http_version:
|
45
|
+
recorded_at: Tue, 04 Sep 2012 23:27:25 GMT
|
46
|
+
- request:
|
47
|
+
method: get
|
48
|
+
uri: https://api.opentok.com/archive/url/200567af-0726-4e93-883b-fe0426d6310a/bbf108c9-7237-49ae-9057-2ccdb71cf675
|
49
|
+
body:
|
50
|
+
encoding: US-ASCII
|
51
|
+
string: ''
|
52
|
+
headers:
|
53
|
+
Accept:
|
54
|
+
- ! '*/*'
|
55
|
+
User-Agent:
|
56
|
+
- Ruby
|
57
|
+
X-Tb-Token-Auth:
|
58
|
+
- T1==cGFydG5lcl9pZD00NTk3ODImc2lnPTU2MDY5Y2VmMTAzY2M4YTUzY2RlNTZlZTAzNzdjODIyNTk0MTU5MzM6cm9sZT1tb2RlcmF0b3Imc2Vzc2lvbl9pZD0xX01YNDBOVGszT0RKLU1USTNMakF1TUM0eGZsUjFaU0JUWlhBZ01EUWdNVFE2TlRNNk1ESWdVRVJVSURJd01USi1NQzQxTWpFeE9ERXpmZyZjcmVhdGVfdGltZT0xMzQ2ODAxMjQ1Jm5vbmNlPTAuNDY2MDM2NDg4Nzc5NDgy
|
59
|
+
response:
|
60
|
+
status:
|
61
|
+
code: 200
|
62
|
+
message: OK
|
63
|
+
headers:
|
64
|
+
Server:
|
65
|
+
- nginx
|
66
|
+
Date:
|
67
|
+
- Tue, 04 Sep 2012 23:27:13 GMT
|
68
|
+
Content-Type:
|
69
|
+
- text/html; charset=utf-8
|
70
|
+
Connection:
|
71
|
+
- keep-alive
|
72
|
+
Pragma:
|
73
|
+
- no-cache
|
74
|
+
Cache-Control:
|
75
|
+
- no-cache
|
76
|
+
Content-Length:
|
77
|
+
- '229'
|
78
|
+
body:
|
79
|
+
encoding: US-ASCII
|
80
|
+
string: https://s3.amazonaws.com/tokbox.com.production/459782/200567af-0726-4e93-883b-fe0426d6310a/bbf108c9-7237-49ae-9057-2ccdb71cf675.flv?Signature=Hn7ti7U2yG8tehW1ypD1R%2FGUvrg%3D&Expires=1346804833&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q
|
81
|
+
http_version:
|
82
|
+
recorded_at: Tue, 04 Sep 2012 23:27:25 GMT
|
83
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.opentok.com/session/create
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: partner_id=0&location=localhost
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*'
|
12
|
+
User-Agent:
|
13
|
+
- Ruby
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
X-Tb-Partner-Auth:
|
17
|
+
- ! '0:'
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Server:
|
24
|
+
- nginx
|
25
|
+
Date:
|
26
|
+
- Tue, 04 Sep 2012 23:27:12 GMT
|
27
|
+
Content-Type:
|
28
|
+
- text/plain; charset=UTF-8
|
29
|
+
Transfer-Encoding:
|
30
|
+
- chunked
|
31
|
+
Connection:
|
32
|
+
- keep-alive
|
33
|
+
body:
|
34
|
+
encoding: US-ASCII
|
35
|
+
string: ! '<Errors><error code="403"><notAuthorized message="The API secret
|
36
|
+
did not match, Invalid credentials passed"/></error></Errors>
|
37
|
+
|
38
|
+
'
|
39
|
+
http_version:
|
40
|
+
recorded_at: Tue, 04 Sep 2012 23:27:24 GMT
|
41
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.opentok.com/session/create
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: partner_id=459782&location=localhost
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*'
|
12
|
+
User-Agent:
|
13
|
+
- Ruby
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
X-Tb-Partner-Auth:
|
17
|
+
- 459782:b44c3baa32b6476d9d88e8194d0eb1c6b777f76b
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Server:
|
24
|
+
- nginx
|
25
|
+
Date:
|
26
|
+
- Tue, 04 Sep 2012 23:27:12 GMT
|
27
|
+
Content-Type:
|
28
|
+
- text/xml; charset=utf-8
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Pragma:
|
32
|
+
- no-cache
|
33
|
+
Cache-Control:
|
34
|
+
- no-cache
|
35
|
+
Access-Control-Allow-Origin:
|
36
|
+
- ! '*'
|
37
|
+
Content-Length:
|
38
|
+
- '294'
|
39
|
+
body:
|
40
|
+
encoding: US-ASCII
|
41
|
+
string: ! "<Sessions>\n <Session>\n <session_id>2_MX40NTk3ODJ-fjIwMTItMDktMDQgMjM6Mjc6MTIuNzY3ODY5KzAwOjAwfjAuNTQzNTEwNTE4NjQxfg</session_id>\n
|
42
|
+
\ <partner_id>459782</partner_id>\n <create_dt>2012-09-04 23:27:12.767869+00:00</create_dt>\n
|
43
|
+
\ <session_status></session_status>\n </Session>\n</Sessions>\n"
|
44
|
+
http_version:
|
45
|
+
recorded_at: Tue, 04 Sep 2012 23:27:24 GMT
|
46
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://api.opentok.com/hl/archive/200567af-0726-4e93-883b-fe0426d6310a/stitch
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: test=none
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*'
|
12
|
+
User-Agent:
|
13
|
+
- Ruby
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
X-Tb-Partner-Auth:
|
17
|
+
- 459782:b44c3baa32b6476d9d88e8194d0eb1c6b777f76b
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 201
|
21
|
+
message: Created
|
22
|
+
headers:
|
23
|
+
Server:
|
24
|
+
- nginx
|
25
|
+
Date:
|
26
|
+
- Tue, 04 Sep 2012 23:27:14 GMT
|
27
|
+
Content-Type:
|
28
|
+
- text/plain
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Location:
|
32
|
+
- https://tokbox.com.production.s3.amazonaws.com/459782%2F200567af-0726-4e93-883b-fe0426d6310a%2Fstitch.mp4?Expires=1346887634&AWSAccessKeyId=AKIAI6LQCPIXYVWCQV6Q&Signature=6%2BihfyAJiQGjmf%2FHV1BGCe14rr8%3D
|
33
|
+
X-Tb-Host:
|
34
|
+
- oms407-oak.tokbox.com
|
35
|
+
Content-Length:
|
36
|
+
- '0'
|
37
|
+
body:
|
38
|
+
encoding: US-ASCII
|
39
|
+
string: ''
|
40
|
+
http_version:
|
41
|
+
recorded_at: Tue, 04 Sep 2012 23:27:26 GMT
|
42
|
+
recorded_with: VCR 2.2.4
|
data/spec/opentok_spec.rb
CHANGED
@@ -1,167 +1,126 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class TestOpentokSDK < OpenTok::OpenTokSDK
|
4
|
-
def do_request(api_url, params, token=nil)
|
5
|
-
super
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
3
|
describe OpenTok do
|
10
|
-
|
11
|
-
before :all do
|
12
|
-
@api_key = '459782'
|
13
|
-
@api_secret = 'b44c3baa32b6476d9d88e8194d0eb1c6b777f76b'
|
14
|
-
@api_staging_url = 'https://staging.tokbox.com/hl'
|
15
|
-
@api_production_url = 'https://api.opentok.com/hl'
|
16
|
-
@host = 'localhost'
|
17
|
-
|
18
|
-
@opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret
|
19
|
-
end
|
20
4
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@opentok = TestOpentokSDK.new @api_key, @api_secret
|
26
|
-
@opts = {:partner_id => @api_key, :location=>@host}
|
27
|
-
end
|
5
|
+
let(:api_key) { '459782' }
|
6
|
+
let(:api_secret) { 'b44c3baa32b6476d9d88e8194d0eb1c6b777f76b' }
|
7
|
+
let(:api_url) { 'https://api.opentok.com' }
|
8
|
+
let(:host) { 'localhost' }
|
28
9
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
10
|
+
let(:opentok) { OpenTok::OpenTokSDK.new api_key, api_secret }
|
11
|
+
|
12
|
+
describe "test Initializers" do
|
13
|
+
it "should be backwards compatible if user set api URL with no effect" do
|
14
|
+
opentok = OpenTok::OpenTokSDK.new api_key, api_secret, {:api_url=>"bla bla"}
|
15
|
+
opentok.api_url.should eq api_url
|
35
16
|
end
|
36
17
|
|
37
|
-
it "should
|
38
|
-
|
39
|
-
|
18
|
+
it "should set api URL with no options" do
|
19
|
+
opentok = OpenTok::OpenTokSDK.new api_key, api_secret
|
20
|
+
opentok.api_url.should eq api_url
|
40
21
|
end
|
41
22
|
|
42
|
-
it "
|
43
|
-
|
44
|
-
|
45
|
-
doc.root.get_elements('Session')[0].get_elements('properties')[0].get_elements('p2p')[0].get_elements('preference')[0].children[0].to_s.should =='enabled'
|
23
|
+
it "should be OpenTok SDK Object" do
|
24
|
+
opentok = OpenTok::OpenTokSDK.new api_key, api_secret
|
25
|
+
opentok.should be_instance_of OpenTok::OpenTokSDK
|
46
26
|
end
|
47
27
|
end
|
48
28
|
|
49
|
-
describe "
|
50
|
-
|
51
|
-
@api_key = '11421872'
|
52
|
-
@api_secret = '296cebc2fc4104cd348016667ffa2a3909ec636f'
|
53
|
-
@opentok = TestOpentokSDK.new @api_key, @api_secret, {:api_url=>@api_production_url}
|
54
|
-
@opts = {:partner_id => @api_key, :location=>@host}
|
55
|
-
end
|
29
|
+
describe "Generate Sessions" do
|
30
|
+
use_vcr_cassette "session"
|
56
31
|
|
57
|
-
|
58
|
-
@opentok.should be_instance_of TestOpentokSDK
|
59
|
-
end
|
60
|
-
|
61
|
-
it "a new OpenTokSDK object should point to the staging environment by default" do
|
62
|
-
@opentok.api_url.should eq @api_production_url
|
63
|
-
end
|
32
|
+
let(:opentok) { OpenTok::OpenTokSDK.new api_key, api_secret }
|
64
33
|
|
65
|
-
it "should generate
|
66
|
-
session =
|
34
|
+
it "should generate valid session" do
|
35
|
+
session = opentok.create_session host
|
67
36
|
session.to_s.should match(/\A[0-9A-z_-]{40,}\Z/)
|
68
37
|
end
|
69
38
|
|
70
|
-
it "
|
71
|
-
|
72
|
-
|
73
|
-
doc.root.get_elements('Session')[0].get_elements('properties')[0].get_elements('p2p')[0].get_elements('preference')[0].children[0].to_s.should =='enabled'
|
39
|
+
it "should generate valid session camelCase" do
|
40
|
+
session = opentok.createSession host
|
41
|
+
session.to_s.should match(/\A[0-9A-z_-]{40,}\Z/)
|
74
42
|
end
|
75
43
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
@archiveId = '5f74aee5-ab3f-421b-b124-ed2a698ee939'
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should have archive resources" do
|
85
|
-
otArchive = @opentok.get_archive_manifest(@archiveId, @token)
|
86
|
-
otArchiveResource = otArchive.resources[0]
|
87
|
-
vid = otArchiveResource.getId()
|
88
|
-
vid.should match(/[0-9A-z=]+/)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should return download url" do
|
92
|
-
otArchive = @opentok.get_archive_manifest(@archiveId, @token)
|
93
|
-
otArchiveResource = otArchive.resources[0]
|
94
|
-
vid = otArchiveResource.getId()
|
95
|
-
url = otArchive.downloadArchiveURL(vid)
|
96
|
-
url.start_with?('http').should eq true
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should return file url" do
|
100
|
-
otArchive = @opentok.get_archive_manifest(@archiveId, @token)
|
101
|
-
otArchiveResource = otArchive.resources[0]
|
102
|
-
vid = otArchiveResource.getId()
|
103
|
-
url = otArchive.downloadArchiveURL(vid, @token)
|
104
|
-
url.start_with?('http').should eq true
|
105
|
-
end
|
44
|
+
it "should generate valid p2p session" do
|
45
|
+
# Creating Session object with p2p enabled
|
46
|
+
sessionProperties = {OpenTok::SessionPropertyConstants::P2P_PREFERENCE => "enabled"} # or disabled
|
47
|
+
session = opentok.createSession( @location, sessionProperties )
|
48
|
+
session.to_s.should match(/\A[0-9A-z_-]{40,}\Z/)
|
106
49
|
end
|
107
50
|
end
|
108
|
-
|
109
|
-
|
110
|
-
|
51
|
+
|
52
|
+
describe "invalid Sessions" do
|
53
|
+
use_vcr_cassette "invalidSession"
|
111
54
|
it "should raise an exception with an invalid key and secret" do
|
112
|
-
|
113
|
-
|
55
|
+
invalidOT = OpenTok::OpenTokSDK.new 0, ''
|
56
|
+
|
114
57
|
expect{
|
115
|
-
session =
|
58
|
+
session = invalidOT.create_session host
|
116
59
|
}.to raise_error OpenTok::OpenTokException
|
117
60
|
end
|
118
|
-
|
119
|
-
it "should be possible to set the api url as an option" do
|
120
|
-
opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret, :api_url => @api_production_url
|
121
|
-
|
122
|
-
opentok.api_url.should_not eq @api_staging_url
|
123
|
-
opentok.api_url.should eq @api_production_url
|
124
|
-
|
125
|
-
opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret, :api_url => @api_staging_url
|
126
|
-
|
127
|
-
opentok.api_url.should_not eq @api_production_url
|
128
|
-
opentok.api_url.should eq @api_staging_url
|
129
|
-
end
|
130
61
|
end
|
131
62
|
|
132
|
-
describe "
|
133
|
-
|
134
|
-
|
135
|
-
|
63
|
+
describe "Generate Tokens" do
|
64
|
+
let(:opentok) { OpenTok::OpenTokSDK.new api_key, api_secret }
|
65
|
+
let(:session) { opentok.createSession host }
|
66
|
+
it "should generate valid token" do
|
67
|
+
token = opentok.generate_token({:session_id => session, :role=>OpenTok::RoleConstants::MODERATOR})
|
68
|
+
token.should match(/(T1==)+[0-9A-z_]+/)
|
136
69
|
end
|
137
|
-
|
138
|
-
|
139
|
-
token
|
140
|
-
|
141
|
-
token.should match(/\A[0-9A-z=]+\Z/)
|
70
|
+
it "should generate valid token camelCase" do
|
71
|
+
token = opentok.generateToken({:session_id => session, :role=>OpenTok::RoleConstants::MODERATOR})
|
72
|
+
token.should match(/(T1==)+[0-9A-z_]+/)
|
142
73
|
end
|
143
|
-
|
144
74
|
it "should be able to set parameters in token" do
|
145
|
-
token =
|
146
|
-
|
75
|
+
token = opentok.generate_token :session_id => session, :role=> OpenTok::RoleConstants::PUBLISHER, :connection_data => "username=Bob,level=4"
|
147
76
|
str = token[4..token.length]
|
148
77
|
decoded = Base64.decode64(str)
|
149
|
-
|
150
78
|
decoded.should match(/publisher.*username.*Bob.*level.*4/)
|
151
79
|
end
|
152
80
|
end
|
153
81
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
82
|
+
|
83
|
+
describe "Archiving downloads" do
|
84
|
+
use_vcr_cassette "archives"
|
85
|
+
let(:api_key) { '459782' }
|
86
|
+
let(:api_secret) { 'b44c3baa32b6476d9d88e8194d0eb1c6b777f76b' }
|
87
|
+
let(:opentok) { OpenTok::OpenTokSDK.new api_key, api_secret, {:api_url=>""} }
|
88
|
+
let(:opts) { {:partner_id => api_key, :location=>host} }
|
89
|
+
|
90
|
+
let(:session) { '1_MX40NTk3ODJ-MTI3LjAuMC4xflR1ZSBTZXAgMDQgMTQ6NTM6MDIgUERUIDIwMTJ-MC41MjExODEzfg' }
|
91
|
+
let(:token) { opentok.generateToken({:session_id => session, :role=>OpenTok::RoleConstants::MODERATOR}) }
|
92
|
+
let(:archiveId) { "200567af-0726-4e93-883b-fe0426d6310a" }
|
93
|
+
|
94
|
+
it "should have archive resources" do
|
95
|
+
otArchive = opentok.getArchiveManifest(archiveId, token)
|
96
|
+
otArchiveResource = otArchive.resources[0]
|
97
|
+
vid = otArchiveResource.getId()
|
98
|
+
vid.should match(/[0-9A-z=]+/)
|
158
99
|
end
|
159
100
|
|
160
|
-
it "
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
101
|
+
it "should return download url" do
|
102
|
+
otArchive = opentok.get_archive_manifest(archiveId, token)
|
103
|
+
otArchiveResource = otArchive.resources[0]
|
104
|
+
vid = otArchiveResource.getId()
|
105
|
+
url = otArchive.downloadArchiveURL(vid, token)
|
106
|
+
url.start_with?('http').should eq true
|
165
107
|
end
|
166
108
|
end
|
109
|
+
|
110
|
+
describe "stitch api" do
|
111
|
+
use_vcr_cassette "stitchArchive"
|
112
|
+
let(:api_key) { '459782' }
|
113
|
+
let(:api_secret) { 'b44c3baa32b6476d9d88e8194d0eb1c6b777f76b' }
|
114
|
+
let(:opentok) { OpenTok::OpenTokSDK.new api_key, api_secret, {:api_url=>""} }
|
115
|
+
let(:session) { '1_MX40NTk3ODJ-MTI3LjAuMC4xflR1ZSBTZXAgMDQgMTQ6NTM6MDIgUERUIDIwMTJ-MC41MjExODEzfg' }
|
116
|
+
let(:token) { opentok.generateToken({:session_id => session, :role=>OpenTok::RoleConstants::MODERATOR}) }
|
117
|
+
let(:archiveId) { "200567af-0726-4e93-883b-fe0426d6310a" }
|
118
|
+
|
119
|
+
it "should return stich url" do
|
120
|
+
a = opentok.stitchArchive( archiveId )
|
121
|
+
a[:code].should == 201
|
122
|
+
a[:location].start_with?('http').should eq true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
167
126
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,2 +1,15 @@
|
|
1
|
-
require 'I18n'
|
2
1
|
require File.dirname(__FILE__) + '/../lib/opentok.rb'
|
2
|
+
|
3
|
+
require 'vcr'
|
4
|
+
require 'webmock'
|
5
|
+
|
6
|
+
VCR.configure do |c|
|
7
|
+
c.cassette_library_dir = 'spec/cassettes'
|
8
|
+
c.hook_into :webmock
|
9
|
+
c.default_cassette_options = { :record => :new_episodes }
|
10
|
+
c.allow_http_connections_when_no_cassette=true
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |c|
|
14
|
+
c.extend VCR::RSpec::Macros
|
15
|
+
end
|
metadata
CHANGED
@@ -1,25 +1,91 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opentok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Stijn Mathysen
|
9
9
|
- Karmen Blake
|
10
|
+
- Song Zheng
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date: 2012-
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
date: 2012-09-04 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rake
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: webmock
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: vcr
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
type: :development
|
73
|
+
prerelease: false
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
description: OpenTok is an API from TokBox that enables websites to weave live group
|
81
|
+
video communication into their online experience. With OpenTok you have the freedom
|
82
|
+
and flexibility to create the most engaging web experience for your users. OpenTok
|
83
|
+
is currently available as a JavaScript and ActionScript 3.0 library. This gem allows
|
84
|
+
you to connect to the API from within Ruby (and Rails)
|
20
85
|
email:
|
21
86
|
- stijn@skylight.be
|
22
87
|
- karmenblake@gmail.com
|
88
|
+
- song@tokbox.com
|
23
89
|
executables: []
|
24
90
|
extensions: []
|
25
91
|
extra_rdoc_files: []
|
@@ -27,7 +93,7 @@ files:
|
|
27
93
|
- .gitignore
|
28
94
|
- CHANGES
|
29
95
|
- Gemfile
|
30
|
-
-
|
96
|
+
- LICENSE
|
31
97
|
- README.md
|
32
98
|
- Rakefile
|
33
99
|
- doc/CHANGES.html
|
@@ -78,16 +144,21 @@ files:
|
|
78
144
|
- doc/rdoc.css
|
79
145
|
- doc/spec/opentok_spec_rb.html
|
80
146
|
- doc/spec/spec_helper_rb.html
|
81
|
-
- lib/monkey_patches.rb
|
82
147
|
- lib/open_tok/archive.rb
|
83
148
|
- lib/open_tok/archive_timeline_event.rb
|
84
149
|
- lib/open_tok/archive_video_resource.rb
|
85
150
|
- lib/open_tok/exception.rb
|
86
151
|
- lib/open_tok/open_tok_sdk.rb
|
152
|
+
- lib/open_tok/request.rb
|
87
153
|
- lib/open_tok/session.rb
|
154
|
+
- lib/open_tok/utils.rb
|
88
155
|
- lib/open_tok/version.rb
|
89
156
|
- lib/opentok.rb
|
90
157
|
- opentok.gemspec
|
158
|
+
- spec/cassettes/archives.yml
|
159
|
+
- spec/cassettes/invalidSession.yml
|
160
|
+
- spec/cassettes/session.yml
|
161
|
+
- spec/cassettes/stitchArchive.yml
|
91
162
|
- spec/opentok_spec.rb
|
92
163
|
- spec/spec_helper.rb
|
93
164
|
homepage: https://github.com/opentok/Opentok-Ruby-SDK
|
@@ -110,10 +181,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
181
|
version: '0'
|
111
182
|
requirements: []
|
112
183
|
rubyforge_project: opentok
|
113
|
-
rubygems_version: 1.8.
|
184
|
+
rubygems_version: 1.8.24
|
114
185
|
signing_key:
|
115
186
|
specification_version: 3
|
116
187
|
summary: OpenTok gem
|
117
188
|
test_files:
|
189
|
+
- spec/cassettes/archives.yml
|
190
|
+
- spec/cassettes/invalidSession.yml
|
191
|
+
- spec/cassettes/session.yml
|
192
|
+
- spec/cassettes/stitchArchive.yml
|
118
193
|
- spec/opentok_spec.rb
|
119
194
|
- spec/spec_helper.rb
|
data/LICENCE
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
Copyright (c) 2011 TokBox, Inc.
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
of this software and associated documentation files (the "Software"), to deal
|
5
|
-
in the Software without restriction, including without limitation the rights
|
6
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
copies of the Software, and to permit persons to whom the Software is
|
8
|
-
furnished to do so, subject to the following conditions:
|
9
|
-
|
10
|
-
The above copyright notice and this permission notice shall be included in
|
11
|
-
all copies or substantial portions of the Software.
|
12
|
-
|
13
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
THE SOFTWARE.
|
data/lib/monkey_patches.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
OpenTok Ruby Library
|
3
|
-
http://www.tokbox.com/
|
4
|
-
|
5
|
-
Copyright 2010 - 2011, TokBox, Inc.
|
6
|
-
|
7
|
-
Last modified: 2011-02-17
|
8
|
-
=end
|
9
|
-
|
10
|
-
class Hash
|
11
|
-
|
12
|
-
# Adding a urlencode method to the hash class for easy querstring generation
|
13
|
-
def urlencode
|
14
|
-
to_a.map do |name_value|
|
15
|
-
if name_value[1].is_a? Array
|
16
|
-
name_value[0] = CGI.escape name_value[0].to_s
|
17
|
-
name_value[1].map { |e| CGI.escape e.to_s }
|
18
|
-
name_value[1] = name_value[1].join "&" + name_value[0] + "="
|
19
|
-
name_value.join '='
|
20
|
-
else
|
21
|
-
name_value.map { |e| CGI.escape e.to_s }.join '='
|
22
|
-
end
|
23
|
-
end.join '&'
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class Net::HTTP
|
28
|
-
alias_method :old_initialize, :initialize
|
29
|
-
def initialize(*args)
|
30
|
-
old_initialize(*args)
|
31
|
-
@ssl_context = OpenSSL::SSL::SSLContext.new
|
32
|
-
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
33
|
-
end
|
34
|
-
end
|