From b92a8640365d1fd0f6e46ae3e7b8c874de7ef505 Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Mon, 7 May 2012 01:48:54 -0700 Subject: [PATCH 1/8] added test cases for session generation in staging and production environment, and test passing p2p parameter --- spec/opentok_spec.rb | 72 ++++++++++++++++++++++++++++++++++++-------- spec/spec_helper.rb | 2 +- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/spec/opentok_spec.rb b/spec/opentok_spec.rb index 3d76a34..ed2334e 100644 --- a/spec/opentok_spec.rb +++ b/spec/opentok_spec.rb @@ -1,5 +1,11 @@ require 'spec_helper' +class TestOpentokSDK < OpenTok::OpenTokSDK + def do_request(api_url, params, token=nil) + super + end +end + describe OpenTok do before :all do @@ -11,23 +17,65 @@ @opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret end - - it "should be possible to valid a OpenTokSDK object with a valid key and secret" do - @opentok.should be_instance_of OpenTok::OpenTokSDK - end - - it "a new OpenTokSDK object should point to the staging environment by default" do - @opentok.api_url.should eq @api_staging_url + + describe "Staging Environment" do + before :all do + @api_key = '14971292' + @api_secret = 'ecbe2b25afec7887bd72fe4763b87add8ce02658' + @opentok = TestOpentokSDK.new @api_key, @api_secret + @opts = {:partner_id => @api_key, :location=>@host} + end + + it "should be possible to valid a OpenTokSDK object with a valid key and secret" do + @opentok.should be_instance_of TestOpentokSDK + end + + it "a new OpenTokSDK object should point to the staging environment by default" do + @opentok.api_url.should eq @api_staging_url + end + + it "should generate a valid session" do + session = @opentok.create_session @host + session.to_s.should match(/\A[0-9A-z_-]{40,}\Z/) + end + + it "do_request should respond with valid p2p" do + @opts.merge!({'p2p.preference' => 'enabled'}) + doc = @opentok.do_request("/session/create", @opts) + doc.root.get_elements('Session')[0].get_elements('properties')[0].get_elements('p2p')[0].get_elements('preference')[0].children[0].to_s.should =='enabled' + end end - - describe "Session creation" do - it "should be possible to generate a valid API token with a valid key and secret" do - opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret - session = opentok.create_session @host + + describe "Production Environment" do + before :all do + @api_key = '11421872' + @api_secret = '296cebc2fc4104cd348016667ffa2a3909ec636f' + @opentok = TestOpentokSDK.new @api_key, @api_secret, {:api_url=>@api_production_url} + @opts = {:partner_id => @api_key, :location=>@host} + end + + it "should be possible to valid a OpenTokSDK object with a valid key and secret" do + @opentok.should be_instance_of TestOpentokSDK + end + it "a new OpenTokSDK object should point to the staging environment by default" do + @opentok.api_url.should eq @api_production_url + end + + it "should generate a valid session" do + session = @opentok.create_session @host session.to_s.should match(/\A[0-9A-z_-]{40,}\Z/) end + + it "do_request should respond with valid p2p" do + @opts.merge!({'p2p.preference' => 'enabled'}) + doc = @opentok.do_request("/session/create", @opts) + doc.root.get_elements('Session')[0].get_elements('properties')[0].get_elements('p2p')[0].get_elements('preference')[0].children[0].to_s.should =='enabled' + end + end + + describe "Session creation" do it "should raise an exception with an invalid key and secret" do opentok = OpenTok::OpenTokSDK.new 0, '' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a75ed7e..b2b3095 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,2 +1,2 @@ require 'I18n' -require File.dirname(__FILE__) + '/../lib/opentok.rb' \ No newline at end of file +require File.dirname(__FILE__) + '/../lib/opentok.rb' From d85d5643fee0e58b06de42438c21a3923d3d680c Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Mon, 7 May 2012 16:07:34 -0700 Subject: [PATCH 2/8] get_archive_manifest now raises error if token does not have moderator assignment --- lib/open_tok/open_tok_sdk.rb | 7 +++++++ spec/opentok_spec.rb | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/lib/open_tok/open_tok_sdk.rb b/lib/open_tok/open_tok_sdk.rb index e621dc9..c5606cf 100644 --- a/lib/open_tok/open_tok_sdk.rb +++ b/lib/open_tok/open_tok_sdk.rb @@ -132,6 +132,13 @@ def create_session(location='', opts={}) # 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) # 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. def get_archive_manifest(archive_id, token) + # verify that token is MODERATOR token + decoder = token[4..token.length] + tokenInfo = Base64.decode64(decoder) + if not (tokenInfo.split('role=')[1].split('&')[0]==OpenTok::RoleConstants::MODERATOR) + raise OpenTokException.new("Token must be assigned role of MODERATROR") + end + doc = do_request("/archive/getmanifest/#{archive_id}", {}, token) if not doc.get_elements('Errors').empty? raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s diff --git a/spec/opentok_spec.rb b/spec/opentok_spec.rb index ed2334e..6786ca4 100644 --- a/spec/opentok_spec.rb +++ b/spec/opentok_spec.rb @@ -124,5 +124,12 @@ def do_request(api_url, params, token=nil) @opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret @valid_session = @opentok.create_session(@host).to_s end + + it "If token does not have moderator role, raise error" do + token = @opentok.generate_token(:session_id=>@valid_session) + expect{ + @opentok.get_archive_manifest("", token) + }.to raise_error OpenTok::OpenTokException + end end end From a7f58323bf1dac35fc00b4dfe669711852b2a61d Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Sun, 20 May 2012 04:22:15 -0500 Subject: [PATCH 3/8] fixed archive functions, updated README --- README.md | 40 +++++++++++++++++++---- lib/open_tok/archive.rb | 44 +++++++++++++++++++++++--- lib/open_tok/archive_video_resource.rb | 6 +++- lib/open_tok/open_tok_sdk.rb | 2 +- spec/opentok_spec.rb | 24 ++++++++++++++ 5 files changed, 103 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4ea90a1..8409cbd 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ session_id = @opentok.create_session( @location, session_properties ) ### Generating Token With the generated session_id, you can start generating tokens for each user. `generate_token` takes in hash with 1-4 properties: -> session_id (string) - required +> session_id (string) - REQUIRED > role (string) - OPTIONAL. subscriber, publisher, or moderator > expire_time (int) - OPTIONAL. Time when token will expire in unix timestamp > connection_data (string) - OPTIONAL. Metadata to store data (names, user id, etc) @@ -69,17 +69,45 @@ token = @opentok.generate_token :session_id => session, :role => OpenTok::RoleCo ### Downloading Archive Videos -To Download archives, first you must first create a token that has a **moderator** role +To Download archived video, you must have an Archive ID which you get from the javascript library + +#### Quick Overview of the javascript library: +1. Create an event listener on `archiveCreated` event: `session.addEventListener('archiveCreated', archiveCreatedHandler);` +2. Create an archive: `archive = session.createArchive(...);` +3. When archive is successfully created `archiveCreatedHandler` would be triggered. An Archive object containing `archiveId` property is passed into your function. Save this in your database, this archiveId is what you use to reference the archive for playbacks and download videos +4. After your archive has been created, you can start recording videos into it by calling `session.startRecording(archive)` +> Optionally, you can also use the standalone archiving, which means that each archive would have only 1 video ### Get Archive Manifest +With your **moderator token** and OpentokSDK Object, you can generate OpenTokArchive Object, which contains information for all videos in the Archive `get_archive_manifest()` takes in 2 parameters: **archiveId** and **moderator token** -> **returns** an `OpenTokArchive`. The *resources* property of this object is array of `OpenTokArchiveVideoResource`, and each `OpenTokArchiveVideoResource` object represents a video in the archive. +> archive_id (string) - REQUIRED. +> **returns** an `OpenTokArchive` object. The *resources* property of this object is array of `OpenTokArchiveVideoResource` objects, and each `OpenTokArchiveVideoResource` object represents a video in the archive. + +Example:(Make sure you have the OpentokSDK Object) +
+@token = 'moderator_token'
+@archiveId = '5f74aee5-ab3f-421b-b124-ed2a698ee939' #Obtained from Javascript Library
+otArchive = @opentok.get_archive_manifest(@archiveId, @token)
+
### Get video ID -With your `OpenTokArchive` object, call `getId()` +`OpenTokArchive.resources` is an array of `OpenTokArchiveVideoResource` objects. OpenTokArchiveVideoResource has `getId()` method that returns the videoId `getId()` will return the video ID (a String) +Example: +
+otArchive = @opentok.get_archive_manifest(@archiveId, @token)
+otVideoResource = otArchive.resources[0]
+videoId = otVideoResource.getId()
+
+ ### Get Download Url -`downloadArchiveURL` takes 1 parameters: `video ID` and returns download URL for the video - +`OpenTokArchive` has `downloadArchiveURL` that will return an url string for downloading the video in the archive. +> video_id (string) - REQUIRED +> returns url string +Example: +
+url1 = otArchive.downloadArchiveURL(vid1)
+
diff --git a/lib/open_tok/archive.rb b/lib/open_tok/archive.rb index f3b36d4..c03e464 100644 --- a/lib/open_tok/archive.rb +++ b/lib/open_tok/archive.rb @@ -9,18 +9,52 @@ module OpenTok class Archive attr_accessor :archive_id, :archive_title, :resources, :timeline - def initialize(archive_id, archive_title, resources, timeline) + def initialize(archive_id, archive_title, resources, timeline, apiUrl, token) @archive_id = archive_id @archive_title = archive_title @resources = resources @timeline = timeline + @apiUrl = apiUrl + @token = token + end + + def do_request(api_url) + url = URI.parse(api_url) + req = Net::HTTP::Get.new(url.path) + + req.add_field 'X-TB-TOKEN-AUTH', @token + + http = Net::HTTP.new(url.host, url.port) + http.use_ssl = true if @apiUrl.start_with?("https") + res = http.start {|http| http.request(req)} + case res + when Net::HTTPSuccess, Net::HTTPRedirection + return res.read_body + else + res.error! + end + rescue Net::HTTPExceptions + raise + raise OpenTokException.new 'Unable to create fufill request: ' + $! + rescue NoMethodError + raise + raise OpenTokException.new 'Unable to create a fufill request at this time: ' + $1 end def download_archive_url(video_id) - "#{API_URL}/archive/url/#{@archive_id}/#{video_id}" + doc = do_request "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}" + if not doc.get_elements('Errors').empty? + raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s + end + doc + end + + def downloadArchiveURL(video_id) + doc = do_request "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}" + return doc end - def self.parse_manifest(manifest) + def self.parse_manifest(manifest, apiUrl, token) archive_id = manifest.attributes['archiveid'] archive_title = manifest.attributes['title'] @@ -34,7 +68,7 @@ def self.parse_manifest(manifest) timeline << OpenTok::ArchiveTimelineEvent.parseXML(event) end - OpenTok::Archive.new(archive_id, archive_title, resources, timeline) + OpenTok::Archive.new(archive_id, archive_title, resources, timeline, apiUrl, token) end end -end \ No newline at end of file +end diff --git a/lib/open_tok/archive_video_resource.rb b/lib/open_tok/archive_video_resource.rb index 7bf6bbf..a6344bb 100644 --- a/lib/open_tok/archive_video_resource.rb +++ b/lib/open_tok/archive_video_resource.rb @@ -16,9 +16,13 @@ def initialize(id, length) @length = length end + def getId + return @id + end + def self.parseXML(video_resource_item) OpenTok::ArchiveVideoResource.new(video_resource_item.attributes['id'], video_resource_item.attributes['length']) end end -end \ No newline at end of file +end diff --git a/lib/open_tok/open_tok_sdk.rb b/lib/open_tok/open_tok_sdk.rb index c5606cf..0b2597e 100644 --- a/lib/open_tok/open_tok_sdk.rb +++ b/lib/open_tok/open_tok_sdk.rb @@ -143,7 +143,7 @@ def get_archive_manifest(archive_id, token) if not doc.get_elements('Errors').empty? raise OpenTokException.new doc.get_elements('Errors')[0].get_elements('error')[0].children.to_s end - OpenTok::Archive.parse_manifest(doc.get_elements('manifest')[0]) + OpenTok::Archive.parse_manifest(doc.get_elements('manifest')[0], @api_url, token) end protected diff --git a/spec/opentok_spec.rb b/spec/opentok_spec.rb index 6786ca4..05b6229 100644 --- a/spec/opentok_spec.rb +++ b/spec/opentok_spec.rb @@ -72,6 +72,30 @@ def do_request(api_url, params, token=nil) doc = @opentok.do_request("/session/create", @opts) doc.root.get_elements('Session')[0].get_elements('properties')[0].get_elements('p2p')[0].get_elements('preference')[0].children[0].to_s.should =='enabled' end + + describe "Archiving downloads" do + before :all do + @session = '1_MX4xNDk3MTI5Mn5-MjAxMi0wNS0yMCAwMTowMzozMS41MDEzMDArMDA6MDB-MC40NjI0MjI4MjU1MDF-' + @opentok = OpenTok::OpenTokSDK.new @api_key, @api_secret, {:api_url=>@api_production_url} + @token = @opentok.generate_token({:session_id => @session, :role=>OpenTok::RoleConstants::MODERATOR}) + @archiveId = '5f74aee5-ab3f-421b-b124-ed2a698ee939' + end + + it "should have archive resources" do + otArchive = @opentok.get_archive_manifest(@archiveId, @token) + otArchiveResource = otArchive.resources[0] + vid = otArchiveResource.getId() + vid.should match(/[0-9A-z=]+/) + end + + it "should return download url" do + otArchive = @opentok.get_archive_manifest(@archiveId, @token) + otArchiveResource = otArchive.resources[0] + vid = otArchiveResource.getId() + url = otArchive.downloadArchiveURL(vid) + url.start_with?('http').should eq true + end + end end From 6d0a12ccfb46f02e069f6ace49e24e730134752a Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Sun, 20 May 2012 04:32:48 -0500 Subject: [PATCH 4/8] updated --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8409cbd..8391b0e 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ To Download archived video, you must have an Archive ID which you get from the j 2. Create an archive: `archive = session.createArchive(...);` 3. When archive is successfully created `archiveCreatedHandler` would be triggered. An Archive object containing `archiveId` property is passed into your function. Save this in your database, this archiveId is what you use to reference the archive for playbacks and download videos 4. After your archive has been created, you can start recording videos into it by calling `session.startRecording(archive)` -> Optionally, you can also use the standalone archiving, which means that each archive would have only 1 video + Optionally, you can also use the standalone archiving, which means that each archive would have only 1 video: ### Get Archive Manifest With your **moderator token** and OpentokSDK Object, you can generate OpenTokArchive Object, which contains information for all videos in the Archive @@ -109,5 +109,5 @@ videoId = otVideoResource.getId() Example:
-url1 = otArchive.downloadArchiveURL(vid1)
+url = otArchive.downloadArchiveURL(video_id)
 
