bigbluebutton_rails 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +9 -1
- data/Gemfile.lock +3 -3
- data/README.rdoc +56 -21
- data/Rakefile +1 -0
- data/app/controllers/bigbluebutton/rooms_controller.rb +92 -35
- data/app/models/bigbluebutton_room.rb +136 -27
- data/app/models/bigbluebutton_server.rb +22 -6
- data/app/views/bigbluebutton/rooms/_form.html.erb +31 -6
- data/app/views/bigbluebutton/rooms/edit.html.erb +1 -1
- data/app/views/bigbluebutton/rooms/index.html.erb +20 -8
- data/app/views/bigbluebutton/rooms/invite.html.erb +56 -0
- data/app/views/bigbluebutton/rooms/{join_wait.html.erb → join.html.erb} +16 -12
- data/app/views/bigbluebutton/rooms/new.html.erb +1 -1
- data/app/views/bigbluebutton/rooms/show.html.erb +33 -9
- data/app/views/bigbluebutton/servers/edit.html.erb +1 -1
- data/app/views/bigbluebutton/servers/index.html.erb +6 -4
- data/app/views/bigbluebutton/servers/new.html.erb +1 -1
- data/app/views/bigbluebutton/servers/show.html.erb +5 -5
- data/bigbluebutton_rails.gemspec +1 -1
- data/config/locales/en.yml +31 -0
- data/lib/bigbluebutton_rails/controller_methods.rb +7 -1
- data/lib/bigbluebutton_rails/rails/routes.rb +10 -1
- data/lib/bigbluebutton_rails/version.rb +1 -1
- data/lib/bigbluebutton_rails.rb +0 -1
- data/lib/classes/bigbluebutton_attendee.rb +2 -0
- data/lib/generators/bigbluebutton_rails/install_generator.rb +2 -1
- data/lib/generators/bigbluebutton_rails/public_generator.rb +0 -1
- data/lib/generators/bigbluebutton_rails/templates/migration.rb +8 -2
- data/spec/controllers/bigbluebutton/rooms_controller_spec.rb +339 -88
- data/spec/factories/bigbluebutton_room.rb +5 -3
- data/spec/factories/user.rb +3 -0
- data/spec/generators/public_generator_spec.rb +0 -1
- data/spec/generators/views_generator_spec.rb +1 -1
- data/spec/models/bigbluebutton_room_spec.rb +276 -177
- data/spec/models/bigbluebutton_server_spec.rb +117 -96
- data/spec/routing/bigbluebutton/rooms_routing_spec.rb +24 -0
- data/spec/support/matchers/shoulda/be_boolean.rb +38 -0
- data/spec/support/mocked_server.rb +14 -0
- metadata +26 -26
- data/config/routes.rb +0 -2
- data/lib/classes/bigbluebutton_meeting.rb +0 -18
- data/lib/generators/bigbluebutton_rails/templates/public/javascripts/heartbeat.js +0 -54
- data/spec/classes/bigbluebutton_meeting_spec.rb +0 -62
data/CHANGELOG.rdoc
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
+
== 0.0.3
|
2
|
+
|
3
|
+
* Rooms can be public or private
|
4
|
+
* New route RoomsController#invite used to request a password to join a room or to allow anonymous users to join.
|
5
|
+
* Room's "meeting_id" attribute renamed to "meetingid".
|
6
|
+
* A room can have it's meetingid randomly generated for each "send_create" call if randomize_meetingid is set.
|
7
|
+
* New attributes for rooms: logout_url, dial_number, voice_bridge and max_participant.
|
8
|
+
|
1
9
|
== 0.0.2
|
2
10
|
|
3
|
-
* New "fetch" methods in BigbluebuttonRooms to fetch info about meetings from BBB and store in the model.
|
11
|
+
* New "fetch" and "send" methods in BigbluebuttonRooms to fetch info about meetings from BBB and store in the model.
|
4
12
|
* New class BigbluebuttonAttendee to store attendee information returned by BBB in get_meeting_info.
|
5
13
|
* New class BigbluebuttonMeeting to store meeting information returned by BBB in get_meetings.
|
6
14
|
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bigbluebutton_rails (0.0.
|
5
|
-
bigbluebutton-api-ruby (~> 0.0.
|
4
|
+
bigbluebutton_rails (0.0.3)
|
5
|
+
bigbluebutton-api-ruby (~> 0.0.10)
|
6
6
|
rails (~> 3.0.3)
|
7
7
|
|
8
8
|
GEM
|
@@ -36,7 +36,7 @@ GEM
|
|
36
36
|
activesupport (= 3.0.6)
|
37
37
|
activesupport (3.0.6)
|
38
38
|
arel (2.0.9)
|
39
|
-
bigbluebutton-api-ruby (0.0.
|
39
|
+
bigbluebutton-api-ruby (0.0.10)
|
40
40
|
nokogiri (~> 1.4.0)
|
41
41
|
builder (2.1.2)
|
42
42
|
diff-lcs (1.1.2)
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= BigBlueButton on Rails
|
2
2
|
|
3
|
-
BigBlueButton
|
3
|
+
{BigBlueButton}[http://bigbluebutton.org] integration for Ruby on Rails 3.
|
4
4
|
|
5
5
|
Features:
|
6
6
|
* Allows multiple servers and multiple conference rooms
|
@@ -9,11 +9,12 @@ Features:
|
|
9
9
|
* Easy integration with authentication and authorization mechanisms, such as Devise and CanCan
|
10
10
|
|
11
11
|
Future:
|
12
|
+
* Private room and invitations to allow visitants to join conferences (using a password or not).
|
12
13
|
* Friendly URLs (e.g. http://somewhere.com/my-server/my-room)
|
13
14
|
* Random meeting IDs to avoid problems with end_meeting and timeouts
|
14
15
|
* Server administration (modify config.xml, use bbb-conf, etc.)
|
15
16
|
|
16
|
-
For more future features and issues check http://code.google.com/p/mconf/issues/list?can=2&q=label%3AComponent%20label%3ABigBlueButtonRails
|
17
|
+
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].
|
17
18
|
|
18
19
|
== Installation
|
19
20
|
|
@@ -47,7 +48,7 @@ For more information see the section Dependencies below.
|
|
47
48
|
|
48
49
|
=== Routes
|
49
50
|
|
50
|
-
The routes to bigbluebutton_rails can be generated with the helper
|
51
|
+
The routes to bigbluebutton_rails can be generated with the helper <tt>bigbluebutton_routes</tt>. See the example below:
|
51
52
|
|
52
53
|
bigbluebutton_routes :default
|
53
54
|
|
@@ -72,21 +73,23 @@ So you can allow access to webconference rooms using URLs such as:
|
|
72
73
|
http://myserver.com/user-10/room-5/join
|
73
74
|
http://myserver.com/zaphod/public-room/join
|
74
75
|
|
75
|
-
|
76
|
+
Obs: bigbluebutton_rails does not allows the room access using IDs such as "room-5" or "public-room" yet, but soon you it will.
|
76
77
|
|
77
78
|
=== User authorization, permissions and assumptions
|
78
79
|
|
79
80
|
There are some basic assumptions made by bigbluebutton_rails:
|
80
81
|
|
81
|
-
* You have a method called
|
82
|
-
* The current_user has an attribute or method called "name" that returns his/her fullname.
|
82
|
+
* You have a method called <tt>current_user</tt> that returns the current user;
|
83
|
+
* The <tt>current_user</tt> has an attribute or method called "name" that returns his/her fullname.
|
83
84
|
|
84
85
|
If you don't, you can change this behaviour easily, keep reading.
|
85
86
|
|
86
|
-
bigbluebutton_rails uses the methods
|
87
|
-
user has in the
|
87
|
+
bigbluebutton_rails 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
|
88
|
+
user has in the <tt>room</tt>, respectively. These methods are defined in <tt>lib/bigbluebutton_rails/controller_methods.rb</tt> and you can reimplement them in your
|
89
|
+
application controller to change their behaviour.
|
88
90
|
|
89
|
-
|
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.
|
90
93
|
|
91
94
|
|
92
95
|
==== Integration with Devise
|
@@ -105,32 +108,62 @@ Files:
|
|
105
108
|
|
106
109
|
* Javascripts:
|
107
110
|
* JQuery (jquery.min.js). See http://jquery.com
|
108
|
-
* JQuery Heartbeat plugin (heartbeat.js). See http://plugins.jquery.com/project/Heartbeat
|
109
111
|
* Images:
|
110
112
|
* loading.gif
|
111
113
|
|
112
|
-
|
114
|
+
JQuery is used in the views <tt>join_wait</tt> and <tt>invite</tt> and can be copied into your application with:
|
113
115
|
|
114
116
|
rails generate bigbluebutton_rails:public
|
115
117
|
|
116
118
|
== How it works
|
117
119
|
|
120
|
+
=== Overview
|
121
|
+
|
118
122
|
bigbluebutton_rails has two entities: servers and rooms. Servers can have multiple rooms, that belong to a server and can also belong to any other model.
|
119
123
|
You can make a room belong to a user, for example.
|
120
124
|
|
121
|
-
Every server has an associated API object (using the gem bigbluebutton-api-ruby) used to access BigBlueButton.
|
122
|
-
The server
|
125
|
+
Every server has an associated API object (using the gem bigbluebutton-api-ruby) used to access the BigBlueButton server.
|
126
|
+
The server controller has only the standard CRUD actions defined by Rails.
|
127
|
+
|
128
|
+
The rooms controller also have the CRUD actions, plus some specific actions to join, end, and check if a meeting is currently running in the room.
|
129
|
+
These extra actions will be explained bellow.
|
130
|
+
|
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
|
+
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.
|
134
|
+
|
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
|
+
can throw a BigBlueButtonException.
|
137
|
+
|
138
|
+
=== RoomsController
|
139
|
+
|
140
|
+
==== <tt>running</tt> and <tt>end</tt>
|
123
141
|
|
124
|
-
|
125
|
-
|
126
|
-
|
142
|
+
These are pretty simple actions. <tt>running</tt> returns a json indicating if the conference is running or not, while <tt>end</tt> ends the meeting.
|
143
|
+
|
144
|
+
==== <tt>join</tt>, <tt>invite</tt> and <tt>auth</tt>
|
145
|
+
|
146
|
+
The actions used to redirect a user to join a room are <tt>join</tt> and <tt>invite</tt>, while <tt>auth</tt> is used by <tt>invite</tt> to authenticate
|
147
|
+
the user. Basic differences:
|
148
|
+
|
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
|
+
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. In case it has, redirects to <tt>join</tt>.
|
152
|
+
* If there is a user logged, uses <tt>bigbluebutton_user().name</tt> as the user name. Otherwise, ask the user to type a name.
|
153
|
+
* <tt>join</tt> requires a <b>logged user</b> and uses <tt>bigbluebutton_role</tt> to get the role of this user.
|
154
|
+
* It redirects the user straight to the meeting if the join is successful.
|
155
|
+
* In case there's no role associated with the current user, falls back to <tt>invite</tt> to ask for a password.
|
156
|
+
|
157
|
+
Internally, they use the same algorithm:
|
127
158
|
|
128
159
|
* If the user is a moderator:
|
129
|
-
* If the
|
130
|
-
* Redirects
|
160
|
+
* If the room is not created yet, creates it.
|
161
|
+
* Redirects the user to the meeting as a moderator.
|
131
162
|
* If the user is a normal attendee:
|
132
|
-
* If the
|
133
|
-
* Otherwise
|
163
|
+
* If the meeting is running, redirects the user to the meeting as an attendee.
|
164
|
+
* 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 metting is not running.
|
134
167
|
|
135
168
|
== Development
|
136
169
|
|
@@ -144,4 +177,6 @@ Prepare the rails_app used for tests:
|
|
144
177
|
|
145
178
|
Run the tests:
|
146
179
|
|
147
|
-
rake spec
|
180
|
+
rake spec
|
181
|
+
|
182
|
+
Develop. :)
|
data/Rakefile
CHANGED
@@ -16,6 +16,7 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
16
16
|
rdoc.rdoc_files.include('README.rdoc')
|
17
17
|
rdoc.rdoc_files.include('CHANGELOG.rdoc')
|
18
18
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
rdoc.rdoc_files.include('app/**/*.rb')
|
19
20
|
end
|
20
21
|
|
21
22
|
eval("$specification = begin; #{ IO.read('bigbluebutton_rails.gemspec')}; end")
|
@@ -26,21 +26,29 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
26
26
|
def create
|
27
27
|
@room = BigbluebuttonRoom.new(params[:bigbluebutton_room])
|
28
28
|
@room.server = @server
|
29
|
-
|
30
|
-
# TODO Generate a random
|
31
|
-
if !params[:bigbluebutton_room].has_key?(:
|
32
|
-
params[:bigbluebutton_room][:
|
33
|
-
@room.
|
29
|
+
|
30
|
+
# TODO Generate a random meetingid everytime a room is created
|
31
|
+
if !params[:bigbluebutton_room].has_key?(:meetingid) or
|
32
|
+
params[:bigbluebutton_room][:meetingid].blank?
|
33
|
+
@room.meetingid = @room.name
|
34
34
|
end
|
35
35
|
|
36
36
|
respond_with @room do |format|
|
37
37
|
if @room.save
|
38
38
|
format.html {
|
39
39
|
message = t('bigbluebutton_rails.rooms.notice.create.success')
|
40
|
-
|
40
|
+
params[:redir_url] ||= bigbluebutton_server_room_path(@server, @room)
|
41
|
+
redirect_to params[:redir_url], :notice => message
|
41
42
|
}
|
42
43
|
else
|
43
|
-
format.html {
|
44
|
+
format.html {
|
45
|
+
unless params[:redir_url].blank?
|
46
|
+
message = t('bigbluebutton_rails.rooms.notice.create.failure')
|
47
|
+
redirect_to params[:redir_url], :error => message
|
48
|
+
else
|
49
|
+
render :action => "new"
|
50
|
+
end
|
51
|
+
}
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
@@ -48,19 +56,27 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
48
56
|
def update
|
49
57
|
@room = BigbluebuttonRoom.find(params[:id])
|
50
58
|
|
51
|
-
if !params[:bigbluebutton_room].has_key?(:
|
52
|
-
params[:bigbluebutton_room][:
|
53
|
-
params[:bigbluebutton_room][:
|
59
|
+
if !params[:bigbluebutton_room].has_key?(:meetingid) or
|
60
|
+
params[:bigbluebutton_room][:meetingid].blank?
|
61
|
+
params[:bigbluebutton_room][:meetingid] = params[:bigbluebutton_room][:name]
|
54
62
|
end
|
55
63
|
|
56
64
|
respond_with @room do |format|
|
57
65
|
if @room.update_attributes(params[:bigbluebutton_room])
|
58
66
|
format.html {
|
59
67
|
message = t('bigbluebutton_rails.rooms.notice.update.success')
|
60
|
-
|
68
|
+
params[:redir_url] ||= bigbluebutton_server_room_path(@server, @room)
|
69
|
+
redirect_to params[:redir_url], :notice => message
|
61
70
|
}
|
62
71
|
else
|
63
|
-
format.html {
|
72
|
+
format.html {
|
73
|
+
unless params[:redir_url].blank?
|
74
|
+
message = t('bigbluebutton_rails.rooms.notice.update.failure')
|
75
|
+
redirect_to params[:redir_url], :error => message
|
76
|
+
else
|
77
|
+
render :action => "edit"
|
78
|
+
end
|
79
|
+
}
|
64
80
|
end
|
65
81
|
end
|
66
82
|
end
|
@@ -79,42 +95,54 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
79
95
|
end
|
80
96
|
|
81
97
|
@room.destroy
|
82
|
-
|
98
|
+
params[:redir_url] ||= bigbluebutton_server_rooms_url
|
99
|
+
redirect_to params[:redir_url]
|
83
100
|
end
|
84
101
|
|
102
|
+
# Used to join public rooms with a logged user.
|
85
103
|
def join
|
86
104
|
@room = BigbluebuttonRoom.find(params[:id])
|
105
|
+
|
106
|
+
# anonymous users or users without a role join through #invite
|
87
107
|
role = bigbluebutton_role(@room)
|
108
|
+
if bigbluebutton_user.nil? or role.nil?
|
109
|
+
redirect_to :action => :invite
|
110
|
+
else
|
111
|
+
join_internal(bigbluebutton_user.name, role, :join)
|
112
|
+
end
|
88
113
|
|
89
|
-
|
90
|
-
@room.fetch_is_running?
|
114
|
+
end
|
91
115
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
@room.send_create unless @room.is_running?
|
96
|
-
join_url = @room.join_url(bigbluebutton_user.name, role)
|
97
|
-
redirect_to(join_url)
|
116
|
+
# Used to join private rooms or to invited anonymous users (not logged)
|
117
|
+
def invite
|
118
|
+
@room = BigbluebuttonRoom.find(params[:id])
|
98
119
|
|
99
|
-
|
100
|
-
|
120
|
+
respond_with @room do |format|
|
121
|
+
|
122
|
+
# if there's already a logged user with a role in the room, join through #join
|
123
|
+
unless bigbluebutton_user.nil? or bigbluebutton_role(@room).nil?
|
124
|
+
format.html { redirect_to :action => :join }
|
101
125
|
else
|
102
|
-
|
103
|
-
join_url = @room.join_url(bigbluebutton_user.name, role)
|
104
|
-
redirect_to(join_url)
|
105
|
-
else
|
106
|
-
render :action => :join_wait
|
107
|
-
end
|
126
|
+
format.html
|
108
127
|
end
|
109
128
|
|
110
|
-
rescue BigBlueButton::BigBlueButtonException => e
|
111
|
-
flash[:error] = e.to_s
|
112
|
-
redirect_to request.referer
|
113
129
|
end
|
114
|
-
|
115
130
|
end
|
116
131
|
|
117
|
-
|
132
|
+
# Authenticates an user using name and password passed in the params from #invite
|
133
|
+
def auth
|
134
|
+
@room = BigbluebuttonRoom.find(params[:id])
|
135
|
+
|
136
|
+
# if there's a user logged, use his name instead of the name in the params
|
137
|
+
name = bigbluebutton_user.nil? ? params[:user][:name] : bigbluebutton_user.name
|
138
|
+
role = @room.user_role(params[:user])
|
139
|
+
|
140
|
+
unless role.nil? or name.nil?
|
141
|
+
join_internal(name, role, :invite)
|
142
|
+
else
|
143
|
+
flash[:error] = t('bigbluebutton_rails.rooms.error.auth.failure')
|
144
|
+
render :action => "invite", :status => :unauthorized
|
145
|
+
end
|
118
146
|
end
|
119
147
|
|
120
148
|
def running
|
@@ -125,7 +153,6 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
125
153
|
rescue BigBlueButton::BigBlueButtonException => e
|
126
154
|
flash[:error] = e.to_s
|
127
155
|
render :json => { running: "false", error: "#{e.to_s}" }
|
128
|
-
#redirect_to request.referer
|
129
156
|
else
|
130
157
|
render :json => { running: "#{@room.is_running?}" }
|
131
158
|
end
|
@@ -162,4 +189,34 @@ class Bigbluebutton::RoomsController < ApplicationController
|
|
162
189
|
end
|
163
190
|
end
|
164
191
|
|
192
|
+
def join_internal(username, role, wait_action)
|
193
|
+
|
194
|
+
begin
|
195
|
+
@room.fetch_is_running?
|
196
|
+
|
197
|
+
# if the current user is a moderator, create the room (if needed)
|
198
|
+
# and join it
|
199
|
+
if role == :moderator
|
200
|
+
@room.send_create unless @room.is_running?
|
201
|
+
join_url = @room.join_url(username, role)
|
202
|
+
redirect_to(join_url)
|
203
|
+
|
204
|
+
# normal user only joins if the conference is running
|
205
|
+
# if it's not, wait for a moderator to create the conference
|
206
|
+
else
|
207
|
+
if @room.is_running?
|
208
|
+
join_url = @room.join_url(username, role)
|
209
|
+
redirect_to(join_url)
|
210
|
+
else
|
211
|
+
flash[:error] = t('bigbluebutton_rails.rooms.error.not_running')
|
212
|
+
render :action => wait_action
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
rescue BigBlueButton::BigBlueButtonException => e
|
217
|
+
flash[:error] = e.to_s
|
218
|
+
redirect_to request.referer
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
165
222
|
end
|
@@ -1,38 +1,63 @@
|
|
1
|
+
require 'active_support/secure_random'
|
2
|
+
|
1
3
|
class BigbluebuttonRoom < ActiveRecord::Base
|
2
4
|
belongs_to :server, :class_name => 'BigbluebuttonServer'
|
3
5
|
belongs_to :owner, :polymorphic => true
|
4
6
|
|
5
7
|
validates :server_id, :presence => true
|
6
|
-
validates :
|
8
|
+
validates :meetingid, :presence => true, :uniqueness => true,
|
7
9
|
:length => { :minimum => 1, :maximum => 100 }
|
8
10
|
validates :name, :presence => true, :uniqueness => true,
|
9
11
|
:length => { :minimum => 1, :maximum => 150 }
|
10
|
-
validates :attendee_password, :length => { :maximum => 50 }
|
11
|
-
validates :moderator_password, :length => { :maximum => 50 }
|
12
12
|
validates :welcome_msg, :length => { :maximum => 250 }
|
13
|
+
validates :private, :inclusion => { :in => [true, false] }
|
14
|
+
validates :randomize_meetingid, :inclusion => { :in => [true, false] }
|
15
|
+
|
16
|
+
# Passwords are 16 character strings
|
17
|
+
# See http://groups.google.com/group/bigbluebutton-dev/browse_thread/thread/9be5aae1648bcab?pli=1
|
18
|
+
validates :attendee_password, :length => { :maximum => 16 }
|
19
|
+
validates :moderator_password, :length => { :maximum => 16 }
|
13
20
|
|
14
|
-
attr_accessible :name, :server_id, :
|
15
|
-
:
|
21
|
+
attr_accessible :name, :server_id, :meetingid, :attendee_password, :moderator_password,
|
22
|
+
:welcome_msg, :owner, :server, :private, :logout_url, :dial_number,
|
23
|
+
:voice_bridge, :max_participants, :owner_id, :owner_type, :randomize_meetingid
|
16
24
|
|
17
|
-
# Note: these params need to be fetched before being accessed
|
18
|
-
|
19
|
-
|
25
|
+
# Note: these params need to be fetched from the server before being accessed
|
26
|
+
attr_accessor :running, :participant_count, :moderator_count, :attendees,
|
27
|
+
:has_been_forcibly_ended, :start_time, :end_time
|
20
28
|
|
29
|
+
after_initialize :init
|
30
|
+
|
31
|
+
# Convenience method to access the attribute <tt>running</tt>
|
21
32
|
def is_running?
|
22
33
|
@running
|
23
34
|
end
|
24
35
|
|
36
|
+
# Fetches info from BBB about this room.
|
37
|
+
# The response is parsed and stored in the model. You can access it using attributes such as:
|
38
|
+
#
|
39
|
+
# room.participant_count
|
40
|
+
# room.attendees[0].full_name
|
41
|
+
#
|
42
|
+
# The attributes changed are:
|
43
|
+
# * <tt>participant_count</tt>
|
44
|
+
# * <tt>moderator_count</tt>
|
45
|
+
# * <tt>running</tt>
|
46
|
+
# * <tt>has_been_forcibly_ended</tt>
|
47
|
+
# * <tt>start_time</tt>
|
48
|
+
# * <tt>end_time</tt>
|
49
|
+
# * <tt>attendees</tt> (array of <tt>BigbluebuttonAttendee</tt>)
|
50
|
+
#
|
51
|
+
# Triggers API call: <tt>get_meeting_info</tt>.
|
25
52
|
def fetch_meeting_info
|
26
|
-
response = self.server.api.get_meeting_info(self.
|
53
|
+
response = self.server.api.get_meeting_info(self.meetingid, self.moderator_password)
|
27
54
|
|
28
55
|
@participant_count = response[:participantCount]
|
29
56
|
@moderator_count = response[:moderatorCount]
|
30
|
-
@running = response[:running]
|
31
|
-
@has_been_forcibly_ended = response[:hasBeenForciblyEnded]
|
32
|
-
@start_time = response[:startTime]
|
33
|
-
|
34
|
-
@end_time = response[:endTime] == "null" ?
|
35
|
-
nil : DateTime.parse(response[:endTime])
|
57
|
+
@running = response[:running]
|
58
|
+
@has_been_forcibly_ended = response[:hasBeenForciblyEnded]
|
59
|
+
@start_time = response[:startTime]
|
60
|
+
@end_time = response[:endTime]
|
36
61
|
@attendees = []
|
37
62
|
response[:attendees].each do |att|
|
38
63
|
attendee = BigbluebuttonAttendee.new
|
@@ -43,37 +68,121 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
43
68
|
response
|
44
69
|
end
|
45
70
|
|
71
|
+
# Fetches the BBB server to see if the meeting is running. Sets <tt>running</tt>
|
72
|
+
#
|
73
|
+
# Triggers API call: <tt>is_meeting_running</tt>.
|
46
74
|
def fetch_is_running?
|
47
|
-
@running = self.server.api.is_meeting_running?(self.
|
75
|
+
@running = self.server.api.is_meeting_running?(self.meetingid)
|
48
76
|
end
|
49
77
|
|
78
|
+
# Sends a call to the BBB server to end the meeting.
|
79
|
+
#
|
80
|
+
# Triggers API call: <tt>end_meeting</tt>.
|
50
81
|
def send_end
|
51
|
-
self.server.api.end_meeting(self.
|
82
|
+
self.server.api.end_meeting(self.meetingid, self.moderator_password)
|
52
83
|
end
|
53
84
|
|
85
|
+
# Sends a call to the BBB server to create the meeting.
|
86
|
+
#
|
87
|
+
# With the response, updates the following attributes:
|
88
|
+
# * <tt>attendee_password</tt>
|
89
|
+
# * <tt>moderator_password</tt>
|
90
|
+
#
|
91
|
+
# Triggers API call: <tt>create_meeting</tt>.
|
54
92
|
def send_create
|
55
|
-
response = self.server.api.create_meeting(self.name, self.meeting_id, self.moderator_password,
|
56
|
-
self.attendee_password, self.welcome_msg)
|
57
93
|
|
58
|
-
|
94
|
+
unless self.randomize_meetingid
|
95
|
+
response = do_create_meeting
|
96
|
+
|
97
|
+
# create a new random meetingid everytime create fails with "duplicateWarning"
|
98
|
+
else
|
99
|
+
self.meetingid = random_meetingid
|
100
|
+
|
101
|
+
count = 0
|
102
|
+
try_again = true
|
103
|
+
while try_again and count < 10
|
104
|
+
response = do_create_meeting
|
105
|
+
|
106
|
+
count += 1
|
107
|
+
try_again = false
|
108
|
+
unless response.nil?
|
109
|
+
if response[:returncode] && response[:messageKey] == "duplicateWarning"
|
110
|
+
self.meetingid = random_meetingid
|
111
|
+
try_again = true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
59
118
|
unless response.nil?
|
60
|
-
self.attendee_password = response[:attendeePW]
|
61
|
-
self.moderator_password = response[:moderatorPW]
|
119
|
+
self.attendee_password = response[:attendeePW]
|
120
|
+
self.moderator_password = response[:moderatorPW]
|
62
121
|
self.save
|
63
122
|
end
|
64
123
|
|
65
124
|
response
|
66
125
|
end
|
67
126
|
|
68
|
-
#
|
127
|
+
# Returns the URL to join this room.
|
128
|
+
# username:: Name of the user
|
129
|
+
# role:: Role of the user in this room. Can be <tt>[:moderator, :attendee]</tt>
|
130
|
+
#
|
131
|
+
# Uses the API but does not require a request to the server.
|
69
132
|
def join_url(username, role)
|
70
133
|
if role == :moderator
|
71
|
-
self.server.api.join_meeting_url(self.
|
72
|
-
self.moderator_password)
|
134
|
+
self.server.api.join_meeting_url(self.meetingid, username, self.moderator_password)
|
73
135
|
else
|
74
|
-
self.server.api.join_meeting_url(self.
|
75
|
-
self.attendee_password)
|
136
|
+
self.server.api.join_meeting_url(self.meetingid, username, self.attendee_password)
|
76
137
|
end
|
77
138
|
end
|
78
139
|
|
140
|
+
|
141
|
+
# Returns the role of the user based on the password given.
|
142
|
+
# The return value can be <tt>:moderator</tt>, <tt>:attendee</tt>, or
|
143
|
+
# nil if the password given does not match any of the room passwords.
|
144
|
+
# params:: Hash with a key :password
|
145
|
+
def user_role(params)
|
146
|
+
role = nil
|
147
|
+
if params.has_key?(:password)
|
148
|
+
if self.moderator_password == params[:password]
|
149
|
+
role = :moderator
|
150
|
+
elsif self.attendee_password == params[:password]
|
151
|
+
role = :attendee
|
152
|
+
end
|
153
|
+
end
|
154
|
+
role
|
155
|
+
end
|
156
|
+
|
157
|
+
protected
|
158
|
+
|
159
|
+
def init
|
160
|
+
self[:meetingid] ||= random_meetingid
|
161
|
+
|
162
|
+
# fetched attributes
|
163
|
+
@participant_count = 0
|
164
|
+
@moderator_count = 0
|
165
|
+
@running = false
|
166
|
+
@has_been_forcibly_ended = false
|
167
|
+
@start_time = nil
|
168
|
+
@end_time = nil
|
169
|
+
@attendees = []
|
170
|
+
end
|
171
|
+
|
172
|
+
def random_meetingid
|
173
|
+
#ActiveSupport::SecureRandom.hex(16)
|
174
|
+
# TODO temporarily using the name to get a friendlier meetingid
|
175
|
+
if self[:name].blank?
|
176
|
+
ActiveSupport::SecureRandom.hex(8)
|
177
|
+
else
|
178
|
+
self[:name] + '-' + ActiveSupport::SecureRandom.random_number(9999).to_s
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def do_create_meeting
|
183
|
+
self.server.api.create_meeting(self.name, self.meetingid, self.moderator_password,
|
184
|
+
self.attendee_password, self.welcome_msg, self.dial_number,
|
185
|
+
self.logout_url, self.max_participants, self.voice_bridge)
|
186
|
+
end
|
187
|
+
|
79
188
|
end
|
@@ -14,6 +14,8 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
14
14
|
|
15
15
|
validates :version, :presence => true, :inclusion => { :in => ['0.64', '0.7'] }
|
16
16
|
|
17
|
+
# Returns the API object (<tt>BigBlueButton::BigBlueButtonAPI</tt> defined in
|
18
|
+
# <tt>bigbluebutton-api-ruby</tt>) associated with this server.
|
17
19
|
def api
|
18
20
|
if @api.nil?
|
19
21
|
@api = BigBlueButton::BigBlueButtonApi.new(self.url, self.salt,
|
@@ -22,20 +24,34 @@ class BigbluebuttonServer < ActiveRecord::Base
|
|
22
24
|
@api
|
23
25
|
end
|
24
26
|
|
27
|
+
# Array of <tt>BigbluebuttonMeeting</tt>
|
25
28
|
attr_reader :meetings
|
26
29
|
|
30
|
+
# Fetches the meetings currently created in the server (running or not).
|
31
|
+
#
|
32
|
+
# Using the response, updates <tt>meetings</tt> with a list of <tt>BigbluebuttonMeeting</tt>
|
33
|
+
# objects.
|
34
|
+
#
|
35
|
+
# Triggers API call: <tt>get_meetings</tt>.
|
27
36
|
def fetch_meetings
|
28
37
|
response = self.api.get_meetings
|
29
38
|
|
30
39
|
# updates the information in the rooms that are currently in BBB
|
31
40
|
@meetings = []
|
32
41
|
response[:meetings].each do |attr|
|
33
|
-
room = BigbluebuttonRoom.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
room = BigbluebuttonRoom.find_by_server_id_and_meetingid(self.id, attr[:meetingID])
|
43
|
+
if room.nil?
|
44
|
+
room = BigbluebuttonRoom.new(:server => self, :meetingid => attr[:meetingID],
|
45
|
+
:attendee_password => attr[:attendeePW],
|
46
|
+
:moderator_password => attr[:moderatorPW])
|
47
|
+
room.running = attr[:running]
|
48
|
+
else
|
49
|
+
room.update_attributes(:attendee_password => attr[:attendeePW],
|
50
|
+
:moderator_password => attr[:moderatorPW])
|
51
|
+
room.running = attr[:running]
|
52
|
+
end
|
53
|
+
|
54
|
+
@meetings << room
|
39
55
|
end
|
40
56
|
end
|
41
57
|
|