bigbluebutton_rails 1.4.0 → 2.0.0
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.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +10 -1
- data/CHANGELOG.md +259 -0
- data/Gemfile +14 -19
- data/Gemfile.lock +194 -188
- data/README.md +416 -0
- data/Rakefile +12 -12
- data/TODO.md +13 -0
- data/app/controllers/bigbluebutton/playback_types_controller.rb +44 -0
- data/app/controllers/bigbluebutton/recordings_controller.rb +17 -10
- data/app/controllers/bigbluebutton/rooms_controller.rb +65 -36
- data/app/controllers/bigbluebutton/servers_controller.rb +12 -8
- data/app/models/bigbluebutton_metadata.rb +1 -1
- data/app/models/bigbluebutton_playback_format.rb +22 -1
- data/app/models/bigbluebutton_playback_type.rb +29 -0
- data/app/models/bigbluebutton_recording.rb +38 -19
- data/app/models/bigbluebutton_room.rb +150 -73
- data/app/models/bigbluebutton_room_options.rb +10 -7
- data/app/models/bigbluebutton_server.rb +69 -13
- data/app/models/bigbluebutton_server_config.rb +49 -0
- data/app/views/bigbluebutton/recordings/_form.html.erb +4 -0
- data/app/views/bigbluebutton/recordings/_recordings.html.erb +10 -3
- data/app/views/bigbluebutton/rooms/_form.html.erb +18 -6
- data/app/views/bigbluebutton/rooms/_rooms.html.erb +6 -3
- data/app/views/bigbluebutton/rooms/invite.html.erb +5 -5
- data/app/views/bigbluebutton/rooms/show.html.erb +18 -6
- data/app/views/bigbluebutton/servers/_form.html.erb +1 -1
- data/app/views/bigbluebutton/servers/show.html.erb +5 -0
- data/app/workers/bigbluebutton_finish_meetings.rb +11 -0
- data/app/workers/bigbluebutton_update_recordings.rb +11 -0
- data/app/workers/bigbluebutton_update_server_configs.rb +18 -0
- data/bigbluebutton_rails.gemspec +8 -7
- data/config/locales/en.yml +52 -7
- data/config/locales/pt-br.yml +162 -0
- data/config/resque/resque.rake +27 -0
- data/config/resque/workers_schedule.yml +17 -0
- data/lib/bigbluebutton_rails.rb +30 -2
- data/lib/bigbluebutton_rails/background_tasks.rb +31 -0
- data/lib/bigbluebutton_rails/controller_methods.rb +12 -8
- data/lib/bigbluebutton_rails/dial_number.rb +48 -0
- data/lib/bigbluebutton_rails/rails/routes.rb +9 -2
- data/lib/bigbluebutton_rails/utils.rb +9 -2
- data/lib/bigbluebutton_rails/version.rb +1 -1
- data/lib/generators/bigbluebutton_rails/install_generator.rb +0 -8
- data/lib/generators/bigbluebutton_rails/templates/migration.rb +28 -6
- data/lib/generators/bigbluebutton_rails/templates/migration_2_0_0.rb +56 -0
- data/lib/tasks/bigbluebutton_rails/meetings.rake +1 -13
- data/lib/tasks/bigbluebutton_rails/recordings.rake +1 -12
- data/lib/tasks/bigbluebutton_rails/server_configs.rake +10 -0
- data/spec/bigbluebutton_rails_spec.rb +0 -13
- data/spec/controllers/bigbluebutton/playback_types_controller_spec.rb +76 -0
- data/spec/controllers/bigbluebutton/recordings_controller_spec.rb +109 -37
- data/spec/controllers/bigbluebutton/rooms_controller_exception_handling_spec.rb +1 -0
- data/spec/controllers/bigbluebutton/rooms_controller_json_responses_spec.rb +27 -3
- data/spec/controllers/bigbluebutton/rooms_controller_spec.rb +338 -77
- data/spec/controllers/bigbluebutton/servers_controller_json_responses_spec.rb +8 -0
- data/spec/controllers/bigbluebutton/servers_controller_spec.rb +182 -47
- data/spec/factories/bigbluebutton_meeting.rb +2 -2
- data/spec/factories/bigbluebutton_playback_format.rb +2 -2
- data/spec/factories/bigbluebutton_playback_type.rb +7 -0
- data/spec/factories/bigbluebutton_recording.rb +8 -0
- data/spec/factories/bigbluebutton_room.rb +10 -3
- data/spec/factories/bigbluebutton_server.rb +6 -1
- data/spec/factories/bigbluebutton_server_config.rb +6 -0
- data/spec/generators/install_generator_spec.rb +0 -16
- data/spec/lib/bigbluebutton_rails/background_tasks_spec.rb +61 -0
- data/spec/lib/bigbluebutton_rails/dial_number_spec.rb +78 -0
- data/spec/lib/bigbluebutton_rails/utils_spec.rb +56 -0
- data/spec/lib/tasks/meetings_rake_spec.rb +14 -1
- data/spec/lib/tasks/recordings_rake_spec.rb +14 -1
- data/spec/models/bigbluebutton_meeting_db_spec.rb +3 -3
- data/spec/models/bigbluebutton_meeting_spec.rb +4 -4
- data/spec/models/bigbluebutton_playback_format_db_spec.rb +0 -1
- data/spec/models/bigbluebutton_playback_format_spec.rb +75 -4
- data/spec/models/bigbluebutton_playback_type_db_spec.rb +14 -0
- data/spec/models/bigbluebutton_playback_type_spec.rb +76 -0
- data/spec/models/bigbluebutton_recording_db_spec.rb +3 -1
- data/spec/models/bigbluebutton_recording_spec.rb +234 -58
- data/spec/models/bigbluebutton_room_db_spec.rb +8 -6
- data/spec/models/bigbluebutton_room_options_db_spec.rb +1 -0
- data/spec/models/bigbluebutton_room_options_spec.rb +137 -38
- data/spec/models/bigbluebutton_room_spec.rb +540 -153
- data/spec/models/bigbluebutton_server_config_spec.rb +115 -0
- data/spec/models/bigbluebutton_server_spec.rb +180 -23
- data/spec/rails_app/app/controllers/my_playback_types_controller.rb +7 -0
- data/spec/rails_app/app/views/frontpage/show.html.erb +1 -0
- data/spec/rails_app/app/views/my_playback_types/index.html.erb +33 -0
- data/spec/rails_app/config/application.rb +0 -3
- data/spec/rails_app/config/database.yml.travis +10 -0
- data/spec/rails_app/config/environments/development.rb +1 -6
- data/spec/rails_app/config/environments/production.rb +2 -0
- data/spec/rails_app/config/environments/test.rb +2 -0
- data/spec/rails_app/config/routes.rb +5 -2
- data/spec/rails_app/db/seeds.rb +1 -1
- data/spec/rails_app/features/config.yml.example +3 -4
- data/spec/rails_app/features/join_rooms.feature +14 -14
- data/spec/rails_app/features/step_definitions/activity_monitor_servers_step.rb +2 -2
- data/spec/rails_app/features/step_definitions/create_rooms_steps.rb +4 -4
- data/spec/rails_app/features/step_definitions/destroy_rooms_steps.rb +2 -2
- data/spec/rails_app/features/step_definitions/join_rooms_steps.rb +10 -10
- data/spec/rails_app/features/step_definitions/web_steps.rb +2 -2
- data/spec/rails_app/features/support/configurations.rb +1 -1
- data/spec/rails_app/features/support/templates.rb +12 -12
- data/spec/rails_app/lib/tasks/db/populate.rake +19 -6
- data/spec/routing/bigbluebutton/custom_controllers_routing_spec.rb +1 -1
- data/spec/routing/bigbluebutton/recordings_only_routing_spec.rb +2 -2
- data/spec/routing/bigbluebutton/recordings_routing_spec.rb +2 -2
- data/spec/routing/bigbluebutton/rooms_only_routing_spec.rb +1 -1
- data/spec/routing/bigbluebutton/rooms_routing_spec.rb +15 -1
- data/spec/routing/bigbluebutton/servers_only_routing_spec.rb +1 -1
- data/spec/routing/bigbluebutton/servers_routing_spec.rb +1 -1
- data/spec/spec_helper.rb +23 -31
- data/spec/support/matchers/delegate_matcher.rb +8 -1
- data/spec/support/matchers/shoulda/respond_with_json_matcher.rb +2 -2
- data/spec/support/mocked_server.rb +2 -0
- data/spec/support/shared_contexts/rake.rb +23 -0
- data/spec/workers/bigbluebutton_finish_meetings_spec.rb +14 -0
- data/spec/workers/bigbluebutton_update_recordings_spec.rb +14 -0
- data/spec/workers/bigbluebutton_update_server_configs_spec.rb +47 -0
- metadata +70 -59
- data/CHANGELOG.rdoc +0 -111
- data/README.rdoc +0 -319
- data/TODO.rdoc +0 -16
- data/config/schedule.rb +0 -7
|
@@ -21,12 +21,17 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
21
21
|
:foreign_key => 'recording_id',
|
|
22
22
|
:dependent => :destroy
|
|
23
23
|
|
|
24
|
-
scope :published, where(:published => true)
|
|
24
|
+
scope :published, -> { where(:published => true) }
|
|
25
25
|
|
|
26
26
|
def to_param
|
|
27
27
|
self.recordid
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def default_playback_format
|
|
31
|
+
playback_formats.joins(:playback_type)
|
|
32
|
+
.where("bigbluebutton_playback_types.default = ?", true).first
|
|
33
|
+
end
|
|
34
|
+
|
|
30
35
|
# Syncs the recordings in the db with the array of recordings in 'recordings',
|
|
31
36
|
# as received from BigBlueButtonApi#get_recordings.
|
|
32
37
|
# Will add new recordings that are not in the db yet and update the ones that
|
|
@@ -56,14 +61,14 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
56
61
|
# set as unavailable the recordings that are not in 'recordings'
|
|
57
62
|
recordIDs = recordings.map{ |rec| rec[:recordID] }
|
|
58
63
|
if recordIDs.length <= 0 # empty response
|
|
59
|
-
BigbluebuttonRecording
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
BigbluebuttonRecording.
|
|
65
|
+
where(available: true, server: server).
|
|
66
|
+
update_all(available: false)
|
|
62
67
|
else
|
|
63
|
-
BigbluebuttonRecording
|
|
64
|
-
|
|
65
|
-
.
|
|
66
|
-
|
|
68
|
+
BigbluebuttonRecording.
|
|
69
|
+
where(available: true, server: server).
|
|
70
|
+
where.not(recordid: recordIDs).
|
|
71
|
+
update_all(available: false)
|
|
67
72
|
end
|
|
68
73
|
end
|
|
69
74
|
|
|
@@ -89,7 +94,7 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
89
94
|
def self.update_recording(server, recording, data)
|
|
90
95
|
recording.server = server
|
|
91
96
|
recording.room = BigbluebuttonRails.match_room_recording(data)
|
|
92
|
-
recording.attributes = data.slice(:meetingid, :name, :published, :start_time, :end_time)
|
|
97
|
+
recording.attributes = data.slice(:meetingid, :name, :published, :start_time, :end_time, :size)
|
|
93
98
|
recording.available = true
|
|
94
99
|
recording.save!
|
|
95
100
|
|
|
@@ -100,7 +105,7 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
100
105
|
# The format expected for 'data' follows the format returned by
|
|
101
106
|
# BigBlueButtonApi#get_recordings but with the keys already converted to our format.
|
|
102
107
|
def self.create_recording(server, data)
|
|
103
|
-
filtered = data.slice(:recordid, :meetingid, :name, :published, :start_time, :end_time)
|
|
108
|
+
filtered = data.slice(:recordid, :meetingid, :name, :published, :start_time, :end_time, :size)
|
|
104
109
|
recording = BigbluebuttonRecording.create(filtered)
|
|
105
110
|
recording.available = true
|
|
106
111
|
recording.room = BigbluebuttonRails.match_room_recording(data)
|
|
@@ -163,16 +168,16 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
163
168
|
formats_copy = formats.clone
|
|
164
169
|
|
|
165
170
|
# make it an array if it's a hash with a single format
|
|
166
|
-
formats_copy = [
|
|
171
|
+
formats_copy = [formats_copy] if formats_copy.is_a?(Hash)
|
|
167
172
|
|
|
168
|
-
BigbluebuttonPlaybackFormat.where(:
|
|
169
|
-
format = formats_copy.select
|
|
170
|
-
!d[:type].blank?
|
|
171
|
-
|
|
173
|
+
BigbluebuttonPlaybackFormat.where(recording_id: recording.id).each do |format_db|
|
|
174
|
+
format = formats_copy.select do |d|
|
|
175
|
+
!d[:type].blank? && d[:type] == format_db.format_type
|
|
176
|
+
end.first
|
|
172
177
|
|
|
173
178
|
# the format exists in the hash, update it in the db
|
|
174
179
|
if format
|
|
175
|
-
format_db.update_attributes({ :
|
|
180
|
+
format_db.update_attributes({ url: format[:url], length: format[:length] })
|
|
176
181
|
formats_copy.delete(format)
|
|
177
182
|
|
|
178
183
|
# the format is not in the hash, remove from the db
|
|
@@ -181,14 +186,28 @@ class BigbluebuttonRecording < ActiveRecord::Base
|
|
|
181
186
|
end
|
|
182
187
|
end
|
|
183
188
|
|
|
184
|
-
#
|
|
189
|
+
# create the formats that are not in the db yet
|
|
185
190
|
formats_copy.each do |format|
|
|
186
191
|
unless format[:type].blank?
|
|
187
|
-
|
|
188
|
-
|
|
192
|
+
playback_type = BigbluebuttonPlaybackType.find_by_identifier(format[:type])
|
|
193
|
+
if playback_type.nil?
|
|
194
|
+
attrs = { identifier: format[:type], visible: true }
|
|
195
|
+
playback_type = BigbluebuttonPlaybackType.create!(attrs)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
attrs = { recording_id: recording.id, url: format[:url],
|
|
199
|
+
length: format[:length].to_i, playback_type_id: playback_type.id }
|
|
189
200
|
BigbluebuttonPlaybackFormat.create!(attrs)
|
|
190
201
|
end
|
|
191
202
|
end
|
|
203
|
+
|
|
204
|
+
cleanup_playback_types
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Remove the unused playback types from the list.
|
|
208
|
+
def self.cleanup_playback_types
|
|
209
|
+
ids = BigbluebuttonPlaybackFormat.uniq.pluck(:playback_type_id)
|
|
210
|
+
BigbluebuttonPlaybackType.destroy_all(['id NOT IN (?)', ids])
|
|
192
211
|
end
|
|
193
212
|
|
|
194
213
|
# Finds the BigbluebuttonMeeting that generated this recording. The meeting is searched using
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
class BigbluebuttonRoom < ActiveRecord::Base
|
|
2
2
|
include ActiveModel::ForbiddenAttributesProtection
|
|
3
3
|
|
|
4
|
-
belongs_to :
|
|
5
|
-
|
|
4
|
+
belongs_to :owner, polymorphic: true
|
|
5
|
+
|
|
6
|
+
belongs_to :server, class_name: 'BigbluebuttonServer'
|
|
6
7
|
|
|
7
8
|
has_many :recordings,
|
|
8
9
|
:class_name => 'BigbluebuttonRecording',
|
|
@@ -24,8 +25,8 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
24
25
|
delegate :default_layout, :default_layout=, :to => :room_options
|
|
25
26
|
delegate :presenter_share_only, :presenter_share_only=, :to => :room_options
|
|
26
27
|
delegate :auto_start_video, :auto_start_video=, :to => :room_options
|
|
27
|
-
delegate :auto_start_audio, :auto_start_audio=, :to => :room_options
|
|
28
|
-
delegate :
|
|
28
|
+
delegate :auto_start_audio, :auto_start_audio=, :to => :room_options
|
|
29
|
+
delegate :background, :background=, :to => :room_options
|
|
29
30
|
|
|
30
31
|
accepts_nested_attributes_for :metadata,
|
|
31
32
|
:allow_destroy => true,
|
|
@@ -33,12 +34,11 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
33
34
|
|
|
34
35
|
validates :meetingid, :presence => true, :uniqueness => true,
|
|
35
36
|
:length => { :minimum => 1, :maximum => 100 }
|
|
36
|
-
validates :name, :presence => true,
|
|
37
|
+
validates :name, :presence => true,
|
|
37
38
|
:length => { :minimum => 1, :maximum => 150 }
|
|
38
39
|
validates :welcome_msg, :length => { :maximum => 250 }
|
|
39
40
|
validates :private, :inclusion => { :in => [true, false] }
|
|
40
|
-
validates :
|
|
41
|
-
validates :record, :inclusion => { :in => [true, false] }
|
|
41
|
+
validates :record_meeting, :inclusion => { :in => [true, false] }
|
|
42
42
|
|
|
43
43
|
validates :duration,
|
|
44
44
|
:presence => true,
|
|
@@ -48,16 +48,16 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
48
48
|
:presence => true,
|
|
49
49
|
:uniqueness => true,
|
|
50
50
|
:length => { :minimum => 1 },
|
|
51
|
-
:format => { :with =>
|
|
51
|
+
:format => { :with => /\A([a-zA-Z\d_]|[a-zA-Z\d_]+[a-zA-Z\d_-]*[a-zA-Z\d_]+)\z/,
|
|
52
52
|
:message => I18n.t('bigbluebutton_rails.rooms.errors.param_format') }
|
|
53
53
|
|
|
54
54
|
# Passwords are 16 character strings
|
|
55
55
|
# See http://groups.google.com/group/bigbluebutton-dev/browse_thread/thread/9be5aae1648bcab?pli=1
|
|
56
|
-
validates :
|
|
57
|
-
validates :
|
|
56
|
+
validates :attendee_key, :length => { :maximum => 16 }
|
|
57
|
+
validates :moderator_key, :length => { :maximum => 16 }
|
|
58
58
|
|
|
59
|
-
validates :
|
|
60
|
-
validates :
|
|
59
|
+
validates :attendee_key, :presence => true, :if => :private?
|
|
60
|
+
validates :moderator_key, :presence => true, :if => :private?
|
|
61
61
|
|
|
62
62
|
# Note: these params need to be fetched from the server before being accessed
|
|
63
63
|
attr_accessor :running, :participant_count, :moderator_count, :attendees,
|
|
@@ -66,7 +66,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
66
66
|
after_initialize :init
|
|
67
67
|
after_create :create_room_options
|
|
68
68
|
before_validation :set_param
|
|
69
|
-
before_validation :
|
|
69
|
+
before_validation :set_keys
|
|
70
70
|
|
|
71
71
|
# the full logout_url used when logout_url is a relative path
|
|
72
72
|
attr_accessor :full_logout_url
|
|
@@ -105,9 +105,9 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
105
105
|
#
|
|
106
106
|
# Triggers API call: <tt>getMeetingInfo</tt>.
|
|
107
107
|
def fetch_meeting_info
|
|
108
|
-
require_server
|
|
108
|
+
require_server :get_meeting_info
|
|
109
109
|
|
|
110
|
-
response = self.server.api.get_meeting_info(self.meetingid, self.
|
|
110
|
+
response = self.server.api.get_meeting_info(self.meetingid, self.moderator_api_password)
|
|
111
111
|
|
|
112
112
|
@participant_count = response[:participantCount]
|
|
113
113
|
@moderator_count = response[:moderatorCount]
|
|
@@ -132,7 +132,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
132
132
|
#
|
|
133
133
|
# Triggers API call: <tt>isMeetingRunning</tt>.
|
|
134
134
|
def fetch_is_running?
|
|
135
|
-
require_server
|
|
135
|
+
require_server :is_meeting_running
|
|
136
136
|
@running = self.server.api.is_meeting_running?(self.meetingid)
|
|
137
137
|
end
|
|
138
138
|
|
|
@@ -140,8 +140,8 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
140
140
|
#
|
|
141
141
|
# Triggers API call: <tt>end</tt>.
|
|
142
142
|
def send_end
|
|
143
|
-
require_server
|
|
144
|
-
response = self.server.api.end_meeting(self.meetingid, self.
|
|
143
|
+
require_server :end
|
|
144
|
+
response = self.server.api.end_meeting(self.meetingid, self.moderator_api_password)
|
|
145
145
|
|
|
146
146
|
# enqueue an update in the meetings for later on
|
|
147
147
|
Resque.enqueue(::BigbluebuttonMeetingUpdater, self.id, 15.seconds)
|
|
@@ -159,21 +159,25 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
159
159
|
# will be created. If a server is selected, the model is saved.
|
|
160
160
|
#
|
|
161
161
|
# With the response, updates the following attributes:
|
|
162
|
-
# * <tt>
|
|
163
|
-
# * <tt>
|
|
162
|
+
# * <tt>attendee_api_password</tt>
|
|
163
|
+
# * <tt>moderator_api_password</tt>
|
|
164
164
|
#
|
|
165
165
|
# Triggers API call: <tt>create</tt>.
|
|
166
166
|
def send_create(user=nil, user_opts={})
|
|
167
167
|
# updates the server whenever a meeting will be created and guarantees it has a meetingid
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
require_server :create
|
|
169
|
+
|
|
170
|
+
self.meetingid = unique_meetingid() if self.meetingid.blank?
|
|
171
|
+
self.moderator_api_password = internal_password() if self.moderator_api_password.blank?
|
|
172
|
+
self.attendee_api_password = internal_password() if self.attendee_api_password.blank?
|
|
170
173
|
self.save unless self.new_record?
|
|
171
|
-
require_server
|
|
172
174
|
|
|
173
175
|
response = internal_create_meeting(user, user_opts)
|
|
174
176
|
unless response.nil?
|
|
175
|
-
self.
|
|
176
|
-
self.
|
|
177
|
+
self.attendee_api_password = response[:attendeePW]
|
|
178
|
+
self.moderator_api_password = response[:moderatorPW]
|
|
179
|
+
self.create_time = response[:createTime]
|
|
180
|
+
self.voice_bridge = response[:voiceBridge] if response.has_key?(:voiceBridge)
|
|
177
181
|
self.save unless self.new_record?
|
|
178
182
|
end
|
|
179
183
|
|
|
@@ -183,20 +187,20 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
183
187
|
# Returns the URL to join this room.
|
|
184
188
|
# username:: Name of the user
|
|
185
189
|
# role:: Role of the user in this room. Can be <tt>[:moderator, :attendee]</tt>
|
|
186
|
-
#
|
|
190
|
+
# key:: Key to be use (in case role == nil)
|
|
187
191
|
# options:: Additional options to use when generating the URL
|
|
188
192
|
#
|
|
189
193
|
# Uses the API but does not require a request to the server.
|
|
190
|
-
def join_url(username, role,
|
|
191
|
-
require_server
|
|
194
|
+
def join_url(username, role, key=nil, options={})
|
|
195
|
+
require_server :join_meeting_url
|
|
192
196
|
|
|
193
197
|
case role
|
|
194
198
|
when :moderator
|
|
195
|
-
r = self.server.api.join_meeting_url(self.meetingid, username, self.
|
|
199
|
+
r = self.server.api.join_meeting_url(self.meetingid, username, self.moderator_api_password, options)
|
|
196
200
|
when :attendee
|
|
197
|
-
r = self.server.api.join_meeting_url(self.meetingid, username, self.
|
|
201
|
+
r = self.server.api.join_meeting_url(self.meetingid, username, self.attendee_api_password, options)
|
|
198
202
|
else
|
|
199
|
-
r = self.server.api.join_meeting_url(self.meetingid, username,
|
|
203
|
+
r = self.server.api.join_meeting_url(self.meetingid, username, map_key_to_internal_password(key), options)
|
|
200
204
|
end
|
|
201
205
|
|
|
202
206
|
r.strip! unless r.nil?
|
|
@@ -204,16 +208,16 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
204
208
|
end
|
|
205
209
|
|
|
206
210
|
|
|
207
|
-
# Returns the role of the user based on the
|
|
211
|
+
# Returns the role of the user based on the key given.
|
|
208
212
|
# The return value can be <tt>:moderator</tt>, <tt>:attendee</tt>, or
|
|
209
|
-
# nil if the
|
|
210
|
-
# params:: Hash with a key :
|
|
213
|
+
# nil if the key given does not match any of the room keys.
|
|
214
|
+
# params:: Hash with a key :key
|
|
211
215
|
def user_role(params)
|
|
212
216
|
role = nil
|
|
213
|
-
if params && params.has_key?(:
|
|
214
|
-
if self.
|
|
217
|
+
if params && params.has_key?(:key)
|
|
218
|
+
if self.moderator_key == params[:key]
|
|
215
219
|
role = :moderator
|
|
216
|
-
elsif self.
|
|
220
|
+
elsif self.attendee_key == params[:key]
|
|
217
221
|
role = :attendee
|
|
218
222
|
end
|
|
219
223
|
end
|
|
@@ -250,6 +254,10 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
250
254
|
def create_meeting(user=nil, request=nil, user_opts={})
|
|
251
255
|
fetch_is_running?
|
|
252
256
|
unless is_running?
|
|
257
|
+
|
|
258
|
+
# in case the meeting is not running but it's still in memory
|
|
259
|
+
suppress(BigBlueButton::BigBlueButtonException) { send_end }
|
|
260
|
+
|
|
253
261
|
add_domain_to_logout_url(request.protocol, request.host_with_port) unless request.nil?
|
|
254
262
|
send_create(user, user_opts)
|
|
255
263
|
true
|
|
@@ -296,7 +304,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
296
304
|
:server => self.server,
|
|
297
305
|
:meetingid => self.meetingid,
|
|
298
306
|
:name => self.name,
|
|
299
|
-
:
|
|
307
|
+
:recorded => self.record_meeting,
|
|
300
308
|
:running => self.running
|
|
301
309
|
}
|
|
302
310
|
unless metadata.nil?
|
|
@@ -326,9 +334,9 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
326
334
|
|
|
327
335
|
# Sets all meetings related to this room as not running
|
|
328
336
|
def finish_meetings
|
|
329
|
-
BigbluebuttonMeeting.where(:
|
|
330
|
-
.
|
|
331
|
-
.
|
|
337
|
+
BigbluebuttonMeeting.where(running: true)
|
|
338
|
+
.where(room_id: self.id)
|
|
339
|
+
.update_all(running: false)
|
|
332
340
|
end
|
|
333
341
|
|
|
334
342
|
# Gets a 'configToken' to use when joining the room.
|
|
@@ -354,7 +362,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
354
362
|
# returns true if something was changed
|
|
355
363
|
config_xml = self.room_options.set_on_config_xml(config_xml)
|
|
356
364
|
if config_xml
|
|
357
|
-
|
|
365
|
+
self.server.update_config(config_xml)
|
|
358
366
|
# get the new token for the room, and return it
|
|
359
367
|
self.server.api.set_config_xml(self.meetingid, config_xml)
|
|
360
368
|
else
|
|
@@ -365,6 +373,33 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
365
373
|
end
|
|
366
374
|
end
|
|
367
375
|
|
|
376
|
+
def available_layouts
|
|
377
|
+
server.present? ? server.available_layouts : []
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def available_layouts_names
|
|
381
|
+
server.present? ? server.available_layouts_names : []
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def available_layouts_for_select
|
|
385
|
+
server.present? ? server.available_layouts_for_select : []
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# Generates a new dial number following `pattern` and saves it in the room, returning
|
|
389
|
+
# the results of `update_attributes`.
|
|
390
|
+
# Will always generate a unique number. Tries several times if the number already
|
|
391
|
+
# exists and returns `nil` in case it wasn't possible to generate a unique value.
|
|
392
|
+
def generate_dial_number!(pattern=nil)
|
|
393
|
+
pattern ||= 'xxxx-xxxx'
|
|
394
|
+
20.times do
|
|
395
|
+
dn = BigbluebuttonRails::DialNumber.randomize(pattern)
|
|
396
|
+
if BigbluebuttonRoom.where(dial_number: dn).empty?
|
|
397
|
+
return self.update_attributes(dial_number: dn)
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
nil
|
|
401
|
+
end
|
|
402
|
+
|
|
368
403
|
protected
|
|
369
404
|
|
|
370
405
|
def create_room_options
|
|
@@ -377,25 +412,44 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
377
412
|
# but not yet ended.
|
|
378
413
|
# Any action that requires a server should call 'require_server' before
|
|
379
414
|
# anything else.
|
|
380
|
-
|
|
415
|
+
# This method will automatically select a server if the room has no server
|
|
416
|
+
# set on it yet.
|
|
417
|
+
def require_server(api_method=nil)
|
|
418
|
+
selected_server = select_server(api_method)
|
|
419
|
+
unless selected_server.nil?
|
|
420
|
+
self.server = selected_server
|
|
421
|
+
self.save if selected_server && !self.new_record?
|
|
422
|
+
end
|
|
381
423
|
if self.server.nil?
|
|
382
|
-
msg = I18n.t('bigbluebutton_rails.rooms.errors.server.
|
|
424
|
+
msg = I18n.t('bigbluebutton_rails.rooms.errors.server.nil')
|
|
383
425
|
raise BigbluebuttonRails::ServerRequired.new(msg)
|
|
384
426
|
end
|
|
385
427
|
end
|
|
386
428
|
|
|
429
|
+
# Selects the server with less rooms in it in case this room has no server
|
|
430
|
+
# set to it yet. Returns nil if there are no servers to select or if the
|
|
431
|
+
# room already has a server associated to it.
|
|
432
|
+
#
|
|
387
433
|
# This method can be overridden to change the way the server is selected
|
|
388
|
-
# before a room is
|
|
389
|
-
#
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
434
|
+
# before a room is used. `api_method` contains the API method that is being
|
|
435
|
+
# called. Any server returned here will be used. If no server is returned, the
|
|
436
|
+
# room will continue with its current server (if any).
|
|
437
|
+
# One good example is to always select a new server when a meeting is being
|
|
438
|
+
# created (in case `api_method` is `:create`), making this a simple load
|
|
439
|
+
# balancing tool that can work well in simple cases.
|
|
440
|
+
def select_server(api_method=nil)
|
|
441
|
+
if self.server.nil?
|
|
442
|
+
BigbluebuttonServer.
|
|
443
|
+
select("bigbluebutton_servers.*, count(bigbluebutton_rooms.id) as room_count").
|
|
444
|
+
joins("LEFT JOIN bigbluebutton_rooms ON bigbluebutton_servers.id = bigbluebutton_rooms.server_id").
|
|
445
|
+
group(:server_id).order("room_count ASC").first
|
|
446
|
+
else
|
|
447
|
+
nil
|
|
448
|
+
end
|
|
394
449
|
end
|
|
395
450
|
|
|
396
451
|
def init
|
|
397
452
|
self[:meetingid] ||= unique_meetingid
|
|
398
|
-
self[:voice_bridge] ||= random_voice_bridge
|
|
399
453
|
|
|
400
454
|
@request_headers = {}
|
|
401
455
|
|
|
@@ -409,29 +463,27 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
409
463
|
@attendees = []
|
|
410
464
|
end
|
|
411
465
|
|
|
412
|
-
def random_voice_bridge
|
|
413
|
-
value = (70000 + SecureRandom.random_number(9999)).to_s
|
|
414
|
-
count = 1
|
|
415
|
-
while not BigbluebuttonRoom.find_by_voice_bridge(value).nil? and count < 10
|
|
416
|
-
count += 1
|
|
417
|
-
value = (70000 + SecureRandom.random_number(9999)).to_s
|
|
418
|
-
end
|
|
419
|
-
value
|
|
420
|
-
end
|
|
421
|
-
|
|
422
466
|
def internal_create_meeting(user=nil, user_opts={})
|
|
423
467
|
opts = {
|
|
424
|
-
:record => self.
|
|
468
|
+
:record => self.record_meeting,
|
|
425
469
|
:duration => self.duration,
|
|
426
|
-
:moderatorPW => self.
|
|
427
|
-
:attendeePW => self.
|
|
470
|
+
:moderatorPW => self.moderator_api_password,
|
|
471
|
+
:attendeePW => self.attendee_api_password,
|
|
428
472
|
:welcome => self.welcome_msg.blank? ? default_welcome_message : self.welcome_msg,
|
|
429
473
|
:dialNumber => self.dial_number,
|
|
430
474
|
:logoutURL => self.full_logout_url || self.logout_url,
|
|
431
475
|
:maxParticipants => self.max_participants,
|
|
432
|
-
:
|
|
476
|
+
:moderatorOnlyMessage => self.moderator_only_message,
|
|
477
|
+
:autoStartRecording => self.auto_start_recording,
|
|
478
|
+
:allowStartStopRecording => self.allow_start_stop_recording
|
|
433
479
|
}.merge(user_opts)
|
|
434
480
|
|
|
481
|
+
# Set the voice bridge only if the gem is configured to do so and the voice bridge
|
|
482
|
+
# is not blank.
|
|
483
|
+
if BigbluebuttonRails.use_local_voice_bridges && !self.voice_bridge.blank?
|
|
484
|
+
opts.merge!({ :voiceBridge => self.voice_bridge })
|
|
485
|
+
end
|
|
486
|
+
|
|
435
487
|
opts.merge!(self.get_metadata_for_create)
|
|
436
488
|
|
|
437
489
|
# Add information about the user that is creating the meeting (if any)
|
|
@@ -442,6 +494,12 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
442
494
|
opts.merge!({ "meta_#{BigbluebuttonRails.metadata_user_name}" => username })
|
|
443
495
|
end
|
|
444
496
|
|
|
497
|
+
# Add the invitation URL, if any
|
|
498
|
+
invitation_url = self.try(BigbluebuttonRails.invitation_url_method)
|
|
499
|
+
unless invitation_url.nil?
|
|
500
|
+
opts.merge!({ "meta_#{BigbluebuttonRails.metadata_invitation_url}" => invitation_url })
|
|
501
|
+
end
|
|
502
|
+
|
|
445
503
|
self.server.api.request_headers = @request_headers # we need the client's IP
|
|
446
504
|
response = self.server.api.create_meeting(self.name, self.meetingid, opts)
|
|
447
505
|
|
|
@@ -455,8 +513,11 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
455
513
|
# there's no message set in this room.
|
|
456
514
|
# Can be used to easily set a default message format for all rooms.
|
|
457
515
|
def default_welcome_message
|
|
458
|
-
|
|
459
|
-
|
|
516
|
+
if self.dial_number.present?
|
|
517
|
+
I18n.t('bigbluebutton_rails.rooms.default_welcome_msg_dial_number')
|
|
518
|
+
else
|
|
519
|
+
I18n.t('bigbluebutton_rails.rooms.default_welcome_msg')
|
|
520
|
+
end
|
|
460
521
|
end
|
|
461
522
|
|
|
462
523
|
# if :param wasn't set, sets it as :name downcase and parameterized
|
|
@@ -466,14 +527,14 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
466
527
|
end
|
|
467
528
|
end
|
|
468
529
|
|
|
469
|
-
# When setting a room as private we generate
|
|
470
|
-
def
|
|
530
|
+
# When setting a room as private we generate keys in case they don't exist.
|
|
531
|
+
def set_keys
|
|
471
532
|
if self.private_changed? and self.private
|
|
472
|
-
if self.
|
|
473
|
-
self.
|
|
533
|
+
if self.moderator_key.blank?
|
|
534
|
+
self.moderator_key = SecureRandom.hex(4)
|
|
474
535
|
end
|
|
475
|
-
if self.
|
|
476
|
-
self.
|
|
536
|
+
if self.attendee_key.blank?
|
|
537
|
+
self.attendee_key = SecureRandom.hex(4)
|
|
477
538
|
end
|
|
478
539
|
end
|
|
479
540
|
end
|
|
@@ -484,4 +545,20 @@ class BigbluebuttonRoom < ActiveRecord::Base
|
|
|
484
545
|
}
|
|
485
546
|
end
|
|
486
547
|
|
|
548
|
+
private
|
|
549
|
+
|
|
550
|
+
def internal_password
|
|
551
|
+
SecureRandom.uuid
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def map_key_to_internal_password(key)
|
|
555
|
+
if key == self.attendee_key
|
|
556
|
+
self.attendee_api_password
|
|
557
|
+
elsif key == self.moderator_key
|
|
558
|
+
self.moderator_api_password
|
|
559
|
+
else
|
|
560
|
+
nil
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
|
|
487
564
|
end
|