bigbluebutton-api-ruby 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ features/config.yml
5
5
  logs/bbb.log
6
6
  rdoc/
7
7
  logs/*
8
+ .bundle/
@@ -0,0 +1 @@
1
+ 1.9.3-p484
@@ -1,3 +1,11 @@
1
+ === 1.3.0
2
+
3
+ * Drop support to BigBlueButton 0.7 and add BigBlueButton to 0.81. Includes support to the new API calls <tt>getDefaultConfigXML</tt> and <tt>setConfigXML</tt>.
4
+ * Reviewed all methods responses (some changed a bit) and documentation.
5
+ * Allow non standard options to be passed to *all* API calls.
6
+ * Removed method <tt>join_meeting</tt> that was usually not used. Should always use <tt>join_meeting_url</tt>.
7
+ * Moved the hash extension method <tt>from_xml</tt> to its own class to prevent conflicts with Rails. See https://github.com/mconf/bigbluebutton-api-ruby/pull/6.
8
+
1
9
  === 1.2.0
2
10
 
3
11
  * Allow non standard options to be passed to some API calls. These API calls are: create_meeting, join_meeting_url,
@@ -1,13 +1,13 @@
1
1
  GIT
2
2
  remote: git://github.com/mconf/bbbot-ruby.git
3
- revision: 6b47fe212ea49a3120e9ee787cedd6097c9c81bd
3
+ revision: fcfd8c4c71371653335a46d7462ee14a9301f546
4
4
  specs:
5
5
  bbbot-ruby (0.0.1)
6
6
 
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- bigbluebutton-api-ruby (1.2.0)
10
+ bigbluebutton-api-ruby (1.3.0)
11
11
  xml-simple (>= 1.1.1)
12
12
 
13
13
  GEM
@@ -67,7 +67,7 @@ GEM
67
67
  multi_json (~> 1.0)
68
68
  rubyzip
69
69
  term-ansicolor (1.0.7)
70
- xml-simple (1.1.1)
70
+ xml-simple (1.1.3)
71
71
  xpath (0.1.4)
72
72
  nokogiri (~> 1.3)
73
73
 
@@ -1,40 +1,44 @@
1
1
  = bigbluebutton-api-ruby {<img src="http://travis-ci.org/mconf/bigbluebutton-api-ruby.png"/>}[http://travis-ci.org/mconf/bigbluebutton-api-ruby]
2
2
 
3
- This is a ruby gem that provides access to the {BigBlueButton}[http://bigbluebutton.org] API.
4
- For the API documentation see {this page}[http://code.google.com/p/bigbluebutton/wiki/API].
3
+ This is a ruby gem that provides access to the API of {BigBlueButton}[http://bigbluebutton.org].
4
+ See the documentation of the API {here}[http://code.google.com/p/bigbluebutton/wiki/API].
5
5
 
6
- Basically it enables a ruby application to interact with BigBlueButton by calling ruby methods instead of HTTP requests making it a lot easier to
7
- interact with BigBlueButton. And also formats the responses to a ruby-friendly format.
6
+ It enables a ruby application to interact with BigBlueButton by calling ruby methods instead of
7
+ HTTP requests, making it a lot easier to interact with BigBlueButton. It also formats the responses
8
+ to a ruby-friendly format and includes helper classes to deal with more complicated API calls, such
9
+ as the pre-upload of slides.
8
10
 
9
- Some details:
11
+ A few features it has:
10
12
 
11
13
  * Provides methods to perform all API calls and get the responses;
12
14
  * Converts the XML responses to ruby hashes, that are easier to work with;
13
15
  * Converts the string values returned to native ruby types. For instance:
14
16
  * Dates are converted DateTime objects (e.g. "Thu Sep 01 17:51:42 UTC 2011");
15
17
  * Response codes are converted to boolean (e.g. "SUCCESS" becomes <tt>true</tt>);
16
- * Deals with errors (e.g. timeouts) throwing BigBlueButtonException exceptions;
18
+ * Deals with errors (e.g. timeouts) throwing <tt>BigBlueButtonException</tt> exceptions;
17
19
  * Support to multiple BigBlueButton API versions (see below).
18
20
 
19
21
  == Supported BigBlueButton versions
20
22
 
21
- The current version of this gem supports *all* the following versions of BigBlueButton:
23
+ The current version of this gem supports <em>all</em> the following versions of BigBlueButton:
22
24
 
23
- * 0.8: currently in the beta3 stage.
24
- * 0.7: including 0.7, 0.71 and 0.71a.
25
+ * 0.8
26
+ * 0.81
25
27
 
26
28
  Older versions:
27
29
 
28
- * 0.64: see the branch "api-0.64". The last version with support to 0.64 is {version 0.0.10}[https://github.com/mconf/bigbluebutton-api-ruby/tree/v0.0.10]. It supports both 0.64 and 0.7.
30
+ * 0.7 (including 0.7, 0.71 and 0.71a): The last version with support to 0.7* is {version 1.2.0}[https://github.com/mconf/bigbluebutton-api-ruby/tree/v1.2.0]. It supports versions 0.7 and 0.8.
31
+ * 0.64: see the branch <tt>api-0.64</tt>. The last version with support to 0.64 is {version 0.0.10}[https://github.com/mconf/bigbluebutton-api-ruby/tree/v0.0.10]. It supports versions 0.64 and 0.7.
29
32
 
30
33
  == Supported ruby versions
31
34
 
32
35
  Tested in rubies:
33
36
 
34
- * ruby-1.8.7
35
- * ruby-1.9.2
36
- * ree-1.8.7
37
- * jruby
37
+ * ruby-2.0.0 (p353)
38
+ * ruby-1.9.3 (p484) *recommended*
39
+ * ruby-1.9.2 (p290)
40
+
41
+ Use these versions to be sure it will work. Other patches of these rubies (e.g. ruby 1.9.3-p194) should work as well.
38
42
 
39
43
  == Releases
40
44
 
@@ -42,9 +46,9 @@ For a list of releases and release notes see {CHANGELOG.rdoc}[https://github.com
42
46
 
43
47
  == Development
44
48
 
45
- Information about the development of <tt>bigbluebutton-api-ruby</tt> can be found in {our wiki}[https://github.com/mconf/bigbluebutton-api-ruby/wiki].
49
+ Information for developers of <tt>bigbluebutton-api-ruby</tt> can be found in {our wiki}[https://github.com/mconf/bigbluebutton-api-ruby/wiki].
46
50
 
47
- The development of this gem is guided by the requirements of the project Mconf. To know more about it visit the {project's wiki}[http://code.google.com/p/mconf/].
51
+ The development of this gem is guided by the requirements of the project Mconf. To know more about it visit the {project's wiki}[https://github.com/mconf/wiki/wiki].
48
52
 
49
53
  == License
50
54
 
data/Rakefile CHANGED
@@ -17,11 +17,12 @@ Cucumber::Rake::Task.new do |t|
17
17
  prepend = "--tags ~@need-bot"
18
18
  end
19
19
 
20
- # defaults to BBB 0.8
21
- if ENV["V"] == "0.7" or ENV["VERSION"] == "0.7"
22
- t.cucumber_opts = "--format pretty --tags ~@wip --tags @version-all,@version-07 #{prepend}"
20
+ # defaults to BBB 0.81, that runs all tests
21
+ # if set to 0.8 only, won't run tests for newer versions
22
+ if ENV["V"] == "0.8" or ENV["VERSION"] == "0.8"
23
+ t.cucumber_opts = "--format pretty --tags ~@wip --tags @version-all #{prepend}"
23
24
  else
24
- t.cucumber_opts = "--format pretty --tags ~@wip --tags @version-all,@version-08 #{prepend}"
25
+ t.cucumber_opts = "--format pretty --tags ~@wip --tags @version-all,@version-081 #{prepend}"
25
26
  end
26
27
  end
27
28
 
@@ -2,7 +2,7 @@ $:.push File.expand_path("../lib", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'bigbluebutton-api-ruby'
5
- s.version = '1.2.0'
5
+ s.version = '1.3.0'
6
6
  s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'LICENSE_003', 'CHANGELOG.rdoc']
7
7
  s.summary = 'Provides an interface to the BigBlueButton web meeting API (https://github.com/mconf/bigbluebutton-api-ruby)'
8
8
  s.description = s.summary
@@ -0,0 +1,74 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
3
+
4
+ require 'bigbluebutton_api'
5
+ require 'prepare'
6
+
7
+ begin
8
+ prepare
9
+
10
+ puts "---------------------------------------------------"
11
+ config_xml = @api.get_default_config_xml
12
+ config_xml = BigBlueButton::BigBlueButtonConfigXml.new(config_xml)
13
+ puts "The default config.xml was taken from the server"
14
+
15
+ puts "---------------------------------------------------"
16
+ layouts = @api.get_available_layouts
17
+ puts "The available layouts are"
18
+ puts layouts.inspect
19
+ puts "The default layouts are"
20
+ puts @api.get_default_layouts.inspect
21
+
22
+ puts "---------------------------------------------------"
23
+ num = rand(1000)
24
+ meeting_name = "Test Meeting #{num}"
25
+ meeting_id = "test-meeting-#{num}"
26
+ username = "House #{rand(1000)}"
27
+ username2 = "Cameron #{rand(1000)}"
28
+ options = { :moderatorPW => "54321",
29
+ :attendeePW => "12345",
30
+ :welcome => 'Welcome to my meeting',
31
+ :dialNumber => '1-800-000-0000x00000#',
32
+ :logoutURL => 'https://github.com/mconf/bigbluebutton-api-ruby',
33
+ :maxParticipants => 25 }
34
+ response = @api.create_meeting(meeting_name, meeting_id, options)
35
+ puts "A meeting has been created: #{meeting_id}"
36
+
37
+ puts "---------------------------------------------------"
38
+ url = @api.join_meeting_url(meeting_id, username, options[:moderatorPW])
39
+ puts "Please join the meeting as moderator using the link: #{url}"
40
+ puts "*** You will be using the DEFAULT config.xml ***"
41
+ puts "Waiting 30 seconds for you to join..."
42
+ puts
43
+ sleep(30)
44
+
45
+ puts "---------------------------------------------------"
46
+ puts "Creating a new config.xml"
47
+ # config_xml.set_attribute("layout", "showToolbar", "false", false)
48
+ config_xml.set_attribute("skinning", "enabled", "false", false)
49
+ config_xml.set_attribute("layout", "defaultLayout", "Webinar", false)
50
+ config_xml.set_attribute("layout", "showLayoutTools", "false", false)
51
+ config_xml.set_attribute("ChatModule", "privateEnabled", "false")
52
+ config_xml.set_attribute("VideoconfModule", "resolutions", "320x240")
53
+ config_xml.set_attribute("VideoconfModule", "presenterShareOnly", "true")
54
+
55
+ puts "---------------------------------------------------"
56
+ token = @api.set_config_xml(meeting_id, config_xml)
57
+ puts "Setting the new config.xml returned the token: #{token}"
58
+
59
+ puts "---------------------------------------------------"
60
+ url = @api.join_meeting_url(meeting_id, username2, options[:moderatorPW], { :configToken => token })
61
+ puts "Please join the meeting again using the link: #{url}"
62
+ puts "*** You will be using the MODIFIED config.xml, with the following modifications: ***"
63
+ puts "*** - Disabled layout (will show the default layout, as was used in BBB < 0.8)"
64
+ puts "*** - Default layout to Webinar"
65
+ puts "*** - Hidden layout tools"
66
+ puts "*** - Disabled private chat"
67
+ puts "*** - Restricted video resolutions to 320x240 only"
68
+ puts "*** - Disabled video sharing except for the presenter"
69
+ puts
70
+
71
+ rescue Exception => ex
72
+ puts "Failed with error #{ex.message}"
73
+ puts ex.backtrace
74
+ end
@@ -0,0 +1,29 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
3
+
4
+ require 'bigbluebutton_api'
5
+ require 'prepare'
6
+
7
+ begin
8
+ prepare
9
+
10
+ num = rand(1000)
11
+ meeting_name = "Test Meeting #{num}"
12
+ meeting_id = "test-meeting-#{num}"
13
+ moderator_name = "House"
14
+ attendee_name = "Cameron"
15
+ puts "---------------------------------------------------"
16
+ options = { :moderatorPW => "54321",
17
+ :attendeePW => "12345",
18
+ :welcome => 'Welcome to my meeting',
19
+ :dialNumber => '1-800-000-0000x00000#',
20
+ :logoutURL => 'https://github.com/mconf/bigbluebutton-api-ruby',
21
+ :maxParticipants => 25 }
22
+ response = @api.create_meeting(meeting_name, meeting_id, options)
23
+ puts "The meeting has been created with the response:"
24
+ puts response.inspect
25
+
26
+ rescue Exception => ex
27
+ puts "Failed with error #{ex.message}"
28
+ puts ex.backtrace
29
+ end
@@ -45,14 +45,6 @@ begin
45
45
  puts "Meeting info:"
46
46
  puts response.inspect
47
47
 
48
- puts
49
- puts
50
- puts
51
- puts "---------------------------------------------------"
52
- response = @api.join_meeting(meeting_id, attendee_name, options[:attendeePW])
53
- puts "Join meeting response:"
54
- puts response.inspect
55
-
56
48
  rescue Exception => ex
57
49
  puts "Failed with error #{ex.message}"
58
50
  puts ex.backtrace
@@ -10,12 +10,13 @@ timeout_ending: 30
10
10
  timeout_bot_start: 60
11
11
 
12
12
  servers:
13
- bbb-dev-07:
14
- salt: 'your-salt'
15
- url: 'http://your-server/bigbluebutton/api'
16
- version: '0.7'
17
- test-install-08:
13
+ test-install-081:
18
14
  salt: '8cd8ef52e8e101574e400365b55e11a6'
19
15
  url: 'http://test-install.blindsidenetworks.com/bigbluebutton/api'
16
+ version: '0.81'
17
+ mobile_salt: '03b07' # needed for >= 0.8
18
+ bbb-08:
19
+ salt: 'lka98f52e8akdlsoie400365b55e98s7'
20
+ url: 'http://yourserver.com/bigbluebutton/api'
20
21
  version: '0.8'
21
22
  mobile_salt: '03b07' # needed for >= 0.8
@@ -19,16 +19,7 @@ Feature: Create rooms
19
19
  When the create method is called with a duplicated meeting id
20
20
  Then the response is an error with the key "idNotUnique"
21
21
 
22
- @version-07 @need-bot
23
- Scenario: Try to recreate a previously ended meeting
24
- Given the create method is called
25
- # note: meeting needs to be running to be ended in 0.7
26
- And the meeting is running
27
- And the meeting is forcibly ended
28
- When the create method is called again with the same meeting id
29
- Then the response is an error with the key "idNotUnique"
30
-
31
- @version-08 @need-bot
22
+ @version-all @need-bot
32
23
  Scenario: Try to recreate a previously ended meeting
33
24
  Given the create method is called
34
25
  And the meeting is running
@@ -2,34 +2,16 @@ Feature: End rooms
2
2
  To stop a meeting using the API
3
3
  One needs to be able to call 'end' to this meeting
4
4
 
5
- @version-07 @need-bot
5
+ @version-all @need-bot
6
6
  Scenario: End a meeting
7
7
  Given that a meeting was created
8
8
  And the meeting is running
9
9
  When the method to end the meeting is called
10
10
  Then the response is successful and well formatted
11
11
  And the meeting should be ended
12
- And the information returned by get_meeting_info is correct
13
12
 
14
- @version-08 @need-bot
15
- Scenario: End a meeting
16
- Given that a meeting was created
17
- And the meeting is running
18
- When the method to end the meeting is called
19
- Then the response is successful and well formatted
20
- And the meeting should be ended
21
- # the meeting may not exist anymore in 0.8
22
-
23
- # in 0.7 ending a meeting that is not running generates an error
24
- @version-07
25
- Scenario: Try to end a meeting that is not running in 0.7
26
- Given that a meeting was created
27
- When the method to end the meeting is called
28
- Then the response is an error with the key "notFound"
29
-
30
- # in 0.8 ending a meeting that is not running is ok
31
- @version-08
32
- Scenario: Try to end a meeting that is not running in 0.8
13
+ @version-all
14
+ Scenario: Try to end a meeting that is not running
33
15
  Given that a meeting was created
34
16
  When the method to end the meeting is called
35
17
  Then the response is successful
@@ -1,4 +1,4 @@
1
- @version-08
1
+ @version-all
2
2
  Feature: Pre-upload slides
3
3
  To have presentations ready in the meeting when the users join
4
4
  One needs to pre-upload these presentations when the meeting is created
@@ -1,4 +1,4 @@
1
- @version-08
1
+ @version-all
2
2
  Feature: Record a meeting and manage recordings
3
3
  To record a meeting or manage the recorded meeting
4
4
  One needs be able to list the recordings, publish and unpublish them
@@ -37,7 +37,7 @@ module BigBlueButton
37
37
  else
38
38
  server = self.cfg['servers'].first[1]
39
39
  end
40
- server['version'] = '0.7' unless server.has_key?('version')
40
+ server['version'] = '0.81' unless server.has_key?('version')
41
41
  server
42
42
  end
43
43
 
@@ -3,10 +3,12 @@ require 'cgi'
3
3
  require 'rexml/document'
4
4
  require 'digest/sha1'
5
5
  require 'rubygems'
6
- require 'hash_to_xml'
6
+ require 'bigbluebutton_hash_to_xml'
7
7
  require 'bigbluebutton_exception'
8
8
  require 'bigbluebutton_formatter'
9
9
  require 'bigbluebutton_modules'
10
+ require 'bigbluebutton_config_xml'
11
+ require 'bigbluebutton_config_layout'
10
12
 
11
13
  module BigBlueButton
12
14
 
@@ -19,13 +21,14 @@ module BigBlueButton
19
21
  # 4. To force meeting to end, call end_meeting .
20
22
  #
21
23
  # Important info about the data returned by the methods:
22
- # * The XML returned by BBB is converted to a Hash. See individual method's documentation for examples.
24
+ # * The XML returned by BigBlueButton is converted to a BigBlueButton::BigBlueButtonHash. See each method's documentation
25
+ # for examples.
23
26
  # * Three values will *always* exist in the hash:
24
27
  # * :returncode (boolean)
25
28
  # * :messageKey (string)
26
29
  # * :message (string)
27
- # * Some of the values returned by BBB are converted to better represent the data. Some of these are listed
28
- # bellow. They will *always* have the type informed:
30
+ # * Some of the values returned by BigBlueButton are converted to better represent the data.
31
+ # Some of these are listed bellow. They will *always* have the type informed:
29
32
  # * :meetingID (string)
30
33
  # * :attendeePW (string)
31
34
  # * :moderatorPW (string)
@@ -33,6 +36,9 @@ module BigBlueButton
33
36
  # * :hasBeenForciblyEnded (boolean)
34
37
  # * :endTime and :startTime (DateTime or nil)
35
38
  #
39
+ # For more information about the API, see the documentation at:
40
+ # * http://code.google.com/p/bigbluebutton/wiki/API
41
+ #
36
42
  class BigBlueButtonApi
37
43
 
38
44
  # URL to a BigBlueButton server (e.g. http://demo.bigbluebutton.org/bigbluebutton/api)
@@ -41,7 +47,7 @@ module BigBlueButton
41
47
  # Secret salt for this server
42
48
  attr_accessor :salt
43
49
 
44
- # API version e.g. 0.7 (valid for 0.7, 0.71 and 0.71a)
50
+ # API version e.g. 0.81
45
51
  attr_accessor :version
46
52
 
47
53
  # Flag to turn on/off debug mode
@@ -60,9 +66,9 @@ module BigBlueButton
60
66
  # Initializes an instance
61
67
  # url:: URL to a BigBlueButton server (e.g. http://demo.bigbluebutton.org/bigbluebutton/api)
62
68
  # salt:: Secret salt for this server
63
- # version:: API version e.g. 0.7 (valid for 0.7, 0.71 and 0.71a)
64
- def initialize(url, salt, version='0.7', debug=false)
65
- @supported_versions = ['0.7', '0.8']
69
+ # version:: API version e.g. 0.81
70
+ def initialize(url, salt, version='0.81', debug=false)
71
+ @supported_versions = ['0.8', '0.81']
66
72
  @url = url
67
73
  @salt = salt
68
74
  @debug = debug
@@ -77,32 +83,37 @@ module BigBlueButton
77
83
  puts "BigBlueButtonAPI: Using version #{@version}" if @debug
78
84
  end
79
85
 
80
-
81
- #
82
- # API calls since 0.7
83
- #
84
-
85
-
86
- # Creates a new meeting. Returns the hash with the response or
87
- # throws BigBlueButtonException on failure.
86
+ # Creates a new meeting. Returns the hash with the response or throws BigBlueButtonException
87
+ # on failure.
88
88
  # meeting_name (string):: Name for the meeting
89
- # meeting_id (string, integer):: Unique identifier for the meeting
90
- # options (Hash):: Hash with optional parameters. The accepted parameters are:
91
- # moderatorPW (string, int), attendeePW (string, int), welcome (string),
89
+ # meeting_id (string):: Unique identifier for the meeting
90
+ # options (Hash):: Hash with additional parameters. The accepted parameters are:
91
+ # moderatorPW (string), attendeePW (string), welcome (string),
92
92
  # dialNumber (int), logoutURL (string), maxParticipants (int),
93
- # voiceBridge (int), record (boolean), duration (int) and "meta" parameters
94
- # (usually strings). If a parameter passed in the hash is not supported it will
95
- # simply be discarded. For details about each see BBB API docs.
93
+ # voiceBridge (int), record (boolean), duration (int), redirectClient (string),
94
+ # clientURL (string), and "meta" parameters (usually strings).
95
+ # For details about each see BigBlueButton's API docs.
96
+ # If you have a custom API with more parameters, you can simply pass them
97
+ # in this hash and they will be added to the API call.
96
98
  # modules (BigBlueButtonModules):: Configuration for the modules. The modules are sent as an xml and the
97
99
  # request will use an HTTP POST instead of GET. Currently only the
98
- # "presentation" module is available. Only used for version > 0.8.
100
+ # "presentation" module is available.
99
101
  # See usage examples below.
100
102
  #
101
103
  # === Example
102
104
  #
103
- # options = { :moderatorPW => "123", :attendeePW => "321", :welcome => "Welcome here!",
104
- # :dialNumber => 5190909090, :logoutURL => "http://mconf.org", :maxParticipants => 25,
105
- # :voiceBridge => 76543, :record => true, :duration => 0, :meta_category => "Remote Class" }
105
+ # options = {
106
+ # :attendeePW => "321",
107
+ # :moderatorPW => "123",
108
+ # :welcome => "Welcome here!",
109
+ # :dialNumber => 5190909090,
110
+ # :voiceBridge => 76543,
111
+ # :logoutURL => "http://mconf.org",
112
+ # :record => true,
113
+ # :duration => 0,
114
+ # :maxParticipants => 25,
115
+ # :meta_category => "Remote Class"
116
+ # }
106
117
  # create_meeting("My Meeting", "my-meeting", options)
107
118
  #
108
119
  # === Example with modules (see BigBlueButtonModules docs for more)
@@ -114,31 +125,32 @@ module BigBlueButton
114
125
  # modules.add_presentation(:base64, "JVBERi0xLjQKJ....[clipped here]....0CiUlRU9GCg==", "first-class.pdf")
115
126
  # create_meeting("My Meeting", "my-meeting", nil, modules)
116
127
  #
117
- # === Example response for 0.7
128
+ # === Example response for 0.81
118
129
  #
119
130
  # On successful creation:
120
131
  #
121
132
  # {
122
- # :returncode => true, :meetingID => "test",
123
- # :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => false,
124
- # :messageKey => "", :message => ""
133
+ # :returncode => true,
134
+ # :meetingID => "0c521f3d",
135
+ # :attendeePW => "12345",
136
+ # :moderatorPW => "54321",
137
+ # :createTime => 1389464535956,
138
+ # :hasBeenForciblyEnded => false,
139
+ # :messageKey => "",
140
+ # :message => ""
125
141
  # }
126
142
  #
127
- # Meeting that was forcibly ended:
143
+ # When creating a meeting that already exist:
128
144
  #
129
145
  # {
130
- # :returncode => true, :meetingID => "test",
131
- # :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => true,
132
- # :messageKey => "duplicateWarning",
133
- # :message => "This conference was already in existence and may currently be in progress."
134
- # }
135
- #
136
- # === Example response for 0.8
137
- #
138
- # {
139
- # :returncode => true, :meetingID => "Test", :createTime => 1308591802,
140
- # :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => false,
141
- # :messageKey => "", :message => ""
146
+ # :returncode => true,
147
+ # :meetingID => "7a1d614b",
148
+ # :attendeePW => "12345",
149
+ # :moderatorPW => "54321",
150
+ # :createTime => 1389464682402,
151
+ # :hasBeenForciblyEnded => false,
152
+ # :messageKey => "duplicateWarning",
153
+ # :message => "This conference was already in existence and may currently be in progress."
142
154
  # }
143
155
  #
144
156
  def create_meeting(meeting_name, meeting_id, options={}, modules=nil)
@@ -149,8 +161,8 @@ module BigBlueButton
149
161
  params[:record] = params[:record].to_s
150
162
  end
151
163
 
152
- # with modules we send a post request (only for >= 0.8)
153
- if modules and @version >= "0.8"
164
+ # with modules we send a post request
165
+ if modules
154
166
  response = send_api_request(:create, params, modules.to_xml)
155
167
  else
156
168
  response = send_api_request(:create, params)
@@ -161,112 +173,131 @@ module BigBlueButton
161
173
  formatter.to_string(:moderatorPW)
162
174
  formatter.to_string(:attendeePW)
163
175
  formatter.to_boolean(:hasBeenForciblyEnded)
164
- if @version >= "0.8"
165
- formatter.to_int(:createTime)
166
- end
176
+ formatter.to_int(:createTime)
167
177
 
168
178
  response
169
179
  end
170
180
 
171
181
  # Ends an existing meeting. Throws BigBlueButtonException on failure.
172
- # meeting_id (string, int):: Unique identifier for the meeting
173
- # moderator_password (string, int):: Moderator password
182
+ # meeting_id (string):: Unique identifier for the meeting
183
+ # moderator_password (string):: Moderator password
184
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
185
+ # parameters, but if you have a custom API with more parameters, you
186
+ # can simply pass them in this hash and they will be added to the API call.
174
187
  #
175
- # === Return examples (for 0.7)
188
+ # === Return examples (for 0.81)
176
189
  #
177
190
  # On success:
178
191
  #
179
192
  # {
180
- # :returncode=>true, :messageKey=>"sentEndMeetingRequest",
181
- # :message=>"A request to end the meeting was sent. Please wait a few seconds, and then use the getMeetingInfo
182
- # or isMeetingRunning API calls to verify that it was ended."
193
+ # :returncode=>true,
194
+ # :messageKey => "sentEndMeetingRequest",
195
+ # :message => "A request to end the meeting was sent. Please wait a few seconds, and then use the getMeetingInfo or isMeetingRunning API calls to verify that it was ended."
183
196
  # }
184
197
  #
185
- def end_meeting(meeting_id, moderator_password)
186
- send_api_request(:end, { :meetingID => meeting_id, :password => moderator_password } )
198
+ def end_meeting(meeting_id, moderator_password, options={})
199
+ params = { :meetingID => meeting_id, :password => moderator_password }.merge(options)
200
+ send_api_request(:end, params)
187
201
  end
188
202
 
189
- # Returns true or false as to whether meeting is open. A meeting is
190
- # only open after at least one participant has joined.
191
- # meeting_id (string, int):: Unique identifier for the meeting
192
- def is_meeting_running?(meeting_id)
193
- hash = send_api_request(:isMeetingRunning, { :meetingID => meeting_id } )
203
+ # Returns whether the meeting is running or not. A meeting is only running after at least
204
+ # one participant has joined. Returns true or false.
205
+ # meeting_id (string):: Unique identifier for the meeting
206
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
207
+ # parameters, but if you have a custom API with more parameters, you
208
+ # can simply pass them in this hash and they will be added to the API call.
209
+ def is_meeting_running?(meeting_id, options={})
210
+ params = { :meetingID => meeting_id }.merge(options)
211
+ hash = send_api_request(:isMeetingRunning, params)
194
212
  BigBlueButtonFormatter.new(hash).to_boolean(:running)
195
213
  end
196
214
 
197
- # Returns the url used to join the meeting
198
- # meeting_id (string, int):: Unique identifier for the meeting
199
- # user_name (string):: Name of the user
200
- # password (string):: Password for this meeting - used to set the user as moderator or attendee
201
- # options (Hash):: Hash with optional parameters. The accepted parameters are:
202
- # userID (string, int), webVoiceConf (string, int) and createTime (int).
203
- # For details about each see BBB API docs.
215
+ # Returns a string with the url used to join the meeting
216
+ # meeting_id (string):: Unique identifier for the meeting
217
+ # user_name (string):: Name of the user
218
+ # password (string):: Password for this meeting - will be used to decide if the user is a
219
+ # moderator or attendee
220
+ # options (Hash):: Hash with additional parameters. The accepted parameters are:
221
+ # userID (string), webVoiceConf (string), createTime (int),
222
+ # configToken (string), and avatarURL (string).
223
+ # For details about each see BigBlueButton's API docs.
224
+ # If you have a custom API with more parameters, you can simply pass them
225
+ # in this hash and they will be added to the API call.
204
226
  def join_meeting_url(meeting_id, user_name, password, options={})
205
227
  params = { :meetingID => meeting_id, :password => password, :fullName => user_name }.merge(options)
206
228
  get_url(:join, params)
207
229
  end
208
230
 
209
- # Warning: As of this version of the gem, this call does not work
210
- # (instead of returning XML response, it should join the meeting).
211
- #
212
- # Joins a user into the meeting using an API call, instead of
213
- # directing the user's browser to moderator_url or attendee_url
214
- # (note: this will still be required however to actually use bbb).
215
- # Returns the URL a user can use to enter this meeting.
216
- # meeting_id (string, int):: Unique identifier for the meeting
217
- # user_name (string):: Name of the user
218
- # password (string, int):: Moderator or attendee password for this meeting
219
- # options (Hash):: Hash with optional parameters. The accepted parameters are:
220
- # userID (string, int), webVoiceConf (string, int) and createTime (int).
221
- # For details about each see BBB API docs.
222
- def join_meeting(meeting_id, user_name, password, options={})
223
- params = { :meetingID => meeting_id, :password => password, :fullName => user_name }.merge(options)
224
- send_api_request(:join, params)
225
- end
226
-
227
- # Returns a hash object containing the meeting information.
228
- # See the API documentation for details on the return XML
229
- # (http://code.google.com/p/bigbluebutton/wiki/API).
231
+ # Returns a hash object containing the information of a meeting.
230
232
  #
231
- # meeting_id (string, int):: Unique identifier for the meeting
232
- # password (string, int):: Moderator password for this meeting
233
+ # meeting_id (string):: Unique identifier for the meeting
234
+ # password (string):: Moderator password for this meeting
235
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
236
+ # parameters, but if you have a custom API with more parameters, you
237
+ # can simply pass them in this hash and they will be added to the API call.
233
238
  #
234
- # === Example responses for 0.7
239
+ # === Example responses for 0.81
235
240
  #
236
- # With attendees:
241
+ # Running with attendees and metadata:
237
242
  #
238
- # {
239
- # :returncode=>true, :meetingID=>"bigbluebutton-api-ruby-test", :attendeePW=>"1234", :moderatorPW=>"4321", :running=>true,
240
- # :hasBeenForciblyEnded=>false, :startTime=>DateTime("Wed Apr 06 17:09:57 UTC 2011"), :endTime=>nil, :participantCount=>4, :moderatorCount=>2,
241
- # :attendees => [
242
- # {:userID=>"ndw1fnaev0rj", :fullName=>"House M.D.", :role=>:moderator},
243
- # {:userID=>"gn9e22b7ynna", :fullName=>"Dexter Morgan", :role=>:moderator},
244
- # {:userID=>"llzihbndryc3", :fullName=>"Cameron Palmer", :role=>:viewer},
245
- # {:userID=>"rbepbovolsxt", :fullName=>"Trinity", :role=>:viewer}
246
- # ], :messageKey=>"", :message=>""
247
- # }
248
- #
249
- # Without attendees (not started):
250
243
  #
251
244
  # {
252
- # :returncode=>true, :meetingID=>"bigbluebutton-api-ruby-test", :attendeePW=>"1234", :moderatorPW=>"4321", :running=>false,
253
- # :hasBeenForciblyEnded=>false, :startTime=>nil, :endTime=>nil, :participantCount=>0, :moderatorCount=>0,
254
- # :attendees=>[], :messageKey=>"", :message=>""
245
+ # :returncode => true,
246
+ # :meetingName => "e56ef2c5",
247
+ # :meetingID => "e56ef2c5",
248
+ # :createTime => 1389465592542,
249
+ # :voiceBridge => 72519,
250
+ # :dialNumber => "1-800-000-0000x00000#",
251
+ # :attendeePW => "12345",
252
+ # :moderatorPW => "54321",
253
+ # :running => true,
254
+ # :recording => false,
255
+ # :hasBeenForciblyEnded => false,
256
+ # :startTime => #<DateTime: 2014-01-11T16:39:58-02:00 ((2456669j,67198s,0n),-7200s,2299161j)>,
257
+ # :endTime => nil,
258
+ # :participantCount => 2,
259
+ # :maxUsers => 25,
260
+ # :moderatorCount => 1,
261
+ # :attendees => [
262
+ # { :userID => "wsfoiqtnugul", :fullName => "Cameron", :role => :viewer, :customdata => {} },
263
+ # { :userID => "qsaogaoqifjk", :fullName => "House", :role => :moderator, :customdata => {} }
264
+ # ],
265
+ # :metadata => {
266
+ # :category => "Testing",
267
+ # :anything => "Just trying it out"
268
+ # },
269
+ # :messageKey => "",
270
+ # :message => ""
255
271
  # }
256
272
  #
257
- # === Example responses for 0.8
273
+ # Created but not started yet:
258
274
  #
259
275
  # {
260
- # :returncode => true, :meetingName => "test", :meetingID => "test", :createTime => 1321906390524,
261
- # :voiceBridge => 72194, :attendeePW => "1234", :moderatorPW => "4321", :running => false, :recording => false,
262
- # :hasBeenForciblyEnded => false, :startTime => nil, :endTime => nil, :participantCount => 0, :maxUsers => 9,
263
- # :moderatorCount => 0, :attendees => [],
264
- # :metadata => { :two => "TWO", :one => "one" },
265
- # :messageKey => "", :message => ""
276
+ # :returncode => true,
277
+ # :meetingName => "fe3ea879",
278
+ # :meetingID => "fe3ea879",
279
+ # :createTime => 1389465320050,
280
+ # :voiceBridge => 79666,
281
+ # :dialNumber => "1-800-000-0000x00000#",
282
+ # :attendeePW => "12345",
283
+ # :moderatorPW => "54321",
284
+ # :running => false,
285
+ # :recording => false,
286
+ # :hasBeenForciblyEnded => false,
287
+ # :startTime => nil,
288
+ # :endTime => nil,
289
+ # :participantCount => 0,
290
+ # :maxUsers => 25,
291
+ # :moderatorCount => 0,
292
+ # :attendees => [],
293
+ # :metadata => {},
294
+ # :messageKey => "",
295
+ # :message => ""
266
296
  # }
267
297
  #
268
- def get_meeting_info(meeting_id, password)
269
- response = send_api_request(:getMeetingInfo, { :meetingID => meeting_id, :password => password } )
298
+ def get_meeting_info(meeting_id, password, options={})
299
+ params = { :meetingID => meeting_id, :password => password }.merge(options)
300
+ response = send_api_request(:getMeetingInfo, params)
270
301
 
271
302
  formatter = BigBlueButtonFormatter.new(response)
272
303
  formatter.flatten_objects(:attendees, :attendee)
@@ -281,38 +312,69 @@ module BigBlueButton
281
312
  formatter.to_datetime(:endTime)
282
313
  formatter.to_int(:participantCount)
283
314
  formatter.to_int(:moderatorCount)
284
- if @version >= "0.8"
285
- formatter.to_string(:meetingName)
286
- formatter.to_int(:maxUsers)
287
- formatter.to_int(:voiceBridge)
288
- formatter.to_int(:createTime)
289
- formatter.to_boolean(:recording)
290
- end
315
+ formatter.to_string(:meetingName)
316
+ formatter.to_int(:maxUsers)
317
+ formatter.to_int(:voiceBridge)
318
+ formatter.to_int(:createTime)
319
+ formatter.to_boolean(:recording)
291
320
 
292
321
  response
293
322
  end
294
323
 
295
- # Returns a hash object containing information about the meetings currently existent in the BBB
324
+ # Returns a hash object with information about all the meetings currently created in the
296
325
  # server, either they are running or not.
297
326
  #
298
- # === Example responses for 0.7
327
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
328
+ # parameters, but if you have a custom API with more parameters, you
329
+ # can simply pass them in this hash and they will be added to the API call.
330
+ #
331
+ # === Example responses for 0.81
299
332
  #
300
333
  # Server with one or more meetings:
301
334
  #
302
- # { :returncode => true,
335
+ # {
336
+ # :returncode => true,
303
337
  # :meetings => [
304
- # {:meetingID=>"Demo Meeting", :attendeePW=>"ap", :moderatorPW=>"mp", :hasBeenForciblyEnded=>false, :running=>true},
305
- # {:meetingID=>"I was ended Meeting", :attendeePW=>"pass", :moderatorPW=>"pass", :hasBeenForciblyEnded=>true, :running=>false}
338
+ # { :meetingID => "e66e88a3",
339
+ # :meetingName => "e66e88a3",
340
+ # :createTime => 1389466124414,
341
+ # :voiceBridge => 78730,
342
+ # :dialNumber=>"1-800-000-0000x00000#",
343
+ # :attendeePW => "12345",
344
+ # :moderatorPW => "54321",
345
+ # :hasBeenForciblyEnded => false,
346
+ # :running => false,
347
+ # :participantCount => 0,
348
+ # :listenerCount => 0,
349
+ # :videoCount => 0 }
350
+ # { :meetingID => "8f21cc63",
351
+ # :meetingName => "8f21cc63",
352
+ # :createTime => 1389466073245,
353
+ # :voiceBridge => 78992,
354
+ # :dialNumber => "1-800-000-0000x00000#",
355
+ # :attendeePW => "12345",
356
+ # :moderatorPW => "54321",
357
+ # :hasBeenForciblyEnded => false,
358
+ # :running => true,
359
+ # :participantCount => 2,
360
+ # :listenerCount => 0,
361
+ # :videoCount => 0 }
306
362
  # ],
307
- # :messageKey=>"", :message=>""
363
+ # :messageKey => "",
364
+ # :message => ""
308
365
  # }
309
366
  #
310
367
  # Server with no meetings:
311
368
  #
312
- # {:returncode=>true, :meetings=>[], :messageKey=>"noMeetings", :message=>"no meetings were found on this server"}
369
+ # {
370
+ # :returncode => true,
371
+ # :meetings => [],
372
+ # :messageKey => "noMeetings",
373
+ # :message => "no meetings were found on this server"
374
+ # }
313
375
  #
314
- def get_meetings
315
- response = send_api_request(:getMeetings, { :random => rand(9999999999) } )
376
+ def get_meetings(options={})
377
+ response = send_api_request(:getMeetings, options)
316
378
 
317
379
  formatter = BigBlueButtonFormatter.new(response)
318
380
  formatter.flatten_objects(:meetings, :meeting)
@@ -320,28 +382,30 @@ module BigBlueButton
320
382
  response
321
383
  end
322
384
 
323
- # Returns the API version (as string) of the associated server. This actually returns
324
- # the version returned by the BBB server, and not the version set by the user in
325
- # the initialization of this object.
385
+ # Returns the API version of the server as a string. Will return the version in the response
386
+ # given by the BigBlueButton server, and not the version set by the user in the initialization
387
+ # of this object!
326
388
  def get_api_version
327
389
  response = send_api_request(:index)
328
390
  response[:returncode] ? response[:version].to_s : ""
329
391
  end
330
392
 
331
393
 
332
-
333
394
  #
334
395
  # API calls since 0.8
335
396
  #
336
397
 
337
398
  # Retrieves the recordings that are available for playback for a given meetingID (or set of meeting IDs).
338
- # options (Hash):: Hash with optional parameters. The accepted parameters are:
339
- # :meetingID (string, Array). For details about each see BBB API docs.
340
- # Any of the following values are accepted for :meetingID :
341
- # :meetingID => "id1"
342
- # :meetingID => "id1,id2,id3"
343
- # :meetingID => ["id1"]
344
- # :meetingID => ["id1", "id2", "id3"]
399
+ # options (Hash):: Hash with additional parameters. The accepted parameters are:
400
+ # :meetingID (string, Array). For details about each see BigBlueButton's
401
+ # API docs.
402
+ # Any of the following values are accepted for :meetingID :
403
+ # :meetingID => "id1"
404
+ # :meetingID => "id1,id2,id3"
405
+ # :meetingID => ["id1"]
406
+ # :meetingID => ["id1", "id2", "id3"]
407
+ # If you have a custom API with more parameters, you can simply pass them
408
+ # in this hash and they will be added to the API call.
345
409
  #
346
410
  # === Example responses
347
411
  #
@@ -349,7 +413,7 @@ module BigBlueButton
349
413
  # :recordings => [
350
414
  # {
351
415
  # :recordID => "7f5745a08b24fa27551e7a065849dda3ce65dd32-1321618219268",
352
- # :meetingID=>"bd1811beecd20f24314819a52ec202bf446ab94b",
416
+ # :meetingID => "bd1811beecd20f24314819a52ec202bf446ab94b",
353
417
  # :name => "Evening Class1",
354
418
  # :published => true,
355
419
  # :startTime => #<DateTime: 2011-11-18T12:10:23+00:00 (212188378223/86400,0/1,2299161)>,
@@ -370,16 +434,26 @@ module BigBlueButton
370
434
  # ]
371
435
  # }
372
436
  # },
373
- # { :recordID => "183f0bf3a0982a127bdb8161-13085974450", :meetingID => "CS102",
374
- # ...
375
- # ...
437
+ # { :recordID => "1254kakap98sd09jk2lk2-1329872486234",
438
+ # :recordID => "7f5745a08b24fa27551e7a065849dda3ce65dd32-1321618219268",
439
+ # :meetingID => "bklajsdoiajs9d8jo23id90",
440
+ # :name => "Evening Class2",
441
+ # :published => false,
442
+ # :startTime => #<DateTime: 2011-11-18T12:10:23+00:00 (212188378223/86400,0/1,2299161)>,
443
+ # :endTime => #<DateTime: 2011-11-18T12:12:25+00:00 (42437675669/17280,0/1,2299161)>,
444
+ # :metadata => {},
445
+ # :playback => {
446
+ # :format => { # notice that this is now a hash, not an array
447
+ # :type => "slides",
448
+ # :url => "http://test-install.blindsidenetworks.com/playback/slides/playback.html?meetingId=1254kakap98sd09jk2lk2-1329872486234",
449
+ # :length => 64
450
+ # }
451
+ # }
376
452
  # }
377
453
  # ]
378
454
  # }
379
455
  #
380
456
  def get_recordings(options={})
381
- raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"
382
-
383
457
  # ["id1", "id2", "id3"] becomes "id1,id2,id3"
384
458
  if options.has_key?(:meetingID)
385
459
  options[:meetingID] = options[:meetingID].join(",") if options[:meetingID].instance_of?(Array)
@@ -400,17 +474,19 @@ module BigBlueButton
400
474
  # "id1,id2,id3"
401
475
  # ["id1"]
402
476
  # ["id1", "id2", "id3"]
403
- # publish (boolean):: Publish or unpublish the recordings?
477
+ # publish (boolean):: Whether to publish or unpublish the recording(s)
478
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
479
+ # parameters, but if you have a custom API with more parameters, you
480
+ # can simply pass them in this hash and they will be added to the API call.
404
481
  #
405
482
  # === Example responses
406
483
  #
407
484
  # { :returncode => true, :published => true }
408
485
  #
409
- def publish_recordings(recordIDs, publish)
410
- raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"
411
-
486
+ def publish_recordings(recordIDs, publish, options={})
412
487
  recordIDs = recordIDs.join(",") if recordIDs.instance_of?(Array) # ["id1", "id2"] becomes "id1,id2"
413
- send_api_request(:publishRecordings, { :recordID => recordIDs, :publish => publish.to_s })
488
+ params = { :recordID => recordIDs, :publish => publish.to_s }.merge(options)
489
+ send_api_request(:publishRecordings, params)
414
490
  end
415
491
 
416
492
  # Delete one or more recordings for a given recordID (or set of record IDs).
@@ -420,16 +496,69 @@ module BigBlueButton
420
496
  # "id1,id2,id3"
421
497
  # ["id1"]
422
498
  # ["id1", "id2", "id3"]
499
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
500
+ # parameters, but if you have a custom API with more parameters, you
501
+ # can simply pass them in this hash and they will be added to the API call.
423
502
  #
424
503
  # === Example responses
425
504
  #
426
505
  # { :returncode => true, :deleted => true }
427
506
  #
428
- def delete_recordings(recordIDs)
429
- raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"
430
-
507
+ def delete_recordings(recordIDs, options={})
431
508
  recordIDs = recordIDs.join(",") if recordIDs.instance_of?(Array) # ["id1", "id2"] becomes "id1,id2"
432
- send_api_request(:deleteRecordings, { :recordID => recordIDs })
509
+ params = { :recordID => recordIDs }.merge(options)
510
+ send_api_request(:deleteRecordings, params)
511
+ end
512
+
513
+
514
+ #
515
+ # API calls since 0.81
516
+ #
517
+
518
+ # Retrieves the default config.xml file from the server.
519
+ # Returns the XML as a string by default, but if `asObject` is set to true, returns the XML
520
+ # parsed as an XmlSimple object ().
521
+ # asObject (Hash):: If true, returns the XML parsed as an XmlSimple object, using:
522
+ # data = XmlSimple.xml_in(response, { 'ForceArray' => false, 'KeepRoot' => true })
523
+ # You can then parse it back into an XML string using:
524
+ # XmlSimple.xml_out(data, { 'RootName' => nil, 'XmlDeclaration' => true })
525
+ # If set to false, returns the XML as a string.
526
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
527
+ # parameters, but if you have a custom API with more parameters, you
528
+ # can simply pass them in this hash and they will be added to the API call.
529
+ def get_default_config_xml(asObject=false, options={})
530
+ response = send_api_request(:getDefaultConfigXML, options, nil, true)
531
+ if asObject
532
+ XmlSimple.xml_in(response, { 'ForceArray' => false, 'KeepRoot' => true })
533
+ else
534
+ response
535
+ end
536
+ end
537
+
538
+ # Sets a config.xml file in the server.
539
+ # Returns the token returned by the server (that can be later used in a 'join' call) in case
540
+ # of success.
541
+ # meeting_id (string):: The ID of the meeting where this config.xml will be used.
542
+ # xml (string|BigBlueButtonConfigXml):: The XML that should be sent as a config.xml.
543
+ # It will usually be an edited output of the default config.xml:
544
+ # xml = api.get_default_config_xml
545
+ # Or you can use directly a BigBlueButtonConfigXml object:
546
+ # BigBlueButtonConfigXml.new(xml)
547
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
548
+ # parameters, but if you have a custom API with more parameters, you
549
+ # can simply pass them in this hash and they will be added to the API call.
550
+ # TODO: Right now we are sending the configXML parameters in the URL and in the body of the POST
551
+ # request. It works if left only in the URL, but the documentation of the API claims that it has
552
+ # to be in the body of the request. So it's no clear yet and this might change in the future.
553
+ def set_config_xml(meeting_id, xml, options={})
554
+ if xml.instance_of?(BigBlueButton::BigBlueButtonConfigXml)
555
+ data = xml.as_string
556
+ else
557
+ data = xml
558
+ end
559
+ params = { :meetingID => meeting_id, :configXML => data }.merge(options)
560
+ response = send_api_request(:setConfigXML, params, data)
561
+ response[:configToken]
433
562
  end
434
563
 
435
564
 
@@ -437,6 +566,32 @@ module BigBlueButton
437
566
  # Helper functions
438
567
  #
439
568
 
569
+ # Returns an array with the name of all layouts available in the server.
570
+ # Will fetch the config.xml file (unless passed in the arguments), fetch the
571
+ # layout definition file, and return the layouts.
572
+ # If something goes wrong, returns nil. Otherwise returns the list of layout
573
+ # names or an empty array if there's no layout defined.
574
+ def get_available_layouts(config_xml=nil)
575
+ config_xml = get_default_config_xml if config_xml.nil?
576
+ config_xml = BigBlueButton::BigBlueButtonConfigXml.new(config_xml)
577
+ layout_config = config_xml.get_attribute("LayoutModule", "layoutConfig", true)
578
+ unless layout_config.nil?
579
+ response = send_request(layout_config)
580
+ layout_config = BigBlueButton::BigBlueButtonConfigLayout.new(response.body)
581
+ layout_config.get_available_layouts
582
+ else
583
+ nil
584
+ end
585
+ end
586
+
587
+ # Returns an array with the layouts that exist by default in a BigBlueButton
588
+ # server. If you want to query the server to get a real list of layouts, use
589
+ # <tt>get_available_layouts</tt>.
590
+ def get_default_layouts
591
+ # this is the list for BigBlueButton 0.81
592
+ ["Default", "Video Chat", "Meeting", "Webinar", "Lecture assistant", "Lecture"]
593
+ end
594
+
440
595
  # Make a simple request to the server to test the connection.
441
596
  def test_connection
442
597
  response = send_api_request(:index)
@@ -474,6 +629,10 @@ module BigBlueButton
474
629
 
475
630
  # stringify and escape all params
476
631
  params.delete_if { |k, v| v.nil? } unless params.nil?
632
+ # some API calls require the params to be sorted
633
+ # first make all keys symbols, so the comparison works
634
+ params = params.inject({}){ |memo,(k,v)| memo[k.to_sym] = v; memo }
635
+ params = Hash[params.sort]
477
636
  params_string = ""
478
637
  params_string = params.map{ |k,v| "#{k}=" + CGI::escape(v.to_s) unless k.nil? || v.nil? }.join("&")
479
638
 
@@ -498,32 +657,39 @@ module BigBlueButton
498
657
  # params (Hash):: The parameters to be passed in the URL
499
658
  # data (string):: Data to be sent with the request. If set, the request will use an HTTP
500
659
  # POST instead of a GET and the data will be sent in the request body.
501
- def send_api_request(method, params={}, data=nil)
660
+ # raw (boolean):: If true, returns the data as it was received. Will not parse it into a Hash,
661
+ # check for errors or throw exceptions.
662
+ def send_api_request(method, params={}, data=nil, raw=false)
502
663
  url = get_url(method, params)
503
664
 
504
665
  @http_response = send_request(url, data)
505
- return { } if @http_response.body.empty?
506
-
507
- # 'Hashify' the XML
666
+ return {} if @http_response.body.empty?
508
667
  @xml_response = @http_response.body
509
- hash = Hash.from_xml(@xml_response)
510
668
 
511
- # simple validation of the xml body
512
- unless hash.has_key?(:returncode)
513
- raise BigBlueButtonException.new("Invalid response body. Is the API URL correct? \"#{@url}\", version #{@version}")
514
- end
669
+ if raw
670
+ result = @xml_response
671
+ else
515
672
 
516
- # default cleanup in the response
517
- hash = BigBlueButtonFormatter.new(hash).default_formatting
673
+ # 'Hashify' the XML
674
+ result = BigBlueButtonHash.from_xml(@xml_response)
518
675
 
519
- # if the return code is an error generates an exception
520
- unless hash[:returncode]
521
- exception = BigBlueButtonException.new(hash[:message])
522
- exception.key = hash.has_key?(:messageKey) ? hash[:messageKey] : ""
523
- raise exception
676
+ # simple validation of the xml body
677
+ unless result.has_key?(:returncode)
678
+ raise BigBlueButtonException.new("Invalid response body. Is the API URL correct? \"#{@url}\", version #{@version}")
679
+ end
680
+
681
+ # default cleanup in the response
682
+ result = BigBlueButtonFormatter.new(result).default_formatting
683
+
684
+ # if the return code is an error generates an exception
685
+ unless result[:returncode]
686
+ exception = BigBlueButtonException.new(result[:message])
687
+ exception.key = result.has_key?(:messageKey) ? result[:messageKey] : ""
688
+ raise exception
689
+ end
524
690
  end
525
691
 
526
- hash
692
+ result
527
693
  end
528
694
 
529
695
  protected