From bd59161932c42abf8e953cff277c01389a5bb75c Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Sun, 20 May 2012 04:34:12 -0500 Subject: [PATCH 5/8] Added a link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8391b0e..8440e17 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ token = @opentok.generate_token :session_id => session, :role => OpenTok::RoleCo ### Downloading Archive Videos To Download archived video, you must have an Archive ID which you get from the javascript library -#### Quick Overview of the javascript library: +#### Quick Overview of the javascript library: 1. Create an event listener on `archiveCreated` event: `session.addEventListener('archiveCreated', archiveCreatedHandler);` 2. Create an archive: `archive = session.createArchive(...);` 3. When archive is successfully created `archiveCreatedHandler` would be triggered. An Archive object containing `archiveId` property is passed into your function. Save this in your database, this archiveId is what you use to reference the archive for playbacks and download videos From 0384640f8090707cacca7386cf11d4a095391529 Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Thu, 31 May 2012 03:56:58 -0700 Subject: [PATCH 6/8] changed downloadArchiveUrl --- README.md | 5 +++-- lib/open_tok/archive.rb | 13 ++++++++----- spec/opentok_spec.rb | 8 ++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8440e17..0262340 100644 --- a/README.md +++ b/README.md @@ -103,11 +103,12 @@ videoId = otVideoResource.getId() ### Get Download Url -`OpenTokArchive` has `downloadArchiveURL` that will return an url string for downloading the video in the archive. +`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 > video_id (string) - REQUIRED +> token (string) - REQUIRED > returns url string Example:
-url = otArchive.downloadArchiveURL(video_id)
+url = otArchive.downloadArchiveURL(video_id, token)
 
