bigbluebutton_rails 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +6 -0
- data/Gemfile.lock +1 -1
- data/README.rdoc +45 -43
- data/app/controllers/bigbluebutton/rooms_controller.rb +3 -3
- data/app/models/bigbluebutton_room.rb +13 -1
- data/app/models/bigbluebutton_server.rb +14 -6
- data/bigbluebutton_rails.gemspec +2 -2
- data/lib/bigbluebutton_rails/rails/routes.rb +14 -20
- data/lib/bigbluebutton_rails/version.rb +1 -1
- data/lib/bigbluebutton_rails.rb +13 -0
- data/lib/classes/bigbluebutton_attendee.rb +1 -1
- data/lib/generators/bigbluebutton_rails/templates/migration.rb +1 -0
- data/spec/models/bigbluebutton_room_spec.rb +83 -8
- data/spec/models/bigbluebutton_server_spec.rb +11 -3
- data/spec/rails_app/app/controllers/custom_rooms_controller.rb +8 -0
- data/spec/rails_app/app/controllers/custom_servers_controller.rb +8 -0
- data/spec/rails_app/config/routes.rb +3 -0
- data/spec/routing/bigbluebutton/custom_controllers_routing_spec.rb +87 -0
- data/spec/routing/bigbluebutton/servers_routing_spec.rb +33 -28
- metadata +25 -21
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 0.0.4
|
2
|
+
|
3
|
+
* A random voice_bridge with 5 digits (recommended) is set when a room is created.
|
4
|
+
* Routes generators now allow specifying custom controllers instead of the defaults Bigbluebutton::ServersController and Bigbluebutton::RoomsController.
|
5
|
+
* Some bug fixes (including fixes for ruby 1.8).
|
6
|
+
|
1
7
|
== 0.0.3
|
2
8
|
|
3
9
|
* Rooms can be public or private
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -7,18 +7,22 @@ Features:
|
|
7
7
|
* Full API access using bigbluebutton-api-ruby (https://github.com/mconf/bigbluebutton-api-ruby)
|
8
8
|
* Easy way to join conferences: simply create a room and call the "join" action
|
9
9
|
* Easy integration with authentication and authorization mechanisms, such as Devise and CanCan
|
10
|
+
* Possibility to create private rooms, that require a password to join
|
11
|
+
* Deals with visitors (users that are not logged), allowing (or forbidding) them to join rooms
|
12
|
+
* Random meeting IDs to avoid problems with end_meeting, timeouts and reuse of URLs
|
10
13
|
|
11
|
-
|
12
|
-
* Private room and invitations to allow visitants to join conferences (using a password or not).
|
14
|
+
Planned features:
|
13
15
|
* Friendly URLs (e.g. http://somewhere.com/my-server/my-room)
|
14
|
-
*
|
16
|
+
* Limit the number of users per room and rooms per server
|
15
17
|
* Server administration (modify config.xml, use bbb-conf, etc.)
|
18
|
+
* Load balancing
|
19
|
+
* Dealing with rooms that exist in the BigBlueButton server but not in the DB
|
16
20
|
|
17
21
|
For more future features and issues check {our google code page}[http://code.google.com/p/mconf/issues/list?can=2&q=label%3AComponent%20label%3ABigBlueButtonRails].
|
18
22
|
|
19
23
|
== Installation
|
20
24
|
|
21
|
-
You can install the latest version of
|
25
|
+
You can install the latest version of BigbluebuttonRails using RubyGems:
|
22
26
|
|
23
27
|
gem install bigbluebutton_rails
|
24
28
|
|
@@ -31,24 +35,13 @@ After installing, you need to run the generator:
|
|
31
35
|
rails generate bigbluebutton_rails:install
|
32
36
|
|
33
37
|
This generator will create a migration file and a locale file in your application directories.
|
34
|
-
Take a look at the migration to see how the models used by
|
38
|
+
Take a look at the migration to see how the models used by BigbluebuttonRails look like.
|
35
39
|
|
36
|
-
|
37
|
-
There is one generator to help you with that:
|
38
|
-
|
39
|
-
rails generate bigbluebutton_rails:views
|
40
|
-
|
41
|
-
It copies all bigbluebutton_rails views into your application, so you can customize them as you wish.
|
42
|
-
|
43
|
-
There is yet another generator that copies the public files (javascripts, images and stylesheets) used by bigbluebutton_rails:
|
44
|
-
|
45
|
-
rails generate bigbluebutton_rails:public
|
46
|
-
|
47
|
-
For more information see the section Dependencies below.
|
40
|
+
To now more about the generators see {How to: Generators}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Generators]
|
48
41
|
|
49
42
|
=== Routes
|
50
43
|
|
51
|
-
The routes to
|
44
|
+
The routes to BigbluebuttonRails can be generated with the helper <tt>bigbluebutton_routes</tt>. See the example below:
|
52
45
|
|
53
46
|
bigbluebutton_routes :default
|
54
47
|
|
@@ -63,42 +56,49 @@ The first line generates the default routes. You need to call it at least once t
|
|
63
56
|
|
64
57
|
bigbluebutton_routes :default
|
65
58
|
|
66
|
-
|
59
|
+
It generates routes scoped with 'bigbluebutton'. These routes look like:
|
60
|
+
|
61
|
+
/bigbluebutton/servers
|
62
|
+
/bigbluebutton/servers/1/rooms/2
|
63
|
+
/bigbluebutton/servers/2/rooms/3/join
|
64
|
+
|
65
|
+
You can customize the scope name and also make the routes point to custom controllers.
|
66
|
+
|
67
|
+
bigbluebutton_routes :default, :scope => 'webconference', :controllers => { :servers => 'custom_servers', :rooms => 'custom_rooms' }
|
68
|
+
bigbluebutton_routes :default, :scope => '' # to remove the scope
|
69
|
+
|
70
|
+
If you customize the controllers as in the first line in the example above, be warned that every route generated after this will
|
71
|
+
be using these controllers!
|
72
|
+
|
73
|
+
You may also want shorter routes to access conference rooms. For that, use the option <tt>room_matchers</tt>:
|
67
74
|
|
68
75
|
bigbluebutton_routes :room_matchers
|
69
76
|
|
70
|
-
It creates routes to the actions "show", "running", "end", and "
|
77
|
+
It creates routes to the actions used to access the conference room: "show", "join", "auth", "running", "end", and "invite".
|
71
78
|
So you can allow access to webconference rooms using URLs such as:
|
72
79
|
|
73
80
|
http://myserver.com/user-10/room-5/join
|
74
81
|
http://myserver.com/zaphod/public-room/join
|
75
82
|
|
76
|
-
Obs:
|
83
|
+
Obs: BigbluebuttonRails does not allows the room access using IDs such as "room-5" or "public-room" yet, but soon you it will.
|
77
84
|
|
78
85
|
=== User authorization, permissions and assumptions
|
79
86
|
|
80
|
-
There are some basic assumptions made by
|
87
|
+
There are some basic assumptions made by BigbluebuttonRails:
|
81
88
|
|
82
89
|
* You have a method called <tt>current_user</tt> that returns the current user;
|
83
90
|
* The <tt>current_user</tt> has an attribute or method called "name" that returns his/her fullname.
|
84
91
|
|
85
92
|
If you don't, you can change this behaviour easily, keep reading.
|
86
93
|
|
87
|
-
|
88
|
-
user has in the <tt>room</tt>, respectively. These methods are defined in
|
89
|
-
application controller to change their behaviour.
|
90
|
-
|
91
|
-
Although this is the general rule, the permission checking is different for public or private rooms. Check the <tt>How it Works</tt>
|
92
|
-
section below for more details.
|
93
|
-
|
94
|
-
|
95
|
-
==== Integration with Devise
|
96
|
-
|
97
|
-
To be written...
|
94
|
+
BigbluebuttonRails uses the methods <tt>bigbluebutton_user</tt> and <tt>bigbluebutton_role(room)</tt> to get the current user and to get the permission that the current
|
95
|
+
user has in the <tt>room</tt>, respectively. These methods are defined in {lib/bigbluebutton_rails/controller_methods.rb}[https://github.com/mconf/bigbluebutton_rails/blob/master/lib/bigbluebutton_rails/controller_methods.rb]
|
96
|
+
and you can reimplement them in your application controller to change their behaviour.
|
98
97
|
|
99
|
-
====
|
98
|
+
==== See also
|
100
99
|
|
101
|
-
|
100
|
+
* {How to: Integrate with Devise}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Integrate-with-Devise]
|
101
|
+
* {How to: Integrate with CanCan}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Integrate-with-CanCan]
|
102
102
|
|
103
103
|
=== Dependencies
|
104
104
|
|
@@ -119,7 +119,7 @@ JQuery is used in the views <tt>join_wait</tt> and <tt>invite</tt> and can be co
|
|
119
119
|
|
120
120
|
=== Overview
|
121
121
|
|
122
|
-
|
122
|
+
BigbluebuttonRails has two entities: servers and rooms. Servers can have multiple rooms, that belong to a server and can also belong to any other model.
|
123
123
|
You can make a room belong to a user, for example.
|
124
124
|
|
125
125
|
Every server has an associated API object (using the gem bigbluebutton-api-ruby) used to access the BigBlueButton server.
|
@@ -130,7 +130,7 @@ These extra actions will be explained bellow.
|
|
130
130
|
|
131
131
|
A room model has methods to fetch and send information to the BBB server. They are simple API calls, but the "fetch" methods check the response and store
|
132
132
|
data from it, while the "send" methods just make the API call. You can, for example, use <tt>fetch_meeting_info</tt> to get information about the meeting
|
133
|
-
(will trigger the API call <tt>getMeetingInfo</tt>). The data parsed from the response wil be stored in the model and can be accessed using it's attributes.
|
133
|
+
(will trigger the API call <tt>getMeetingInfo</tt>). The data parsed from the response wil be stored in the model and can be accessed using it's attributes.
|
134
134
|
|
135
135
|
All methods in the models that trigger any API call are documented with "Triggers API call" and the API functions that are called. Be aware that they
|
136
136
|
can throw a BigBlueButtonException.
|
@@ -148,9 +148,11 @@ the user. Basic differences:
|
|
148
148
|
|
149
149
|
* <tt>invite</tt> renders a view to ask for a user name and a password. It is used to enable <b>anonymous users</b> to join a room or
|
150
150
|
to define the user role using the <b>room password</b> instead of the <tt>bigbluebutton_role</tt> method.
|
151
|
-
* It first checks <tt>bigbluebutton_role</tt> to see if the current user already has a role in the target room.
|
152
|
-
|
153
|
-
*
|
151
|
+
* It first checks <tt>bigbluebutton_role</tt> to see if the current user already has a role in the target room.
|
152
|
+
* In case it has (see {controller_methods.rb}[https://github.com/mconf/bigbluebutton_rails/blob/master/lib/bigbluebutton_rails/controller_methods.rb] for more info), redirects to <tt>join</tt>.
|
153
|
+
* Otherwise:
|
154
|
+
* If there is a user logged, uses <tt>bigbluebutton_user().name</tt> as the user name. Otherwise, ask the user to type a name.
|
155
|
+
* <tt>join</tt> requires a <b>logged user</b> and uses <tt>bigbluebutton_role</tt> to get the role for this user
|
154
156
|
* It redirects the user straight to the meeting if the join is successful.
|
155
157
|
* In case there's no role associated with the current user, falls back to <tt>invite</tt> to ask for a password.
|
156
158
|
|
@@ -159,11 +161,11 @@ Internally, they use the same algorithm:
|
|
159
161
|
* If the user is a moderator:
|
160
162
|
* If the room is not created yet, creates it.
|
161
163
|
* Redirects the user to the meeting as a moderator.
|
162
|
-
* If the user is a normal attendee:
|
164
|
+
* If the user is not a moderator (a normal attendee):
|
163
165
|
* If the meeting is running, redirects the user to the meeting as an attendee.
|
164
166
|
* Otherwise:
|
165
|
-
* <tt>join</tt> redirects to <tt>join_wait</tt>, to wait for a moderator before joining the conference.
|
166
|
-
* <tt>invite</tt> renders the invite view again and shows a warning that the
|
167
|
+
* <tt>join</tt> redirects to <tt>join_wait</tt>, to wait for a moderator before joining the conference. The page will continuously pool the server to check if the meeting is running. When it starts, it redirects the user to the conference.
|
168
|
+
* <tt>invite</tt> renders the invite view again and shows a warning informing that the meeting is not running. The user must re-submit the form to try again.
|
167
169
|
|
168
170
|
== Development
|
169
171
|
|
@@ -26,7 +26,7 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
26
26
|
def create
|
27
27
|
@room = BigbluebuttonRoom.new(params[:bigbluebutton_room])
|
28
28
|
@room.server = @server
|
29
|
-
|
29
|
+
|
30
30
|
# TODO Generate a random meetingid everytime a room is created
|
31
31
|
if !params[:bigbluebutton_room].has_key?(:meetingid) or
|
32
32
|
params[:bigbluebutton_room][:meetingid].blank?
|
@@ -152,9 +152,9 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
152
152
|
@room.fetch_is_running?
|
153
153
|
rescue BigBlueButton::BigBlueButtonException => e
|
154
154
|
flash[:error] = e.to_s
|
155
|
-
render :json => { running
|
155
|
+
render :json => { :running => "false", :error => "#{e.to_s}" }
|
156
156
|
else
|
157
|
-
render :json => { running
|
157
|
+
render :json => { :running => "#{@room.is_running?}" }
|
158
158
|
end
|
159
159
|
|
160
160
|
end
|
@@ -12,6 +12,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
12
12
|
validates :welcome_msg, :length => { :maximum => 250 }
|
13
13
|
validates :private, :inclusion => { :in => [true, false] }
|
14
14
|
validates :randomize_meetingid, :inclusion => { :in => [true, false] }
|
15
|
+
validates :voice_bridge, :presence => true, :uniqueness => true
|
15
16
|
|
16
17
|
# Passwords are 16 character strings
|
17
18
|
# See http://groups.google.com/group/bigbluebutton-dev/browse_thread/thread/9be5aae1648bcab?pli=1
|
@@ -62,7 +63,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
62
63
|
response[:attendees].each do |att|
|
63
64
|
attendee = BigbluebuttonAttendee.new
|
64
65
|
attendee.from_hash(att)
|
65
|
-
@attendees << attendee
|
66
|
+
@attendees << attendee
|
66
67
|
end
|
67
68
|
|
68
69
|
response
|
@@ -158,6 +159,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
158
159
|
|
159
160
|
def init
|
160
161
|
self[:meetingid] ||= random_meetingid
|
162
|
+
self[:voice_bridge] ||= random_voice_bridge
|
161
163
|
|
162
164
|
# fetched attributes
|
163
165
|
@participant_count = 0
|
@@ -179,6 +181,16 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
179
181
|
end
|
180
182
|
end
|
181
183
|
|
184
|
+
def random_voice_bridge
|
185
|
+
value = (70000 + ActiveSupport::SecureRandom.random_number(9999)).to_s
|
186
|
+
count = 0
|
187
|
+
while not BigbluebuttonRoom.find_by_voice_bridge(value).nil? and count < 10
|
188
|
+
count += 1
|
189
|
+
value = (70000 + ActiveSupport::SecureRandom.random_number(9999)).to_s
|
190
|
+
end
|
191
|
+
value
|
192
|
+
end
|
193
|
+
|
182
194
|
def do_create_meeting
|
183
195
|
self.server.api.create_meeting(self.name, self.meetingid, self.moderator_password,
|
184
196
|
self.attendee_password, self.welcome_msg, self.dial_number,
|
@@ -14,6 +14,11 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
14
14
|
|
15
15
|
validates :version, :presence => true, :inclusion => { :in => ['0.64', '0.7'] }
|
16
16
|
|
17
|
+
# Array of <tt>BigbluebuttonMeeting</tt>
|
18
|
+
attr_reader :meetings
|
19
|
+
|
20
|
+
after_initialize :init
|
21
|
+
|
17
22
|
# Returns the API object (<tt>BigBlueButton::BigBlueButtonAPI</tt> defined in
|
18
23
|
# <tt>bigbluebutton-api-ruby</tt>) associated with this server.
|
19
24
|
def api
|
@@ -24,9 +29,6 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
24
29
|
@api
|
25
30
|
end
|
26
31
|
|
27
|
-
# Array of <tt>BigbluebuttonMeeting</tt>
|
28
|
-
attr_reader :meetings
|
29
|
-
|
30
32
|
# Fetches the meetings currently created in the server (running or not).
|
31
33
|
#
|
32
34
|
# Using the response, updates <tt>meetings</tt> with a list of <tt>BigbluebuttonMeeting</tt>
|
@@ -41,9 +43,8 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
41
43
|
response[:meetings].each do |attr|
|
42
44
|
room = BigbluebuttonRoom.find_by_server_id_and_meetingid(self.id, attr[:meetingID])
|
43
45
|
if room.nil?
|
44
|
-
room = BigbluebuttonRoom.new(:server => self, :meetingid => attr[:meetingID],
|
45
|
-
:attendee_password => attr[:attendeePW],
|
46
|
-
:moderator_password => attr[:moderatorPW])
|
46
|
+
room = BigbluebuttonRoom.new(:server => self, :meetingid => attr[:meetingID], :name => attr[:meetingID],
|
47
|
+
:attendee_password => attr[:attendeePW], :moderator_password => attr[:moderatorPW])
|
47
48
|
room.running = attr[:running]
|
48
49
|
else
|
49
50
|
room.update_attributes(:attendee_password => attr[:attendeePW],
|
@@ -55,4 +56,11 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
59
|
+
protected
|
60
|
+
|
61
|
+
def init
|
62
|
+
# fetched attributes
|
63
|
+
@meetings = []
|
64
|
+
end
|
65
|
+
|
58
66
|
end
|
data/bigbluebutton_rails.gemspec
CHANGED
@@ -4,11 +4,11 @@ require "bigbluebutton_rails/version"
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "bigbluebutton_rails"
|
6
6
|
s.version = BigbluebuttonRails::VERSION.dup
|
7
|
-
s.platform = Gem::Platform::RUBY
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
8
|
s.summary = "BigBlueButton integration for Ruby on Rails"
|
9
9
|
s.email = "mconf@googlegroups.com"
|
10
10
|
s.homepage = "http://github.com/mconf/bigbluebutton_rails"
|
11
|
-
s.description = "BigBlueButton
|
11
|
+
s.description = "It allows you to interact with a BigBlueButton server from your Ruby on Rails web application"
|
12
12
|
s.authors = ['Leonardo Crauss Daronco']
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
@@ -28,21 +28,14 @@ module ActionDispatch::Routing
|
|
28
28
|
# running_bigbluebutton_server_room GET /bigbluebutton/servers/:server_id/rooms/:id/running(.:format)
|
29
29
|
# { :action=>"running", :controller=>"bigbluebutton/rooms" }
|
30
30
|
#
|
31
|
-
# The
|
32
|
-
#
|
31
|
+
# The routes point by default to the controllers Bigbluebutton::ServersController and Bigbluebutton::RoomsController
|
32
|
+
# and the the routes are scoped (namespaced) with 'bigbluebutton'. You can change the namespace with:
|
33
33
|
#
|
34
34
|
# bigbluebutton_routes :default, :scope => "webconference"
|
35
35
|
#
|
36
|
-
#
|
36
|
+
# You can also change the controllers with:
|
37
37
|
#
|
38
|
-
#
|
39
|
-
# { :action=>"show", :controller=>"bigbluebutton/servers" }
|
40
|
-
# POST /webconference/servers/:id(.:format)
|
41
|
-
# { :action=>"update", :controller=>"bigbluebutton/servers" }
|
42
|
-
# join_webconference_server_room GET /webconference/servers/:server_id/rooms/:id/join(.:format)
|
43
|
-
# { :action=>"join", :controller=>"bigbluebutton/rooms" }
|
44
|
-
# running_webconference_server_room GET /webconference/servers/:server_id/rooms/:id/running(.:format)
|
45
|
-
# { :action=>"running", :controller=>"bigbluebutton/rooms" }
|
38
|
+
# bigbluebutton_routes :default, :controllers { :servers => "custom_servers", :rooms => "custom_rooms" }
|
46
39
|
#
|
47
40
|
# ==== Room matchers
|
48
41
|
#
|
@@ -81,11 +74,12 @@ module ActionDispatch::Routing
|
|
81
74
|
|
82
75
|
def bigbluebutton_routes_default(*params) #:nodoc:
|
83
76
|
options = params.extract_options!
|
84
|
-
options_scope = options.has_key?(:scope) ? options[:scope] :
|
77
|
+
options_scope = options.has_key?(:scope) ? options[:scope] : BigbluebuttonRails.routing_scope
|
78
|
+
BigbluebuttonRails.set_controllers(options[:controllers])
|
85
79
|
|
86
80
|
scope options_scope, :as => options_scope do
|
87
|
-
resources :servers, :controller =>
|
88
|
-
resources :rooms, :controller =>
|
81
|
+
resources :servers, :controller => BigbluebuttonRails.controllers[:servers] do
|
82
|
+
resources :rooms, :controller => BigbluebuttonRails.controllers[:rooms] do
|
89
83
|
get :join, :on => :member
|
90
84
|
get :running, :on => :member
|
91
85
|
get :end, :on => :member
|
@@ -98,12 +92,12 @@ module ActionDispatch::Routing
|
|
98
92
|
|
99
93
|
def bigbluebutton_routes_room_matchers(*params) #:nodoc:
|
100
94
|
# TODO This is generating helpers like "user_running_room" instead of "running_user_room"
|
101
|
-
get 'room/:id' =>
|
102
|
-
get 'room/:id/join' =>
|
103
|
-
post 'room/:id/join' =>
|
104
|
-
get 'room/:id/running' =>
|
105
|
-
get 'room/:id/end' =>
|
106
|
-
get 'room/:id/invite' =>
|
95
|
+
get 'room/:id' => "#{BigbluebuttonRails.controllers[:rooms]}#show", :as => 'room'
|
96
|
+
get 'room/:id/join' => "#{BigbluebuttonRails.controllers[:rooms]}#join", :as => 'join_room'
|
97
|
+
post 'room/:id/join' => "#{BigbluebuttonRails.controllers[:rooms]}#auth", :as => 'join_room'
|
98
|
+
get 'room/:id/running' => "#{BigbluebuttonRails.controllers[:rooms]}#running", :as => 'running_room'
|
99
|
+
get 'room/:id/end' => "#{BigbluebuttonRails.controllers[:rooms]}#end", :as => 'end_room'
|
100
|
+
get 'room/:id/invite' => "#{BigbluebuttonRails.controllers[:rooms]}#invite", :as => 'invite_room'
|
107
101
|
end
|
108
102
|
|
109
103
|
end
|
data/lib/bigbluebutton_rails.rb
CHANGED
@@ -6,4 +6,17 @@ module BigbluebuttonRails
|
|
6
6
|
require 'bigbluebutton_rails/rails'
|
7
7
|
require 'bigbluebutton_rails/controller_methods'
|
8
8
|
require 'bigbluebutton_rails/rails/routes'
|
9
|
+
|
10
|
+
# Default controllers to generate the routes
|
11
|
+
mattr_accessor :controllers
|
12
|
+
@@controllers = { :servers => 'bigbluebutton/servers', :rooms => 'bigbluebutton/rooms' }
|
13
|
+
|
14
|
+
# Default scope for routes
|
15
|
+
mattr_accessor :routing_scope
|
16
|
+
@@routing_scope = 'bigbluebutton'
|
17
|
+
|
18
|
+
def self.set_controllers(options)
|
19
|
+
@@controllers.merge!(options).slice!(:servers, :rooms) unless options.nil?
|
20
|
+
end
|
21
|
+
|
9
22
|
end
|
@@ -7,7 +7,7 @@ class BigbluebuttonAttendee
|
|
7
7
|
def from_hash(hash)
|
8
8
|
self.user_id = hash[:userID].to_s
|
9
9
|
self.full_name = hash[:fullName].to_s
|
10
|
-
self.role = hash[:role].downcase == "moderator" ? :moderator : :attendee
|
10
|
+
self.role = hash[:role].to_s.downcase == "moderator" ? :moderator : :attendee
|
11
11
|
end
|
12
12
|
|
13
13
|
def ==(other)
|
@@ -27,6 +27,7 @@ class CreateBigbluebuttonRails < ActiveRecord::Migration
|
|
27
27
|
end
|
28
28
|
add_index :bigbluebutton_rooms, :server_id
|
29
29
|
add_index :bigbluebutton_rooms, :meetingid, :unique => true
|
30
|
+
add_index :bigbluebutton_rooms, :voice_bridge, :unique => true
|
30
31
|
end
|
31
32
|
|
32
33
|
def self.down
|
@@ -23,11 +23,12 @@ describe BigbluebuttonRoom do
|
|
23
23
|
it { should have_db_column(:randomize_meetingid).of_type(:boolean) }
|
24
24
|
it { should have_db_index(:server_id) }
|
25
25
|
it { should have_db_index(:meetingid).unique(true) }
|
26
|
-
it {
|
26
|
+
it { should have_db_index(:voice_bridge).unique(true) }
|
27
|
+
it {
|
27
28
|
room = BigbluebuttonRoom.new
|
28
29
|
room.private.should be_false
|
29
30
|
}
|
30
|
-
it {
|
31
|
+
it {
|
31
32
|
room = BigbluebuttonRoom.new
|
32
33
|
room.randomize_meetingid.should be_true
|
33
34
|
}
|
@@ -44,6 +45,7 @@ describe BigbluebuttonRoom do
|
|
44
45
|
|
45
46
|
it { should validate_presence_of(:server_id) }
|
46
47
|
it { should validate_presence_of(:meetingid) }
|
48
|
+
it { should validate_presence_of(:voice_bridge) }
|
47
49
|
it { should validate_presence_of(:name) }
|
48
50
|
|
49
51
|
it { should be_boolean(:private) }
|
@@ -59,6 +61,7 @@ describe BigbluebuttonRoom do
|
|
59
61
|
|
60
62
|
it { should validate_uniqueness_of(:meetingid) }
|
61
63
|
it { should validate_uniqueness_of(:name) }
|
64
|
+
it { should validate_uniqueness_of(:voice_bridge) }
|
62
65
|
|
63
66
|
it {
|
64
67
|
room = Factory.create(:bigbluebutton_room)
|
@@ -103,11 +106,83 @@ describe BigbluebuttonRoom do
|
|
103
106
|
room.attendees.should == []
|
104
107
|
end
|
105
108
|
|
106
|
-
|
107
|
-
room.meetingid.should_not be_nil
|
109
|
+
context "meetingid" do
|
110
|
+
it { room.meetingid.should_not be_nil }
|
111
|
+
it {
|
112
|
+
b = BigbluebuttonRoom.new(:meetingid => "user defined")
|
113
|
+
b.meetingid.should == "user defined"
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
context "voice_bridge" do
|
118
|
+
it { room.voice_bridge.should_not be_nil }
|
119
|
+
it { room.voice_bridge.length.should == 5 }
|
120
|
+
it { room.voice_bridge[0].should == '7' }
|
121
|
+
it {
|
122
|
+
b = BigbluebuttonRoom.new(:voice_bridge => "user defined")
|
123
|
+
b.voice_bridge.should == "user defined"
|
124
|
+
}
|
108
125
|
end
|
109
126
|
end
|
110
127
|
|
128
|
+
|
129
|
+
|
130
|
+
=begin
|
131
|
+
context "randomizes meetingid" do
|
132
|
+
let(:fail_hash) { { :returncode => true, :meetingID => "new id",
|
133
|
+
:messageKey => "duplicateWarning" } }
|
134
|
+
let(:success_hash) { { :returncode => true, :meetingID => "new id",
|
135
|
+
:messageKey => "" } }
|
136
|
+
let(:new_id) { "new id" }
|
137
|
+
before {
|
138
|
+
room.randomize_meetingid = true
|
139
|
+
room.server = mocked_server
|
140
|
+
}
|
141
|
+
|
142
|
+
it "before calling create" do
|
143
|
+
room.should_receive(:random_meetingid).and_return(new_id)
|
144
|
+
mocked_api.should_receive(:create_meeting).
|
145
|
+
with(room.name, new_id, room.moderator_password,
|
146
|
+
room.attendee_password, room.welcome_msg, room.dial_number,
|
147
|
+
room.logout_url, room.max_participants, room.voice_bridge)
|
148
|
+
room.send_create
|
149
|
+
end
|
150
|
+
|
151
|
+
it "and tries again on error" do
|
152
|
+
# fails twice and them succeds
|
153
|
+
room.should_receive(:random_meetingid).exactly(3).times.and_return(new_id)
|
154
|
+
mocked_api.should_receive(:create_meeting).
|
155
|
+
with(room.name, new_id, room.moderator_password,
|
156
|
+
room.attendee_password, room.welcome_msg, room.dial_number,
|
157
|
+
room.logout_url, room.max_participants, room.voice_bridge).
|
158
|
+
twice.
|
159
|
+
and_return(fail_hash)
|
160
|
+
mocked_api.should_receive(:create_meeting).
|
161
|
+
with(room.name, new_id, room.moderator_password,
|
162
|
+
room.attendee_password, room.welcome_msg, room.dial_number,
|
163
|
+
room.logout_url, room.max_participants, room.voice_bridge).
|
164
|
+
once.
|
165
|
+
and_return(success_hash)
|
166
|
+
room.send_create
|
167
|
+
end
|
168
|
+
|
169
|
+
it "and limits to 10 tries" do
|
170
|
+
room.should_receive(:random_meetingid).exactly(11).times.and_return(new_id)
|
171
|
+
mocked_api.should_receive(:create_meeting).
|
172
|
+
with(room.name, new_id, room.moderator_password,
|
173
|
+
room.attendee_password, room.welcome_msg, room.dial_number,
|
174
|
+
room.logout_url, room.max_participants, room.voice_bridge).
|
175
|
+
exactly(10).times.
|
176
|
+
and_return(fail_hash)
|
177
|
+
room.send_create
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
=end
|
183
|
+
|
184
|
+
|
185
|
+
|
111
186
|
context "using the api" do
|
112
187
|
before { mock_server_and_api }
|
113
188
|
let(:room) { Factory.create(:bigbluebutton_room) }
|
@@ -137,13 +212,13 @@ describe BigbluebuttonRoom do
|
|
137
212
|
describe "#fetch_meeting_info" do
|
138
213
|
|
139
214
|
# these hashes should be exactly as returned by bigbluebutton-api-ruby to be sure we are testing it right
|
140
|
-
let(:hash_info) {
|
215
|
+
let(:hash_info) {
|
141
216
|
{ :returncode=>true, :meetingID=>"test_id", :attendeePW=>"1234", :moderatorPW=>"4321",
|
142
217
|
:running=>false, :hasBeenForciblyEnded=>false, :startTime=>nil, :endTime=>nil,
|
143
218
|
:participantCount=>0, :moderatorCount=>0, :attendees=>[], :messageKey=>"", :message=>""
|
144
219
|
}
|
145
220
|
}
|
146
|
-
let(:users) {
|
221
|
+
let(:users) {
|
147
222
|
[
|
148
223
|
{:userID=>"ndw1fnaev0rj", :fullName=>"House M.D.", :role=>:moderator},
|
149
224
|
{:userID=>"gn9e22b7ynna", :fullName=>"Dexter Morgan", :role=>:moderator},
|
@@ -151,7 +226,7 @@ describe BigbluebuttonRoom do
|
|
151
226
|
{:userID=>"rbepbovolsxt", :fullName=>"Trinity", :role=>:viewer}
|
152
227
|
]
|
153
228
|
}
|
154
|
-
let(:hash_info2) {
|
229
|
+
let(:hash_info2) {
|
155
230
|
{ :returncode=>true, :meetingID=>"test_id", :attendeePW=>"1234", :moderatorPW=>"4321",
|
156
231
|
:running=>true, :hasBeenForciblyEnded=>false, :startTime=>DateTime.parse("Wed Apr 06 17:09:57 UTC 2011"),
|
157
232
|
:endTime=>nil, :participantCount=>4, :moderatorCount=>2,
|
@@ -214,7 +289,7 @@ describe BigbluebuttonRoom do
|
|
214
289
|
let(:attendee_password) { Forgery(:basic).password }
|
215
290
|
let(:moderator_password) { Forgery(:basic).password }
|
216
291
|
let(:hash_create) {
|
217
|
-
{
|
292
|
+
{
|
218
293
|
:returncode => "SUCCESS", :meetingID => "test_id",
|
219
294
|
:attendeePW => attendee_password, :moderatorPW => moderator_password,
|
220
295
|
:hasBeenForciblyEnded => "false", :messageKey => {}, :message => {}
|
@@ -44,8 +44,8 @@ describe BigbluebuttonServer do
|
|
44
44
|
server = Factory.create(:bigbluebutton_server)
|
45
45
|
Factory.create(:bigbluebutton_room, :server => server)
|
46
46
|
Factory.create(:bigbluebutton_room, :server => server)
|
47
|
-
expect {
|
48
|
-
expect {
|
47
|
+
expect {
|
48
|
+
expect {
|
49
49
|
server.destroy
|
50
50
|
}.to change{ BigbluebuttonServer.count }.by(-1)
|
51
51
|
}.to change{ BigbluebuttonRoom.count }.by(-2)
|
@@ -90,6 +90,14 @@ describe BigbluebuttonServer do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
context "initializes" do
|
94
|
+
let(:server) { BigbluebuttonServer.new }
|
95
|
+
|
96
|
+
it "fetched attributes before they are fetched" do
|
97
|
+
server.meetings.should == []
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
93
101
|
context "fetching info from bbb" do
|
94
102
|
let(:server) { Factory.create(:bigbluebutton_server) }
|
95
103
|
let(:room1) { Factory.create(:bigbluebutton_room, :server => server, :meetingid => "room1") }
|
@@ -107,7 +115,7 @@ describe BigbluebuttonServer do
|
|
107
115
|
{ :meetingID => "im not in the db", :attendeePW=>"pass", :moderatorPW=>"pass", :hasBeenForciblyEnded => true, :running => true}
|
108
116
|
]
|
109
117
|
}
|
110
|
-
let(:hash) {
|
118
|
+
let(:hash) {
|
111
119
|
{ :returncode => true,
|
112
120
|
:meetings => meetings
|
113
121
|
}
|
@@ -11,4 +11,7 @@ RailsApp::Application.routes.draw do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
# note: controllers modified here will be used in the routes added after this (if any)
|
15
|
+
bigbluebutton_routes :default, :scope => "custom", :controllers => { :servers => 'custom_servers', :rooms => 'custom_rooms' }
|
16
|
+
|
14
17
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActionController do
|
4
|
+
include Shoulda::Matchers::ActionController
|
5
|
+
|
6
|
+
describe "routing" do
|
7
|
+
|
8
|
+
# custom controllers - servers
|
9
|
+
it {
|
10
|
+
{:get => "/custom/servers"}.
|
11
|
+
should route_to(:controller => "custom_servers", :action => "index")
|
12
|
+
}
|
13
|
+
it {
|
14
|
+
{:post => "/custom/servers"}.
|
15
|
+
should route_to(:controller => "custom_servers", :action => "create")
|
16
|
+
}
|
17
|
+
it {
|
18
|
+
{:get => "/custom/servers/new"}.
|
19
|
+
should route_to(:controller => "custom_servers", :action => "new")
|
20
|
+
}
|
21
|
+
it {
|
22
|
+
{:get => "/custom/servers/1/edit"}.
|
23
|
+
should route_to(:controller => "custom_servers", :action => "edit", :id => "1")
|
24
|
+
}
|
25
|
+
it {
|
26
|
+
{:get => "/custom/servers/1"}.
|
27
|
+
should route_to(:controller => "custom_servers", :action => "show", :id => "1")
|
28
|
+
}
|
29
|
+
it {
|
30
|
+
{:put => "/custom/servers/1"}.
|
31
|
+
should route_to(:controller => "custom_servers", :action => "update", :id => "1")
|
32
|
+
}
|
33
|
+
it {
|
34
|
+
{:delete => "/custom/servers/1"}.
|
35
|
+
should route_to(:controller => "custom_servers", :action => "destroy", :id => "1")
|
36
|
+
}
|
37
|
+
|
38
|
+
# custom controllers - rooms
|
39
|
+
it {
|
40
|
+
{:get => "/custom/servers/1/rooms"}.
|
41
|
+
should route_to(:controller => "custom_rooms", :action => "index", :server_id => "1")
|
42
|
+
}
|
43
|
+
it {
|
44
|
+
{:get => "/custom/servers/1/rooms/new"}.
|
45
|
+
should route_to(:controller => "custom_rooms", :action => "new", :server_id => "1")
|
46
|
+
}
|
47
|
+
it {
|
48
|
+
{:get => "/custom/servers/1/rooms/1/edit"}.
|
49
|
+
should route_to(:controller => "custom_rooms", :action => "edit", :server_id => "1", :id => "1")
|
50
|
+
}
|
51
|
+
it {
|
52
|
+
{:get => "/custom/servers/1/rooms/1"}.
|
53
|
+
should route_to(:controller => "custom_rooms", :action => "show", :server_id => "1", :id => "1")
|
54
|
+
}
|
55
|
+
it {
|
56
|
+
{:put => "/custom/servers/1/rooms/1"}.
|
57
|
+
should route_to(:controller => "custom_rooms", :action => "update", :server_id => "1", :id => "1")
|
58
|
+
}
|
59
|
+
it {
|
60
|
+
{:delete => "/custom/servers/1/rooms/1"}.
|
61
|
+
should route_to(:controller => "custom_rooms", :action => "destroy", :server_id => "1", :id => "1")
|
62
|
+
}
|
63
|
+
it {
|
64
|
+
{:get => "/custom/servers/1/rooms/1/join"}.
|
65
|
+
should route_to(:controller => "custom_rooms", :action => "join", :server_id => "1", :id => "1")
|
66
|
+
}
|
67
|
+
it {
|
68
|
+
{:get => "/custom/servers/1/rooms/1/running"}.
|
69
|
+
should route_to(:controller => "custom_rooms", :action => "running", :server_id => "1", :id => "1")
|
70
|
+
}
|
71
|
+
it {
|
72
|
+
{:get => "/custom/servers/1/rooms/1/end"}.
|
73
|
+
should route_to(:controller => "custom_rooms", :action => "end", :server_id => "1", :id => "1")
|
74
|
+
}
|
75
|
+
it {
|
76
|
+
{:get => "/custom/servers/1/rooms/1/invite"}.
|
77
|
+
should route_to(:controller => "custom_rooms", :action => "invite", :server_id => "1", :id => "1")
|
78
|
+
}
|
79
|
+
it {
|
80
|
+
{:post => "/custom/servers/1/rooms/1/join"}.
|
81
|
+
should route_to(:controller => "custom_rooms", :action => "auth", :server_id => "1", :id => "1")
|
82
|
+
}
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
@@ -4,34 +4,39 @@ describe Bigbluebutton::ServersController do
|
|
4
4
|
include Shoulda::Matchers::ActionController
|
5
5
|
|
6
6
|
describe "routing" do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
7
|
+
|
8
|
+
# normal and scoped routes
|
9
|
+
['bigbluebutton', 'webconference'].each do |prefix|
|
10
|
+
it {
|
11
|
+
{:get => "/#{prefix}/servers"}.
|
12
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "index")
|
13
|
+
}
|
14
|
+
it {
|
15
|
+
{:post => "/#{prefix}/servers"}.
|
16
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "create")
|
17
|
+
}
|
18
|
+
it {
|
19
|
+
{:get => "/#{prefix}/servers/new"}.
|
20
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "new")
|
21
|
+
}
|
22
|
+
it {
|
23
|
+
{:get => "/#{prefix}/servers/1/edit"}.
|
24
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "edit", :id => "1")
|
25
|
+
}
|
26
|
+
it {
|
27
|
+
{:get => "/#{prefix}/servers/1"}.
|
28
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "show", :id => "1")
|
29
|
+
}
|
30
|
+
it {
|
31
|
+
{:put => "/#{prefix}/servers/1"}.
|
32
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "update", :id => "1")
|
33
|
+
}
|
34
|
+
it {
|
35
|
+
{:delete => "/#{prefix}/servers/1"}.
|
36
|
+
should route_to(:controller => "bigbluebutton/servers", :action => "destroy", :id => "1")
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
35
40
|
end
|
36
41
|
|
37
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bigbluebutton_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-05-16 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &87438090 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *87438090
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bigbluebutton-api-ruby
|
27
|
-
requirement: &
|
27
|
+
requirement: &87437620 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.0.10
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *87437620
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec-rails
|
38
|
-
requirement: &
|
38
|
+
requirement: &87437220 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.5.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *87437220
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: factory_girl
|
49
|
-
requirement: &
|
49
|
+
requirement: &87436820 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.3.2
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *87436820
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: sqlite3-ruby
|
60
|
-
requirement: &
|
60
|
+
requirement: &87436290 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.3.3
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *87436290
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: generator_spec
|
71
|
-
requirement: &
|
71
|
+
requirement: &87435880 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.8.2
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *87435880
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: shoulda-matchers
|
82
|
-
requirement: &
|
82
|
+
requirement: &87435530 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 1.0.0.beta
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *87435530
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: forgery
|
93
|
-
requirement: &
|
93
|
+
requirement: &87435160 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,8 +98,9 @@ dependencies:
|
|
98
98
|
version: 0.3.7
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
102
|
-
description: BigBlueButton
|
101
|
+
version_requirements: *87435160
|
102
|
+
description: It allows you to interact with a BigBlueButton server from your Ruby
|
103
|
+
on Rails web application
|
103
104
|
email: mconf@googlegroups.com
|
104
105
|
executables: []
|
105
106
|
extensions: []
|
@@ -157,6 +158,8 @@ files:
|
|
157
158
|
- spec/rails_app/.gitignore
|
158
159
|
- spec/rails_app/Rakefile
|
159
160
|
- spec/rails_app/app/controllers/application_controller.rb
|
161
|
+
- spec/rails_app/app/controllers/custom_rooms_controller.rb
|
162
|
+
- spec/rails_app/app/controllers/custom_servers_controller.rb
|
160
163
|
- spec/rails_app/app/controllers/space_controller.rb
|
161
164
|
- spec/rails_app/app/controllers/user_controller.rb
|
162
165
|
- spec/rails_app/app/helpers/application_helper.rb
|
@@ -199,6 +202,7 @@ files:
|
|
199
202
|
- spec/rails_app/public/stylesheets/scaffold.css
|
200
203
|
- spec/rails_app/script/rails
|
201
204
|
- spec/rails_app/vendor/plugins/.gitkeep
|
205
|
+
- spec/routing/bigbluebutton/custom_controllers_routing_spec.rb
|
202
206
|
- spec/routing/bigbluebutton/rooms_routing_spec.rb
|
203
207
|
- spec/routing/bigbluebutton/servers_routing_spec.rb
|
204
208
|
- spec/spec_helper.rb
|
@@ -219,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
219
223
|
version: '0'
|
220
224
|
segments:
|
221
225
|
- 0
|
222
|
-
hash:
|
226
|
+
hash: 986260833
|
223
227
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
228
|
none: false
|
225
229
|
requirements:
|
@@ -228,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
232
|
version: '0'
|
229
233
|
segments:
|
230
234
|
- 0
|
231
|
-
hash:
|
235
|
+
hash: 986260833
|
232
236
|
requirements: []
|
233
237
|
rubyforge_project:
|
234
238
|
rubygems_version: 1.7.2
|