forked from External/greenlight
GRN2-129: Added server recordings and refactored adminsitrator panel (#662)
* Added server recordings and refactored adminsitrator panel * Fixed some issues * Fixed issue with owner email search * Fixed issue with edit user
This commit is contained in:
parent
8c63f793a5
commit
a055b88eb7
@ -43,9 +43,9 @@ $(document).on('turbolinks:load', function(){
|
|||||||
|
|
||||||
window.location.replace(url);
|
window.location.replace(url);
|
||||||
})
|
})
|
||||||
|
}
|
||||||
/* COLOR SELECTORS */
|
|
||||||
|
|
||||||
|
if (controller == "admins" && action == "site_settings") {
|
||||||
loadColourSelectors()
|
loadColourSelectors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
app/assets/javascripts/recording.js
Normal file
41
app/assets/javascripts/recording.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
// Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
// version.
|
||||||
|
//
|
||||||
|
// BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
// with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Handle changing of settings tabs.
|
||||||
|
$(document).on('turbolinks:load', function(){
|
||||||
|
var controller = $("body").data('controller');
|
||||||
|
var action = $("body").data('action');
|
||||||
|
|
||||||
|
if (controller == "rooms" && action == "show"
|
||||||
|
|| controller == "rooms" && action == "update"
|
||||||
|
|| controller == "users" && action == "recordings"
|
||||||
|
|| controller == "admins" && action == "server_recordings"){
|
||||||
|
// Handle recording emails.
|
||||||
|
$('.email-link').each(function(){
|
||||||
|
$(this).click(function(){
|
||||||
|
var subject = $(".username").text() + " " + t('room.mailer.subject');
|
||||||
|
var body = t('room.mailer.body') + "\n\n" + $(this).attr("data-pres-link");
|
||||||
|
var autogenerated = "\n\n" + t('room.mailer.autogenerated') + "\n";
|
||||||
|
var footer = t('room.mailer.footer');
|
||||||
|
|
||||||
|
var url = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body) + encodeURIComponent(autogenerated) + encodeURIComponent(footer);
|
||||||
|
var win = window.open(url, '_blank');
|
||||||
|
|
||||||
|
win.focus();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
@ -18,7 +18,10 @@ $(document).on('turbolinks:load', function(){
|
|||||||
var controller = $("body").data('controller');
|
var controller = $("body").data('controller');
|
||||||
var action = $("body").data('action');
|
var action = $("body").data('action');
|
||||||
|
|
||||||
if(controller == "rooms" && action == "show" || controller == "rooms" && action == "update" || controller == "users" && action == "recordings"){
|
if(controller == "rooms" && action == "show"
|
||||||
|
|| controller == "rooms" && action == "update"
|
||||||
|
|| controller == "users" && action == "recordings"
|
||||||
|
|| controller == "admins" && action == "server_recordings"){
|
||||||
|
|
||||||
// Set a room header rename event
|
// Set a room header rename event
|
||||||
var configure_room_header = function(room_title){
|
var configure_room_header = function(room_title){
|
||||||
|
@ -39,21 +39,6 @@ $(document).on('turbolinks:load', function(){
|
|||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle recording emails.
|
|
||||||
$('.email-link').each(function(){
|
|
||||||
$(this).click(function(){
|
|
||||||
var subject = $(".username").text() + " " + t('room.mailer.subject');
|
|
||||||
var body = t('room.mailer.body') + "\n\n" + $(this).attr("data-pres-link");
|
|
||||||
var autogenerated = "\n\n" + t('room.mailer.autogenerated') + "\n";
|
|
||||||
var footer = t('room.mailer.footer');
|
|
||||||
|
|
||||||
var url = "mailto:?subject=" + encodeURIComponent(subject) + "&body=" + encodeURIComponent(body) + encodeURIComponent(autogenerated) + encodeURIComponent(footer);
|
|
||||||
var win = window.open(url, '_blank');
|
|
||||||
|
|
||||||
win.focus();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display and update all fields related to creating a room in the createRoomModal
|
// Display and update all fields related to creating a room in the createRoomModal
|
||||||
|
@ -22,7 +22,8 @@ $(document).on('turbolinks:load', function(){
|
|||||||
(controller == "rooms" && action == "show") ||
|
(controller == "rooms" && action == "show") ||
|
||||||
(controller == "rooms" && action == "update") ||
|
(controller == "rooms" && action == "update") ||
|
||||||
(controller == "rooms" && action == "join") ||
|
(controller == "rooms" && action == "join") ||
|
||||||
(controller == "users" && action == "recordings")) {
|
(controller == "users" && action == "recordings") ||
|
||||||
|
(controller == "admins" && action == "server_recordings")) {
|
||||||
// Submit search if the user hits enter
|
// Submit search if the user hits enter
|
||||||
$("#search-input").keypress(function(key) {
|
$("#search-input").keypress(function(key) {
|
||||||
var keyPressed = key.which
|
var keyPressed = key.which
|
||||||
|
@ -20,7 +20,7 @@ $(document).on('turbolinks:load', function(){
|
|||||||
var action = $("body").data('action');
|
var action = $("body").data('action');
|
||||||
|
|
||||||
// Only run on the settings page.
|
// Only run on the settings page.
|
||||||
if ((controller == "users" && action == "edit") || (controller == "users" && action == "update") || (controller == "admins" && action == "index")){
|
if ((controller == "users" && action == "edit") || (controller == "users" && action == "update")){
|
||||||
var settingsButtons = $('.setting-btn');
|
var settingsButtons = $('.setting-btn');
|
||||||
var settingsViews = $('.setting-view');
|
var settingsViews = $('.setting-view');
|
||||||
|
|
||||||
|
@ -18,7 +18,10 @@ $(document).on('turbolinks:load', function(){
|
|||||||
var controller = $("body").data('controller');
|
var controller = $("body").data('controller');
|
||||||
var action = $("body").data('action');
|
var action = $("body").data('action');
|
||||||
|
|
||||||
if(controller == "rooms" && action == "show" || controller == "rooms" && action == "update" || controller == "users" && action == "recordings"){
|
if(controller == "rooms" && action == "show"
|
||||||
|
|| controller == "rooms" && action == "update"
|
||||||
|
|| controller == "users" && action == "recordings"
|
||||||
|
|| controller == "admins" && action == "server_recordings"){
|
||||||
|
|
||||||
// Choose active header
|
// Choose active header
|
||||||
// (Name, Length or Users)
|
// (Name, Length or Users)
|
||||||
|
@ -84,6 +84,7 @@ a {
|
|||||||
color: #6e7687 !important;
|
color: #6e7687 !important;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $primary-color !important;
|
color: $primary-color !important;
|
||||||
|
background-color: $primary-color-lighten !important;
|
||||||
}
|
}
|
||||||
&:active {
|
&:active {
|
||||||
background-color: $primary-color-lighten !important;
|
background-color: $primary-color-lighten !important;
|
||||||
@ -130,6 +131,7 @@ input:focus, select:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
& a {
|
& a {
|
||||||
|
color: $primary-color !important;
|
||||||
border-color: $primary-color !important;
|
border-color: $primary-color !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ class AdminsController < ApplicationController
|
|||||||
include Pagy::Backend
|
include Pagy::Backend
|
||||||
include Themer
|
include Themer
|
||||||
include Emailer
|
include Emailer
|
||||||
|
include Recorder
|
||||||
|
|
||||||
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
|
manage_users = [:edit_user, :promote, :demote, :ban_user, :unban_user, :approve]
|
||||||
site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
|
site_settings = [:branding, :coloring, :coloring_lighten, :coloring_darken,
|
||||||
@ -40,11 +41,27 @@ class AdminsController < ApplicationController
|
|||||||
@pagy, @users = pagy(user_list)
|
@pagy, @users = pagy(user_list)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# GET /admins/site_settings
|
||||||
|
def site_settings
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET /admins/server_recordings
|
||||||
|
def server_recordings
|
||||||
|
server_rooms = if Rails.configuration.loadbalanced_configuration
|
||||||
|
Room.includes(:owner).where(users: { provider: user_settings_provider }).pluck(:bbb_id)
|
||||||
|
else
|
||||||
|
Room.pluck(:bbb_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
@search, @order_column, @order_direction, recs =
|
||||||
|
all_recordings(server_rooms, @user_domain, params.permit(:search, :column, :direction), true, true)
|
||||||
|
@pagy, @recordings = pagy_array(recs)
|
||||||
|
end
|
||||||
|
|
||||||
# MANAGE USERS
|
# MANAGE USERS
|
||||||
|
|
||||||
# GET /admins/edit/:user_uid
|
# GET /admins/edit/:user_uid
|
||||||
def edit_user
|
def edit_user
|
||||||
render "admins/index", locals: { setting_id: "account" }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /admins/promote/:user_uid
|
# POST /admins/promote/:user_uid
|
||||||
@ -111,7 +128,7 @@ class AdminsController < ApplicationController
|
|||||||
# POST /admins/branding
|
# POST /admins/branding
|
||||||
def branding
|
def branding
|
||||||
@settings.update_value("Branding Image", params[:url])
|
@settings.update_value("Branding Image", params[:url])
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /admins/color
|
# POST /admins/color
|
||||||
@ -119,23 +136,23 @@ class AdminsController < ApplicationController
|
|||||||
@settings.update_value("Primary Color", params[:color])
|
@settings.update_value("Primary Color", params[:color])
|
||||||
@settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
|
@settings.update_value("Primary Color Lighten", color_lighten(params[:color]))
|
||||||
@settings.update_value("Primary Color Darken", color_darken(params[:color]))
|
@settings.update_value("Primary Color Darken", color_darken(params[:color]))
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
def coloring_lighten
|
def coloring_lighten
|
||||||
@settings.update_value("Primary Color Lighten", params[:color])
|
@settings.update_value("Primary Color Lighten", params[:color])
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
def coloring_darken
|
def coloring_darken
|
||||||
@settings.update_value("Primary Color Darken", params[:color])
|
@settings.update_value("Primary Color Darken", params[:color])
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /admins/room_authentication
|
# POST /admins/room_authentication
|
||||||
def room_authentication
|
def room_authentication
|
||||||
@settings.update_value("Room Authentication", params[:value])
|
@settings.update_value("Room Authentication", params[:value])
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST /admins/registration_method/:method
|
# POST /admins/registration_method/:method
|
||||||
@ -144,11 +161,11 @@ class AdminsController < ApplicationController
|
|||||||
|
|
||||||
# Only allow change to Join by Invitation if user has emails enabled
|
# Only allow change to Join by Invitation if user has emails enabled
|
||||||
if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
|
if !Rails.configuration.enable_email_verification && new_method == Rails.configuration.registration_methods[:invite]
|
||||||
redirect_to admins_path,
|
redirect_to admin_site_settings_path,
|
||||||
flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
|
flash: { alert: I18n.t("administrator.flash.invite_email_verification") }
|
||||||
else
|
else
|
||||||
@settings.update_value("Registration Method", new_method)
|
@settings.update_value("Registration Method", new_method)
|
||||||
redirect_to admins_path,
|
redirect_to admin_site_settings_path,
|
||||||
flash: { success: I18n.t("administrator.flash.registration_method_updated") }
|
flash: { success: I18n.t("administrator.flash.registration_method_updated") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -156,7 +173,7 @@ class AdminsController < ApplicationController
|
|||||||
# POST /admins/room_limit
|
# POST /admins/room_limit
|
||||||
def room_limit
|
def room_limit
|
||||||
@settings.update_value("Room Limit", params[:limit])
|
@settings.update_value("Room Limit", params[:limit])
|
||||||
redirect_to admins_path, flash: { success: I18n.t("administrator.flash.settings") }
|
redirect_to admin_site_settings_path, flash: { success: I18n.t("administrator.flash.settings") }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -16,11 +16,50 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License along
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
module APIConcern
|
module Recorder
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
include ::BbbApi
|
||||||
|
|
||||||
|
# Fetches all recordings for a room.
|
||||||
|
def recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
|
||||||
|
res = bbb(provider).get_recordings(meetingID: room_bbb_id)
|
||||||
|
|
||||||
|
format_recordings(res, search_params, ret_search_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetches a rooms public recordings.
|
||||||
|
def public_recordings(room_bbb_id, provider, search_params = {}, ret_search_params = false)
|
||||||
|
search, order_col, order_dir, recs = recordings(room_bbb_id, provider, search_params, ret_search_params)
|
||||||
|
[search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Makes paginated API calls to get recordings
|
||||||
|
def all_recordings(room_bbb_ids, provider, search_params = {}, ret_search_params = false, search_name = false)
|
||||||
|
pag_num = Rails.configuration.pagination_number
|
||||||
|
|
||||||
|
pag_loops = room_bbb_ids.length / pag_num - 1
|
||||||
|
|
||||||
|
res = { recordings: [] }
|
||||||
|
|
||||||
|
(0..pag_loops).each do |i|
|
||||||
|
pag_rooms = room_bbb_ids[pag_num * i, pag_num]
|
||||||
|
|
||||||
|
# bbb.get_recordings returns an object
|
||||||
|
# take only the array portion of the object that is returned
|
||||||
|
full_res = bbb(provider).get_recordings(meetingID: pag_rooms)
|
||||||
|
res[:recordings].push(*full_res[:recordings])
|
||||||
|
end
|
||||||
|
|
||||||
|
last_pag_room = room_bbb_ids[pag_num * (pag_loops + 1), room_bbb_ids.length % pag_num]
|
||||||
|
|
||||||
|
full_res = bbb(provider).get_recordings(meetingID: last_pag_room)
|
||||||
|
res[:recordings].push(*full_res[:recordings])
|
||||||
|
|
||||||
|
format_recordings(res, search_params, ret_search_params, search_name)
|
||||||
|
end
|
||||||
|
|
||||||
# Format, filter, and sort recordings to match their current use in the app
|
# Format, filter, and sort recordings to match their current use in the app
|
||||||
def format_recordings(api_res, search_params, ret_search_params)
|
def format_recordings(api_res, search_params, ret_search_params, search_name = false)
|
||||||
search = search_params[:search] || ""
|
search = search_params[:search] || ""
|
||||||
order_col = search_params[:column] && search_params[:direction] != "none" ? search_params[:column] : "end_time"
|
order_col = search_params[:column] && search_params[:direction] != "none" ? search_params[:column] : "end_time"
|
||||||
order_dir = search_params[:column] && search_params[:direction] != "none" ? search_params[:direction] : "desc"
|
order_dir = search_params[:column] && search_params[:direction] != "none" ? search_params[:direction] : "desc"
|
||||||
@ -40,7 +79,7 @@ module APIConcern
|
|||||||
r.delete(:playback)
|
r.delete(:playback)
|
||||||
end
|
end
|
||||||
|
|
||||||
recs = filter_recordings(api_res, search)
|
recs = filter_recordings(api_res, search, search_name)
|
||||||
recs = sort_recordings(recs, order_col, order_dir)
|
recs = sort_recordings(recs, order_col, order_dir)
|
||||||
|
|
||||||
if ret_search_params
|
if ret_search_params
|
||||||
@ -50,7 +89,7 @@ module APIConcern
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_recordings(api_res, search)
|
def filter_recordings(api_res, search, search_name = false)
|
||||||
api_res[:recordings].select do |r|
|
api_res[:recordings].select do |r|
|
||||||
(!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
|
(!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
|
||||||
r[:metadata][:name].downcase.include?(search)) ||
|
r[:metadata][:name].downcase.include?(search)) ||
|
||||||
@ -59,7 +98,8 @@ module APIConcern
|
|||||||
((r[:metadata].nil? || r[:metadata][:name].nil?) &&
|
((r[:metadata].nil? || r[:metadata][:name].nil?) &&
|
||||||
r[:name].downcase.include?(search)) ||
|
r[:name].downcase.include?(search)) ||
|
||||||
r[:participants].include?(search) ||
|
r[:participants].include?(search) ||
|
||||||
!r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty?
|
!r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty? ||
|
||||||
|
(search_name && Room.find_by(bbb_id: r[:meetingID]).owner.email.downcase.include?(search))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -50,6 +50,11 @@ class RecordingsController < ApplicationController
|
|||||||
|
|
||||||
# Ensure the user is logged into the room they are accessing.
|
# Ensure the user is logged into the room they are accessing.
|
||||||
def verify_room_ownership
|
def verify_room_ownership
|
||||||
redirect_to root_path unless @room.owned_by?(current_user)
|
if !current_user ||
|
||||||
|
!@room.owned_by?(current_user) ||
|
||||||
|
!current_user.has_cached_role?(:admin) ||
|
||||||
|
!current_user.has_cached_role?(:super_admin)
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
class RoomsController < ApplicationController
|
class RoomsController < ApplicationController
|
||||||
include RecordingsHelper
|
include RecordingsHelper
|
||||||
include Pagy::Backend
|
include Pagy::Backend
|
||||||
|
include Recorder
|
||||||
|
|
||||||
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
|
before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
|
||||||
before_action :validate_verified_email, except: [:show, :join],
|
before_action :validate_verified_email, except: [:show, :join],
|
||||||
@ -56,7 +57,7 @@ class RoomsController < ApplicationController
|
|||||||
def show
|
def show
|
||||||
if current_user && @room.owned_by?(current_user)
|
if current_user && @room.owned_by?(current_user)
|
||||||
@search, @order_column, @order_direction, recs =
|
@search, @order_column, @order_direction, recs =
|
||||||
@room.recordings(params.permit(:search, :column, :direction), true)
|
recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
|
||||||
|
|
||||||
@pagy, @recordings = pagy_array(recs)
|
@pagy, @recordings = pagy_array(recs)
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ class RoomsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
@search, @order_column, @order_direction, pub_recs =
|
@search, @order_column, @order_direction, pub_recs =
|
||||||
@room.public_recordings(params.permit(:search, :column, :direction), true)
|
public_recordings(@room.bbb_id, @user_domain, params.permit(:search, :column, :direction), true)
|
||||||
|
|
||||||
@pagy, @public_recordings = pagy_array(pub_recs)
|
@pagy, @public_recordings = pagy_array(pub_recs)
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ class RoomsController < ApplicationController
|
|||||||
|
|
||||||
search_params = params[@room.invite_path] || params
|
search_params = params[@room.invite_path] || params
|
||||||
@search, @order_column, @order_direction, pub_recs =
|
@search, @order_column, @order_direction, pub_recs =
|
||||||
@room.public_recordings(search_params.permit(:search, :column, :direction), true)
|
public_recordings(@room.bbb_id, @user_domain, search_params.permit(:search, :column, :direction), true)
|
||||||
|
|
||||||
@pagy, @public_recordings = pagy_array(pub_recs)
|
@pagy, @public_recordings = pagy_array(pub_recs)
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ class UsersController < ApplicationController
|
|||||||
include Pagy::Backend
|
include Pagy::Backend
|
||||||
include Emailer
|
include Emailer
|
||||||
include Registrar
|
include Registrar
|
||||||
|
include Recorder
|
||||||
|
|
||||||
before_action :find_user, only: [:edit, :update, :destroy]
|
before_action :find_user, only: [:edit, :update, :destroy]
|
||||||
before_action :ensure_unauthenticated, only: [:new, :create]
|
before_action :ensure_unauthenticated, only: [:new, :create]
|
||||||
@ -103,6 +104,8 @@ class UsersController < ApplicationController
|
|||||||
|
|
||||||
# PATCH /u/:user_uid/edit
|
# PATCH /u/:user_uid/edit
|
||||||
def update
|
def update
|
||||||
|
redirect_path = current_user.admin_of?(@user) ? admins_path : edit_user_path(@user)
|
||||||
|
|
||||||
if params[:setting] == "password"
|
if params[:setting] == "password"
|
||||||
# Update the users password.
|
# Update the users password.
|
||||||
errors = {}
|
errors = {}
|
||||||
@ -123,7 +126,7 @@ class UsersController < ApplicationController
|
|||||||
if errors.empty? && @user.save
|
if errors.empty? && @user.save
|
||||||
# Notify the user that their account has been updated.
|
# Notify the user that their account has been updated.
|
||||||
flash[:success] = I18n.t("info_update_success")
|
flash[:success] = I18n.t("info_update_success")
|
||||||
redirect_to edit_user_path(@user)
|
redirect_to redirect_path
|
||||||
else
|
else
|
||||||
# Append custom errors.
|
# Append custom errors.
|
||||||
errors.each { |k, v| @user.errors.add(k, v) }
|
errors.each { |k, v| @user.errors.add(k, v) }
|
||||||
@ -132,11 +135,11 @@ class UsersController < ApplicationController
|
|||||||
elsif user_params[:email] != @user.email && @user.update_attributes(user_params)
|
elsif user_params[:email] != @user.email && @user.update_attributes(user_params)
|
||||||
@user.update_attributes(email_verified: false)
|
@user.update_attributes(email_verified: false)
|
||||||
flash[:success] = I18n.t("info_update_success")
|
flash[:success] = I18n.t("info_update_success")
|
||||||
redirect_to edit_user_path(@user)
|
redirect_to redirect_path
|
||||||
elsif @user.update_attributes(user_params)
|
elsif @user.update_attributes(user_params)
|
||||||
update_locale(@user)
|
update_locale(@user)
|
||||||
flash[:success] = I18n.t("info_update_success")
|
flash[:success] = I18n.t("info_update_success")
|
||||||
redirect_to edit_user_path(@user)
|
redirect_to redirect_path
|
||||||
else
|
else
|
||||||
render :edit, params: { settings: params[:settings] }
|
render :edit, params: { settings: params[:settings] }
|
||||||
end
|
end
|
||||||
@ -165,7 +168,8 @@ class UsersController < ApplicationController
|
|||||||
def recordings
|
def recordings
|
||||||
if current_user && current_user.uid == params[:user_uid]
|
if current_user && current_user.uid == params[:user_uid]
|
||||||
@search, @order_column, @order_direction, recs =
|
@search, @order_column, @order_direction, recs =
|
||||||
current_user.all_recordings(params.permit(:search, :column, :direction), true)
|
all_recordings(current_user.rooms.pluck(:bbb_id), current_user.provider,
|
||||||
|
params.permit(:search, :column, :direction), true)
|
||||||
@pagy, @recordings = pagy_array(recs)
|
@pagy, @recordings = pagy_array(recs)
|
||||||
else
|
else
|
||||||
redirect_to root_path
|
redirect_to root_path
|
||||||
|
@ -19,6 +19,18 @@
|
|||||||
module AdminsHelper
|
module AdminsHelper
|
||||||
include Pagy::Frontend
|
include Pagy::Frontend
|
||||||
|
|
||||||
|
# Returns the action method of the current page
|
||||||
|
def active_page
|
||||||
|
route = Rails.application.routes.recognize_path(request.env['PATH_INFO'])
|
||||||
|
|
||||||
|
route[:action]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gets the email of the room owner to which the recording belongs to
|
||||||
|
def recording_owner_email(room_id)
|
||||||
|
Room.find_by(bbb_id: room_id).owner.email
|
||||||
|
end
|
||||||
|
|
||||||
def display_invite
|
def display_invite
|
||||||
current_page?(admins_path) && invite_registration
|
current_page?(admins_path) && invite_registration
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
require 'bbb_api'
|
require 'bbb_api'
|
||||||
|
|
||||||
class Room < ApplicationRecord
|
class Room < ApplicationRecord
|
||||||
include ::APIConcern
|
|
||||||
include ::BbbApi
|
include ::BbbApi
|
||||||
|
|
||||||
before_create :setup
|
before_create :setup
|
||||||
@ -40,7 +39,7 @@ class Room < ApplicationRecord
|
|||||||
|
|
||||||
# Checks if a room is running on the BigBlueButton server.
|
# Checks if a room is running on the BigBlueButton server.
|
||||||
def running?
|
def running?
|
||||||
bbb.is_meeting_running?(bbb_id)
|
bbb(owner.provider).is_meeting_running?(bbb_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determines the invite path for the room.
|
# Determines the invite path for the room.
|
||||||
@ -62,7 +61,7 @@ class Room < ApplicationRecord
|
|||||||
|
|
||||||
# Send the create request.
|
# Send the create request.
|
||||||
begin
|
begin
|
||||||
meeting = bbb.create_meeting(name, bbb_id, create_options)
|
meeting = bbb(owner.provider).create_meeting(name, bbb_id, create_options)
|
||||||
# Update session info.
|
# Update session info.
|
||||||
unless meeting[:messageKey] == 'duplicateWarning'
|
unless meeting[:messageKey] == 'duplicateWarning'
|
||||||
update_attributes(sessions: sessions + 1, last_session: DateTime.now)
|
update_attributes(sessions: sessions + 1, last_session: DateTime.now)
|
||||||
@ -84,10 +83,10 @@ class Room < ApplicationRecord
|
|||||||
options[:user_is_moderator] ||= false
|
options[:user_is_moderator] ||= false
|
||||||
options[:meeting_recorded] ||= false
|
options[:meeting_recorded] ||= false
|
||||||
|
|
||||||
return call_invalid_res unless bbb
|
return call_invalid_res unless bbb(owner.provider)
|
||||||
|
|
||||||
# Get the meeting info.
|
# Get the meeting info.
|
||||||
meeting_info = bbb.get_meeting_info(bbb_id, nil)
|
meeting_info = bbb(owner.provider).get_meeting_info(bbb_id, nil)
|
||||||
|
|
||||||
# Determine the password to use when joining.
|
# Determine the password to use when joining.
|
||||||
password = if options[:user_is_moderator]
|
password = if options[:user_is_moderator]
|
||||||
@ -101,7 +100,7 @@ class Room < ApplicationRecord
|
|||||||
join_opts[:userID] = uid if uid
|
join_opts[:userID] = uid if uid
|
||||||
join_opts[:joinViaHtml5] = options[:join_via_html5] if options[:join_via_html5]
|
join_opts[:joinViaHtml5] = options[:join_via_html5] if options[:join_via_html5]
|
||||||
|
|
||||||
bbb.join_meeting_url(bbb_id, name, password, join_opts)
|
bbb(owner.provider).join_meeting_url(bbb_id, name, password, join_opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Notify waiting users that a meeting has started.
|
# Notify waiting users that a meeting has started.
|
||||||
@ -111,7 +110,7 @@ class Room < ApplicationRecord
|
|||||||
|
|
||||||
# Retrieves all the users in a room.
|
# Retrieves all the users in a room.
|
||||||
def participants
|
def participants
|
||||||
res = bbb.get_meeting_info(bbb_id, nil)
|
res = bbb(owner.provider).get_meeting_info(bbb_id, nil)
|
||||||
res[:attendees].map do |att|
|
res[:attendees].map do |att|
|
||||||
User.find_by(uid: att[:userID], name: att[:fullName])
|
User.find_by(uid: att[:userID], name: att[:fullName])
|
||||||
end
|
end
|
||||||
@ -120,27 +119,18 @@ class Room < ApplicationRecord
|
|||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fetches all recordings for a room.
|
def recording_count
|
||||||
def recordings(search_params = {}, ret_search_params = false)
|
bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].length
|
||||||
res = bbb.get_recordings(meetingID: bbb_id)
|
|
||||||
|
|
||||||
format_recordings(res, search_params, ret_search_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Fetches a rooms public recordings.
|
|
||||||
def public_recordings(search_params = {}, ret_search_params = false)
|
|
||||||
search, order_col, order_dir, recs = recordings(search_params, ret_search_params)
|
|
||||||
[search, order_col, order_dir, recs.select { |r| r[:metadata][:"gl-listed"] == "true" }]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_recording(record_id, meta)
|
def update_recording(record_id, meta)
|
||||||
meta[:recordID] = record_id
|
meta[:recordID] = record_id
|
||||||
bbb.send_api_request("updateRecordings", meta)
|
bbb(owner.provider).send_api_request("updateRecordings", meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Deletes a recording from a room.
|
# Deletes a recording from a room.
|
||||||
def delete_recording(record_id)
|
def delete_recording(record_id)
|
||||||
bbb.delete_recordings(record_id)
|
bbb(owner.provider).delete_recordings(record_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -155,7 +145,7 @@ class Room < ApplicationRecord
|
|||||||
|
|
||||||
# Deletes all recordings associated with the room.
|
# Deletes all recordings associated with the room.
|
||||||
def delete_all_recordings
|
def delete_all_recordings
|
||||||
record_ids = recordings.map { |r| r[:recordID] }
|
record_ids = bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].pluck(:recordID)
|
||||||
delete_recording(record_ids) unless record_ids.empty?
|
delete_recording(record_ids) unless record_ids.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ require 'bbb_api'
|
|||||||
|
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
rolify
|
rolify
|
||||||
include ::APIConcern
|
|
||||||
include ::BbbApi
|
include ::BbbApi
|
||||||
|
|
||||||
attr_accessor :reset_token
|
attr_accessor :reset_token
|
||||||
@ -118,31 +117,8 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.admins_order(column, direction)
|
def self.admins_order(column, direction)
|
||||||
order("#{column} #{direction}")
|
# Arel.sql to avoid sql injection
|
||||||
end
|
order(Arel.sql("#{column} #{direction}"))
|
||||||
|
|
||||||
def all_recordings(search_params = {}, ret_search_params = false)
|
|
||||||
pag_num = Rails.configuration.pagination_number
|
|
||||||
|
|
||||||
pag_loops = rooms.length / pag_num - 1
|
|
||||||
|
|
||||||
res = { recordings: [] }
|
|
||||||
|
|
||||||
(0..pag_loops).each do |i|
|
|
||||||
pag_rooms = rooms[pag_num * i, pag_num]
|
|
||||||
|
|
||||||
# bbb.get_recordings returns an object
|
|
||||||
# take only the array portion of the object that is returned
|
|
||||||
full_res = bbb.get_recordings(meetingID: pag_rooms.pluck(:bbb_id))
|
|
||||||
res[:recordings].push(*full_res[:recordings])
|
|
||||||
end
|
|
||||||
|
|
||||||
last_pag_room = rooms[pag_num * (pag_loops + 1), rooms.length % pag_num]
|
|
||||||
|
|
||||||
full_res = bbb.get_recordings(meetingID: last_pag_room.pluck(:bbb_id))
|
|
||||||
res[:recordings].push(*full_res[:recordings])
|
|
||||||
|
|
||||||
format_recordings(res, search_params, ret_search_params)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Activates an account and initialize a users main room
|
# Activates an account and initialize a users main room
|
||||||
|
26
app/views/admins/components/_menu_buttons.html.erb
Normal file
26
app/views/admins/components/_menu_buttons.html.erb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="list-group list-group-transparent mb-0">
|
||||||
|
<%= link_to admins_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "index"}" do %>
|
||||||
|
<span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to admin_site_settings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "site_settings"}" do %>
|
||||||
|
<span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
|
||||||
|
<% end %>
|
||||||
|
<%= link_to admin_recordings_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "server_recordings"}" do %>
|
||||||
|
<span class="icon mr-4"><i class="fas fa-video"></i></i></span><%= t("administrator.recordings.title") %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
91
app/views/admins/components/_recordings.html.erb
Normal file
91
app/views/admins/components/_recordings.html.erb
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="recordings-table" class="table table-hover table-outline table-vcenter text-nowrap card-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-header="name" data-order="<%= @order_column == "name" ? @order_direction : "none" %>">
|
||||||
|
<%= t("recording.table.name") %>
|
||||||
|
<% if @order_column == "name" && @order_direction == "desc" %>
|
||||||
|
↓
|
||||||
|
<% elsif @order_column == "name" && @order_direction == "asc" %>
|
||||||
|
↑
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<th class="text-left" data-header="length" data-order="<%= @order_column == "length" ? @order_direction : "none" %>">
|
||||||
|
<%= t("recording.table.length") %>
|
||||||
|
<% if @order_column == "length" && @order_direction == "desc" %>
|
||||||
|
↓
|
||||||
|
<% elsif @order_column == "length" && @order_direction == "asc" %>
|
||||||
|
↑
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<th class="text-left" data-header="users" data-order="<%= @order_column == "users" ? @order_direction : "none" %>">
|
||||||
|
<%= t("recording.table.users") %>
|
||||||
|
<% if @order_column == "users" && @order_direction == "desc" %>
|
||||||
|
↓
|
||||||
|
<% elsif @order_column == "users" && @order_direction == "asc" %>
|
||||||
|
↑
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<th class="text-left" data-header="visibility" data-order="<%= @order_column == "visibility" ? @order_direction : "none" %>">
|
||||||
|
<%= t("recording.table.visibility") %>
|
||||||
|
<% if @order_column == "visibility" && @order_direction == "desc" %>
|
||||||
|
↓
|
||||||
|
<% elsif @order_column == "visibility" && @order_direction == "asc" %>
|
||||||
|
↑
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<th data-header="formats" data-order="<%= @order_column == "formats" ? @order_direction : "none" %>">
|
||||||
|
<%= t("recording.table.formats") %>
|
||||||
|
<% if @order_column == "formats" && @order_direction == "desc" %>
|
||||||
|
↓
|
||||||
|
<% elsif @order_column == "formats" && @order_direction == "asc" %>
|
||||||
|
↑
|
||||||
|
<% end %>
|
||||||
|
</th>
|
||||||
|
<th class="text-center"><i class="icon-settings"></i></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="recording-table">
|
||||||
|
<tr id="no_recordings_found" style="display: none;">
|
||||||
|
<td colspan="7" class="text-center h4 p-6 font-weight-normal" >
|
||||||
|
<%= t("recording.no_matched_recordings", inject:"") %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% if @recordings.empty? %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="7" class="text-center h4 p-6 font-weight-normal">
|
||||||
|
<%= t("administrator.recordings.no_recordings") %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% else %>
|
||||||
|
<% @recordings.each do |recording| %>
|
||||||
|
<%= render "admins/components/server_recording_row", recording: recording %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% if !@recordings.empty?%>
|
||||||
|
<div class="float-right mr-4 mt-4">
|
||||||
|
<%== pagy_bootstrap_nav(@pagy) %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
81
app/views/admins/components/_server_recording_row.html.erb
Normal file
81
app/views/admins/components/_server_recording_row.html.erb
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div id="recording-title" class="form-inline edit_hover_class" data-recordid="<%= recording[:recordID] %>" data-room-uid="<%= room_uid_from_bbb(recording[:meetingID]) %>" data-path="<%= update_room_path(room_uid: room_uid_from_bbb(recording[:meetingID])) %>">
|
||||||
|
<text id='recording-text'>
|
||||||
|
<% if recording[:metadata][:name] %>
|
||||||
|
<%= recording[:metadata][:name] %>
|
||||||
|
<% else %>
|
||||||
|
<%= recording[:name] %>
|
||||||
|
<% end %>
|
||||||
|
</text>
|
||||||
|
<a><i id="edit-record" class="fa fa-edit align-top ml-2" data-edit-recordid="<%= recording[:recordID] %>"></i></a>
|
||||||
|
</div>
|
||||||
|
<div class="small text-muted">
|
||||||
|
<%= t("recording.recorded_on", date: recording_date(recording[:startTime])) %>
|
||||||
|
</div>
|
||||||
|
<div class="small text-muted">
|
||||||
|
<%= recording_owner_email(recording[:meetingID]) %>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td id="recording-length" class="text-left" data-full-length="<%= recording[:playbacks].empty? ? 0 : recording[:playbacks].first[:length]%>">
|
||||||
|
<%= recording_length(recording[:playbacks]) %>
|
||||||
|
</td>
|
||||||
|
<td id="recording-users" class="text-left">
|
||||||
|
<%= recording[:participants] || "-" %>
|
||||||
|
</td>
|
||||||
|
<td class="text-left">
|
||||||
|
<div class="dropdown">
|
||||||
|
<% if recording[:metadata][:"gl-listed"] == "true" %>
|
||||||
|
<button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-globe px-2"></i> <%= t("recording.visibility.public") %></button>
|
||||||
|
<% else %>
|
||||||
|
<button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown"><i class="dropdown-icon fas fa-link px-2"></i> <%= t("recording.visibility.unlisted") %></button>
|
||||||
|
<% end %>
|
||||||
|
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||||
|
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "public"), class: "dropdown-item" do %>
|
||||||
|
<i class="dropdown-icon fas fa-globe"></i> <%= t("recording.visibility.public") %>
|
||||||
|
<% end %>
|
||||||
|
<%= button_to update_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID], state: "unlisted"), class: "dropdown-item" do %>
|
||||||
|
<i class="dropdown-icon fas fa-link"></i> <%= t("recording.visibility.unlisted") %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<% sorted_formats = recording[:playbacks].sort_by! { |p| p[:type] } %>
|
||||||
|
<% sorted_formats.each do |p| %>
|
||||||
|
<%= link_to t("recording.format.#{p[:type]}"), p[:url], class: "btn btn-sm btn-primary", target: "_blank" %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<div class="item-action dropdown">
|
||||||
|
<a href="javascript:void(0)" data-toggle="dropdown" class="icon">
|
||||||
|
<i class="fas fa-ellipsis-v px-4"></i>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<% p = recording[:playbacks].find do |p| p.key?(:length) end %>
|
||||||
|
<% if p %>
|
||||||
|
<a class="dropdown-item email-link" data-pres-link="<%= p[:url] %>"><i class="dropdown-icon far fa-envelope"></i> <%= t("recording.email") %></a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<% end %>
|
||||||
|
<%= button_to delete_recording_path(meetingID: recording[:meetingID], record_id: recording[:recordID]), method: :delete, class: "dropdown-item" do %>
|
||||||
|
<i class="dropdown-icon far fa-trash-alt"></i> <%= t("delete") %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
26
app/views/admins/components/_setting_view.html.erb
Normal file
26
app/views/admins/components/_setting_view.html.erb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<%= content_tag(:div, id: setting_id, class: "setting-view card") do %>
|
||||||
|
<div class="card-body p-6">
|
||||||
|
<div class="card-title text-primary">
|
||||||
|
<div class="form-group">
|
||||||
|
<%= render "shared/components/subtitle", subtitle: setting_title, search: search %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= render "admins/components/#{setting_id}" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
@ -13,6 +13,21 @@
|
|||||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
%>
|
%>
|
||||||
|
|
||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
<% if @role.present? %>
|
<% if @role.present? %>
|
||||||
<%= render "shared/components/admins_tags" %>
|
<%= render "shared/components/admins_tags" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
@ -146,3 +161,4 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= render "shared/modals/invite_user_modal" %>
|
<%= render "shared/modals/invite_user_modal" %>
|
||||||
|
|
27
app/views/admins/edit_user.html.erb
Normal file
27
app/views/admins/edit_user.html.erb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="container pt-6">
|
||||||
|
<%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3 mb-4">
|
||||||
|
<%= render "admins/components/menu_buttons" %>
|
||||||
|
</div>
|
||||||
|
<div id="edit_user" class="col-lg-9">
|
||||||
|
<%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -18,26 +18,10 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-3 mb-4">
|
<div class="col-lg-3 mb-4">
|
||||||
<div class="list-group list-group-transparent mb-0">
|
<%= render "admins/components/menu_buttons" %>
|
||||||
<button id="users" class="list-group-item list-group-item-action setting-btn <%= "active" if !params[:setting] || params[:setting] == "users"%>">
|
|
||||||
<span class="icon mr-3"><i class="fas fa-users"></i></span><%= t("administrator.users.title") %>
|
|
||||||
</button>
|
|
||||||
<button id="site_settings" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "site_settings"%>">
|
|
||||||
<span class="icon mr-4"><i class="fas fa-cogs"></i></span><%= t("administrator.site_settings.title") %>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div id="users" class="col-lg-9">
|
||||||
|
<%= render "admins/components/setting_view", setting_id: "users", setting_title: t("administrator.users.title"), search: true %>
|
||||||
<div class="col-lg-9">
|
|
||||||
<% if defined?(setting_id) && setting_id == "account" %>
|
|
||||||
<%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("administrator.users.edit.title") %>
|
|
||||||
<% else %>
|
|
||||||
<%= render "shared/settings/setting_view", admin_view: true, setting_id: "users", setting_title: t("administrator.users.title") %>
|
|
||||||
<%= render "shared/settings/setting_view", admin_view: true, setting_id: "site_settings", setting_title: t("administrator.site_settings.subtitle") %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "shared/modals/delete_account_modal", delete_location: relative_root %>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
27
app/views/admins/server_recordings.html.erb
Normal file
27
app/views/admins/server_recordings.html.erb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="container pt-6">
|
||||||
|
<%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3 mb-4">
|
||||||
|
<%= render "admins/components/menu_buttons" %>
|
||||||
|
</div>
|
||||||
|
<div id="server_recordings" class="col-lg-9">
|
||||||
|
<%= render "admins/components/setting_view", setting_id: "recordings", setting_title: t("administrator.recordings.title"), search: true %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
27
app/views/admins/site_settings.html.erb
Normal file
27
app/views/admins/site_settings.html.erb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<%
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="container pt-6">
|
||||||
|
<%= render "shared/components/subtitle", subtitle: t("administrator.title"), search: false %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3 mb-4">
|
||||||
|
<%= render "admins/components/menu_buttons" %>
|
||||||
|
</div>
|
||||||
|
<div id="site_settings" class="col-lg-9">
|
||||||
|
<%= render "admins/components/setting_view", setting_id: "settings", setting_title: t("administrator.site_settings.subtitle"), search: false %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -89,7 +89,7 @@
|
|||||||
<%= render "shared/components/room_block", room: room %>
|
<%= render "shared/components/room_block", room: room %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<%= render "shared/modals/delete_room_modal", room: room %>
|
<%= render "shared/modals/delete_room_modal", recording_count: room.recording_count, room: room %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% unless room_limit_exceeded %>
|
<% unless room_limit_exceeded %>
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<p>
|
<p>
|
||||||
<%= t("modal.delete_room.warning").html_safe %>
|
<%= t("modal.delete_room.warning").html_safe %>
|
||||||
<% if room.recordings.length > 0 %>
|
<% if recording_count > 0 %>
|
||||||
<%= t("modal.delete_room.recording_warning", recordings_num: room.recordings.length).html_safe %>
|
<%= t("modal.delete_room.recording_warning", recordings_num: recording_count).html_safe %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,17 +20,17 @@
|
|||||||
<div class="col-lg-3 mb-4">
|
<div class="col-lg-3 mb-4">
|
||||||
<div class="list-group list-group-transparent mb-0">
|
<div class="list-group list-group-transparent mb-0">
|
||||||
|
|
||||||
<button id="account" class="list-group-item list-group-item-action setting-btn <%= "active" if !params[:setting] || params[:setting] == "account"%>">
|
<button id="account" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if !params[:setting] || params[:setting] == "account"%>">
|
||||||
<span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
|
<span class="icon mr-3"><i class="fas fa-user"></i></span><%= t("settings.account.title") %>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<% if @user.social_uid.nil? %>
|
<% if @user.social_uid.nil? %>
|
||||||
<button id="password" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "password"%>">
|
<button id="password" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "password"%>">
|
||||||
<span class="icon mr-3"><i class="fas fa-lock"></i></span><%= t("settings.password.title") %>
|
<span class="icon mr-3"><i class="fas fa-lock"></i></span><%= t("settings.password.title") %>
|
||||||
</button>
|
</button>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<button id="delete" class="list-group-item list-group-item-action setting-btn <%= "active" if params[:setting] == "delete"%>">
|
<button id="delete" class="list-group-item list-group-item-action dropdown-item setting-btn <%= "active" if params[:setting] == "delete"%>">
|
||||||
<span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
|
<span class="icon mr-3"><i class="fas fa-trash-alt"></i></span><%= t("settings.delete.title") %>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,6 +73,9 @@ en:
|
|||||||
registration_method_updated: Registration method successfully updated
|
registration_method_updated: Registration method successfully updated
|
||||||
settings: Site Settings successfully changed
|
settings: Site Settings successfully changed
|
||||||
unauthorized: You are not authorized to perform actions on this user
|
unauthorized: You are not authorized to perform actions on this user
|
||||||
|
recordings:
|
||||||
|
title: Server Recordings
|
||||||
|
no_recordings: This server has no recordings.
|
||||||
title: Organization Settings
|
title: Organization Settings
|
||||||
users:
|
users:
|
||||||
invite: Invite User
|
invite: Invite User
|
||||||
|
@ -37,6 +37,8 @@ Rails.application.routes.draw do
|
|||||||
resources :admins, only: [:index]
|
resources :admins, only: [:index]
|
||||||
|
|
||||||
scope '/admins' do
|
scope '/admins' do
|
||||||
|
get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
|
||||||
|
get '/recordings', to: 'admins#server_recordings', as: :admin_recordings
|
||||||
post '/branding', to: 'admins#branding', as: :admin_branding
|
post '/branding', to: 'admins#branding', as: :admin_branding
|
||||||
post '/coloring', to: 'admins#coloring', as: :admin_coloring
|
post '/coloring', to: 'admins#coloring', as: :admin_coloring
|
||||||
post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication
|
post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication
|
||||||
|
@ -12,15 +12,9 @@ module BbbApi
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Sets a BigBlueButtonApi object for interacting with the API.
|
# Sets a BigBlueButtonApi object for interacting with the API.
|
||||||
def bbb
|
def bbb(user_provider)
|
||||||
if Rails.configuration.loadbalanced_configuration
|
if Rails.configuration.loadbalanced_configuration
|
||||||
if instance_of? Room
|
user_domain = retrieve_provider_info(user_provider)
|
||||||
# currently in the Room Model
|
|
||||||
user_domain = retrieve_provider_info(owner.provider)
|
|
||||||
elsif instance_of? User
|
|
||||||
# currently in the User Model
|
|
||||||
user_domain = retrieve_provider_info(provider)
|
|
||||||
end
|
|
||||||
|
|
||||||
BigBlueButton::BigBlueButtonApi.new(remove_slash(user_domain["apiURL"]), user_domain["secret"], "0.8")
|
BigBlueButton::BigBlueButtonApi.new(remove_slash(user_domain["apiURL"]), user_domain["secret"], "0.8")
|
||||||
else
|
else
|
||||||
|
567
spec/concerns/recorder_spec.rb
Normal file
567
spec/concerns/recorder_spec.rb
Normal file
@ -0,0 +1,567 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
require 'bigbluebutton_api'
|
||||||
|
|
||||||
|
shared_examples_for "recorder" do
|
||||||
|
let(:controller) { described_class } # the class that includes the concern
|
||||||
|
|
||||||
|
before do
|
||||||
|
@user = create(:user)
|
||||||
|
@room = @user.main_room
|
||||||
|
|
||||||
|
allow_any_instance_of(Room).to receive(:owner).and_return(@user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should properly find meeting recordings" do
|
||||||
|
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
||||||
|
recordings: [
|
||||||
|
{
|
||||||
|
name: "Example",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider)).to contain_exactly(
|
||||||
|
name: "Example",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "gets all filtered and sorted recordings for the user" do
|
||||||
|
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
||||||
|
recordings: [
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "5",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "test",
|
||||||
|
participants: "1",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Exam",
|
||||||
|
participants: "1",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
name: "z",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(all_recordings(@user.rooms.pluck(:bbb_id), @user.provider, search: "Exam", column: "name",
|
||||||
|
direction: "desc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "5",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#filtering' do
|
||||||
|
before do
|
||||||
|
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
||||||
|
recordings: [
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "5",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "test",
|
||||||
|
participants: "1",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Exam",
|
||||||
|
participants: "1",
|
||||||
|
playback: {
|
||||||
|
format:
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
name: "metadata",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should filter recordings on name" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, search: "Exam")).to contain_exactly(
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "5",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should filter recordings on participants" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, search: "5")).to contain_exactly(
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "5",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should filter recordings on format" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, search: "presentation")).to contain_exactly(
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "test",
|
||||||
|
participants: "1",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should filter recordings on visibility" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, search: "public")).to contain_exactly(
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "test",
|
||||||
|
participants: "1",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "presentation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should filter recordings on metadata name by default" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, search: "metadata")).to contain_exactly(
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Exam",
|
||||||
|
participants: "1",
|
||||||
|
playbacks:
|
||||||
|
[
|
||||||
|
{
|
||||||
|
type: "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "false",
|
||||||
|
name: "metadata",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#sorting' do
|
||||||
|
before do
|
||||||
|
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
||||||
|
recordings: [
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playback: {
|
||||||
|
format: {
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playback: {
|
||||||
|
format: {
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort recordings on name" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, column: "name", direction: "asc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort recordings on participants" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, column: "users", direction: "desc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort recordings on visibility" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, column: "visibility", direction: "desc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort recordings on length" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, column: "length", direction: "asc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should sort recordings on format" do
|
||||||
|
expect(recordings(@room.bbb_id, @room.owner.provider, column: "formats", direction: "desc")).to eq(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "Example",
|
||||||
|
participants: "3",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "presentation",
|
||||||
|
length: "4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
"gl-listed": "true",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
meetingID: @room.bbb_id,
|
||||||
|
name: "aExamaaa",
|
||||||
|
participants: "1",
|
||||||
|
playbacks: [
|
||||||
|
{
|
||||||
|
type: "other",
|
||||||
|
length: "3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
metadata: {
|
||||||
|
name: "Z",
|
||||||
|
"gl-listed": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -52,7 +52,7 @@ describe AdminsController, type: :controller do
|
|||||||
|
|
||||||
get :edit_user, params: { user_uid: @user.uid }
|
get :edit_user, params: { user_uid: @user.uid }
|
||||||
|
|
||||||
expect(response).to render_template(:index)
|
expect(response).to render_template(:edit_user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
|
||||||
|
|
||||||
expect(feature[:value]).to eq(fake_image_url)
|
expect(feature[:value]).to eq(fake_image_url)
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -214,7 +214,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
|
||||||
|
|
||||||
expect(feature[:value]).to eq(primary_color)
|
expect(feature[:value]).to eq(primary_color)
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "changes the primary-lighten on the page" do
|
it "changes the primary-lighten on the page" do
|
||||||
@ -229,7 +229,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
|
||||||
|
|
||||||
expect(feature[:value]).to eq(primary_color)
|
expect(feature[:value]).to eq(primary_color)
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "changes the primary-darken on the page" do
|
it "changes the primary-darken on the page" do
|
||||||
@ -244,7 +244,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
|
||||||
|
|
||||||
expect(feature[:value]).to eq(primary_color)
|
expect(feature[:value]).to eq(primary_color)
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -264,7 +264,7 @@ describe AdminsController, type: :controller do
|
|||||||
|
|
||||||
expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
|
expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
|
||||||
expect(flash[:success]).to be_present
|
expect(flash[:success]).to be_present
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not allow the user to change to invite if emails are off" do
|
it "does not allow the user to change to invite if emails are off" do
|
||||||
@ -277,7 +277,7 @@ describe AdminsController, type: :controller do
|
|||||||
post :registration_method, params: { method: "invite" }
|
post :registration_method, params: { method: "invite" }
|
||||||
|
|
||||||
expect(flash[:alert]).to be_present
|
expect(flash[:alert]).to be_present
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
|
||||||
|
|
||||||
expect(feature[:value]).to eq("true")
|
expect(feature[:value]).to eq("true")
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ describe AdminsController, type: :controller do
|
|||||||
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
|
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
|
||||||
|
|
||||||
expect(feature[:value]).to eq("5")
|
expect(feature[:value]).to eq("5")
|
||||||
expect(response).to redirect_to(admins_path)
|
expect(response).to redirect_to(admin_site_settings_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -28,6 +28,8 @@ def random_valid_room_params
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe RoomsController, type: :controller do
|
describe RoomsController, type: :controller do
|
||||||
|
it_behaves_like "recorder"
|
||||||
|
include Recorder
|
||||||
describe "GET #show" do
|
describe "GET #show" do
|
||||||
before do
|
before do
|
||||||
@user = create(:user)
|
@user = create(:user)
|
||||||
@ -39,7 +41,7 @@ describe RoomsController, type: :controller do
|
|||||||
|
|
||||||
get :show, params: { room_uid: @owner.main_room }
|
get :show, params: { room_uid: @owner.main_room }
|
||||||
|
|
||||||
expect(assigns(:recordings)).to eql(@owner.main_room.recordings)
|
expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id, @owner.provider))
|
||||||
expect(assigns(:is_running)).to eql(@owner.main_room.running?)
|
expect(assigns(:is_running)).to eql(@owner.main_room.running?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -302,6 +302,7 @@ describe UsersController, type: :controller do
|
|||||||
describe "PATCH #update" do
|
describe "PATCH #update" do
|
||||||
it "properly updates user attributes" do
|
it "properly updates user attributes" do
|
||||||
user = create(:user)
|
user = create(:user)
|
||||||
|
@request.session[:user_id] = user.id
|
||||||
|
|
||||||
params = random_valid_user_params
|
params = random_valid_user_params
|
||||||
patch :update, params: params.merge!(user_uid: user)
|
patch :update, params: params.merge!(user_uid: user)
|
||||||
@ -315,6 +316,7 @@ describe UsersController, type: :controller do
|
|||||||
|
|
||||||
it "renders #edit on unsuccessful save" do
|
it "renders #edit on unsuccessful save" do
|
||||||
@user = create(:user)
|
@user = create(:user)
|
||||||
|
@request.session[:user_id] = @user.id
|
||||||
|
|
||||||
patch :update, params: invalid_params.merge!(user_uid: @user)
|
patch :update, params: invalid_params.merge!(user_uid: @user)
|
||||||
expect(response).to render_template(:edit)
|
expect(response).to render_template(:edit)
|
||||||
|
@ -133,420 +133,6 @@ describe Room, type: :model do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context "#recordings" do
|
context "#recordings" do
|
||||||
it "should properly find meeting recordings" do
|
|
||||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
|
||||||
recordings: [
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(@room.recordings).to contain_exactly(
|
|
||||||
name: "Example",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
context '#filtering' do
|
|
||||||
before do
|
|
||||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
|
||||||
recordings: [
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "5",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "test",
|
|
||||||
participants: "1",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Exam",
|
|
||||||
participants: "1",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
name: "z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should filter recordings on name" do
|
|
||||||
expect(@room.recordings(search: "Exam")).to contain_exactly(
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "5",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should filter recordings on participants" do
|
|
||||||
expect(@room.recordings(search: "5")).to contain_exactly(
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "5",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should filter recordings on format" do
|
|
||||||
expect(@room.recordings(search: "presentation")).to contain_exactly(
|
|
||||||
{
|
|
||||||
name: "test",
|
|
||||||
participants: "1",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should filter recordings on visibility" do
|
|
||||||
expect(@room.recordings(search: "public")).to contain_exactly(
|
|
||||||
{
|
|
||||||
name: "test",
|
|
||||||
participants: "1",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should filter recordings on metadata name by default" do
|
|
||||||
expect(@room.recordings(search: "z")).to contain_exactly(
|
|
||||||
name: "Exam",
|
|
||||||
participants: "1",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
name: "z",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context '#sorting' do
|
|
||||||
before do
|
|
||||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
|
||||||
recordings: [
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playback: {
|
|
||||||
format: {
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playback: {
|
|
||||||
format: {
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should sort recordings on name" do
|
|
||||||
expect(@room.recordings(column: "name", direction: "asc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should sort recordings on participants" do
|
|
||||||
expect(@room.recordings(column: "users", direction: "desc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should sort recordings on visibility" do
|
|
||||||
expect(@room.recordings(column: "visibility", direction: "desc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should sort recordings on length" do
|
|
||||||
expect(@room.recordings(column: "length", direction: "asc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should sort recordings on format" do
|
|
||||||
expect(@room.recordings(column: "formats", direction: "desc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "presentation",
|
|
||||||
length: "4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "1",
|
|
||||||
playbacks: [
|
|
||||||
{
|
|
||||||
type: "other",
|
|
||||||
length: "3"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
name: "Z",
|
|
||||||
"gl-listed": "false"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "deletes the recording" do
|
it "deletes the recording" do
|
||||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
|
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
|
||||||
returncode: true, deleted: true
|
returncode: true, deleted: true
|
||||||
|
@ -173,97 +173,4 @@ describe User, type: :model do
|
|||||||
.to raise_exception(ActiveRecord::RecordInvalid, "Validation failed: Email can't be blank")
|
.to raise_exception(ActiveRecord::RecordInvalid, "Validation failed: Email can't be blank")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#recordings' do
|
|
||||||
it "gets all filtered and sorted recordings for the user" do
|
|
||||||
allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_recordings).and_return(
|
|
||||||
recordings: [
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "5",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "test",
|
|
||||||
participants: "1",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Exam",
|
|
||||||
participants: "1",
|
|
||||||
playback: {
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
name: "z",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(@user.all_recordings(search: "Exam", column: "name", direction: "desc")).to eq(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "Example",
|
|
||||||
participants: "3",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "presentation"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "true",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "aExamaaa",
|
|
||||||
participants: "5",
|
|
||||||
playbacks:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
metadata: {
|
|
||||||
"gl-listed": "false",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user