diff --git a/lib/open_tok/archive.rb b/lib/open_tok/archive.rb index c03e464..09cefac 100644 --- a/lib/open_tok/archive.rb +++ b/lib/open_tok/archive.rb @@ -18,11 +18,11 @@ def initialize(archive_id, archive_title, resources, timeline, apiUrl, token) @token = token end - def do_request(api_url) + def do_request(api_url, token) url = URI.parse(api_url) req = Net::HTTP::Get.new(url.path) - req.add_field 'X-TB-TOKEN-AUTH', @token + req.add_field 'X-TB-TOKEN-AUTH', token http = Net::HTTP.new(url.host, url.port) http.use_ssl = true if @apiUrl.start_with?("https") @@ -49,9 +49,12 @@ def download_archive_url(video_id) doc end - def downloadArchiveURL(video_id) - doc = do_request "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}" - return doc + def downloadArchiveURL(video_id, token="") + if token=="" + return "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}" + else + return do_request "#{@apiUrl}/archive/url/#{@archive_id}/#{video_id}", token + end end def self.parse_manifest(manifest, apiUrl, token) diff --git a/spec/opentok_spec.rb b/spec/opentok_spec.rb index 05b6229..57b462e 100644 --- a/spec/opentok_spec.rb +++ b/spec/opentok_spec.rb @@ -95,6 +95,14 @@ def do_request(api_url, params, token=nil) url = otArchive.downloadArchiveURL(vid) url.start_with?('http').should eq true end + + it "should return file url" do + otArchive = @opentok.get_archive_manifest(@archiveId, @token) + otArchiveResource = otArchive.resources[0] + vid = otArchiveResource.getId() + url = otArchive.downloadArchiveURL(vid, @token) + url.start_with?('http').should eq true + end end end From ac55c3a4b3f94dc6584fc9664302761102a73708 Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Thu, 31 May 2012 04:35:50 -0700 Subject: [PATCH 7/8] updated version number --- lib/open_tok/version.rb | 4 ++-- opentok.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/open_tok/version.rb b/lib/open_tok/version.rb index d58faa5..32accfd 100644 --- a/lib/open_tok/version.rb +++ b/lib/open_tok/version.rb @@ -1,3 +1,3 @@ module Opentok - VERSION = "0.0.5" -end \ No newline at end of file + VERSION = "0.0.7" +end diff --git a/opentok.gemspec b/opentok.gemspec index d932bd8..0fd767f 100644 --- a/opentok.gemspec +++ b/opentok.gemspec @@ -8,7 +8,7 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.authors = ["Stijn Mathysen", "Karmen Blake"] s.email = ["stijn@skylight.be", "karmenblake@gmail.com"] - s.homepage = "https://github.com/stijnster/opentok" + s.homepage = "https://github.com/opentok/Opentok-Ruby-SDK" s.summary = %q{OpenTok gem} s.description = %q{OpenTok is a free set of APIs 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)} From 01fe6abc66bfec4d10255cd58e5350a9c8d2fd45 Mon Sep 17 00:00:00 2001 From: Song Zheng Date: Tue, 5 Jun 2012 15:51:42 -0700 Subject: [PATCH 8/8] moderator_token download archive cause errors fix --- lib/open_tok/open_tok_sdk.rb | 7 +------ spec/opentok_spec.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/open_tok/open_tok_sdk.rb b/lib/open_tok/open_tok_sdk.rb index 0b2597e..513c617 100644 --- a/lib/open_tok/open_tok_sdk.rb +++ b/lib/open_tok/open_tok_sdk.rb @@ -132,12 +132,7 @@ def create_session(location='', opts={}) # 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) # 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. def get_archive_manifest(archive_id, token) - # verify that token is MODERATOR token - decoder = token[4..token.length] - tokenInfo = Base64.decode64(decoder) - if not (tokenInfo.split('role=')[1].split('&')[0]==OpenTok::RoleConstants::MODERATOR) - raise OpenTokException.new("Token must be assigned role of MODERATROR") - end + # TODO: verify that token is MODERATOR token, Staging and production doc = do_request("/archive/getmanifest/#{archive_id}", {}, token) if not doc.get_elements('Errors').empty? diff --git a/spec/opentok_spec.rb b/spec/opentok_spec.rb index 57b462e..3a52f9b 100644 --- a/spec/opentok_spec.rb +++ b/spec/opentok_spec.rb @@ -157,11 +157,11 @@ def do_request(api_url, params, token=nil) @valid_session = @opentok.create_session(@host).to_s end - it "If token does not have moderator role, raise error" do - token = @opentok.generate_token(:session_id=>@valid_session) - expect{ - @opentok.get_archive_manifest("", token) - }.to raise_error OpenTok::OpenTokException - end +# it "If token does not have moderator role, raise error" do +# token = @opentok.generate_token(:session_id=>@valid_session) +# expect{ +# @opentok.get_archive_manifest("", token) +# }.to raise_error OpenTok::OpenTokException +# end end end