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:
		
				
					committed by
					
						
						Jesus Federico
					
				
			
			
				
	
			
			
			
						parent
						
							8c63f793a5
						
					
				
				
					commit
					a055b88eb7
				
			@@ -1,96 +0,0 @@
 | 
			
		||||
# 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/>.
 | 
			
		||||
 | 
			
		||||
module APIConcern
 | 
			
		||||
  extend ActiveSupport::Concern
 | 
			
		||||
 | 
			
		||||
  # Format, filter, and sort recordings to match their current use in the app
 | 
			
		||||
  def format_recordings(api_res, search_params, ret_search_params)
 | 
			
		||||
    search = search_params[:search] || ""
 | 
			
		||||
    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"
 | 
			
		||||
 | 
			
		||||
    search = search.downcase
 | 
			
		||||
 | 
			
		||||
    api_res[:recordings].each do |r|
 | 
			
		||||
      next if r.key?(:error)
 | 
			
		||||
      # Format playbacks in a more pleasant way.
 | 
			
		||||
      r[:playbacks] = if !r[:playback] || !r[:playback][:format]
 | 
			
		||||
        []
 | 
			
		||||
      elsif r[:playback][:format].is_a?(Array)
 | 
			
		||||
        r[:playback][:format]
 | 
			
		||||
      else
 | 
			
		||||
        [r[:playback][:format]]
 | 
			
		||||
      end
 | 
			
		||||
      r.delete(:playback)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    recs = filter_recordings(api_res, search)
 | 
			
		||||
    recs = sort_recordings(recs, order_col, order_dir)
 | 
			
		||||
 | 
			
		||||
    if ret_search_params
 | 
			
		||||
      [search, order_col, order_dir, recs]
 | 
			
		||||
    else
 | 
			
		||||
      recs
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def filter_recordings(api_res, search)
 | 
			
		||||
    api_res[:recordings].select do |r|
 | 
			
		||||
             (!r[:metadata].nil? && ((!r[:metadata][:name].nil? &&
 | 
			
		||||
                    r[:metadata][:name].downcase.include?(search)) ||
 | 
			
		||||
                  (r[:metadata][:"gl-listed"] == "true" && search == "public") ||
 | 
			
		||||
                  (r[:metadata][:"gl-listed"] == "false" && search == "unlisted"))) ||
 | 
			
		||||
               ((r[:metadata].nil? || r[:metadata][:name].nil?) &&
 | 
			
		||||
                 r[:name].downcase.include?(search)) ||
 | 
			
		||||
               r[:participants].include?(search) ||
 | 
			
		||||
               !r[:playbacks].select { |p| p[:type].downcase.include?(search) }.empty?
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def sort_recordings(recs, order_col, order_dir)
 | 
			
		||||
    recs = case order_col
 | 
			
		||||
           when "end_time"
 | 
			
		||||
              recs.sort_by { |r| r[:endTime] }
 | 
			
		||||
           when "name"
 | 
			
		||||
              recs.sort_by do |r|
 | 
			
		||||
                if !r[:metadata].nil? && !r[:metadata][:name].nil?
 | 
			
		||||
                  r[:metadata][:name].downcase
 | 
			
		||||
                else
 | 
			
		||||
                  r[:name].downcase
 | 
			
		||||
                end
 | 
			
		||||
              end
 | 
			
		||||
           when "length"
 | 
			
		||||
              recs.sort_by { |r| r[:playbacks].reject { |p| p[:type] == "statistics" }.first[:length] }
 | 
			
		||||
           when "users"
 | 
			
		||||
              recs.sort_by { |r| r[:participants] }
 | 
			
		||||
           when "visibility"
 | 
			
		||||
              recs.sort_by { |r| r[:metadata][:"gl-listed"] }
 | 
			
		||||
           when "formats"
 | 
			
		||||
              recs.sort_by { |r| r[:playbacks].first[:type].downcase }
 | 
			
		||||
            else
 | 
			
		||||
              recs.sort_by { |r| r[:endTime] }
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
    if order_dir == 'asc'
 | 
			
		||||
      recs
 | 
			
		||||
    else
 | 
			
		||||
      recs.reverse
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
require 'bbb_api'
 | 
			
		||||
 | 
			
		||||
class Room < ApplicationRecord
 | 
			
		||||
  include ::APIConcern
 | 
			
		||||
  include ::BbbApi
 | 
			
		||||
 | 
			
		||||
  before_create :setup
 | 
			
		||||
@@ -40,7 +39,7 @@ class Room < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  # Checks if a room is running on the BigBlueButton server.
 | 
			
		||||
  def running?
 | 
			
		||||
    bbb.is_meeting_running?(bbb_id)
 | 
			
		||||
    bbb(owner.provider).is_meeting_running?(bbb_id)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Determines the invite path for the room.
 | 
			
		||||
@@ -62,7 +61,7 @@ class Room < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
    # Send the create request.
 | 
			
		||||
    begin
 | 
			
		||||
      meeting = bbb.create_meeting(name, bbb_id, create_options)
 | 
			
		||||
      meeting = bbb(owner.provider).create_meeting(name, bbb_id, create_options)
 | 
			
		||||
      # Update session info.
 | 
			
		||||
      unless meeting[:messageKey] == 'duplicateWarning'
 | 
			
		||||
        update_attributes(sessions: sessions + 1, last_session: DateTime.now)
 | 
			
		||||
@@ -84,10 +83,10 @@ class Room < ApplicationRecord
 | 
			
		||||
    options[:user_is_moderator] ||= false
 | 
			
		||||
    options[:meeting_recorded] ||= false
 | 
			
		||||
 | 
			
		||||
    return call_invalid_res unless bbb
 | 
			
		||||
    return call_invalid_res unless bbb(owner.provider)
 | 
			
		||||
 | 
			
		||||
    # 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.
 | 
			
		||||
    password = if options[:user_is_moderator]
 | 
			
		||||
@@ -101,7 +100,7 @@ class Room < ApplicationRecord
 | 
			
		||||
    join_opts[:userID] = uid if uid
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
  # Notify waiting users that a meeting has started.
 | 
			
		||||
@@ -111,7 +110,7 @@ class Room < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  # Retrieves all the users in a room.
 | 
			
		||||
  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|
 | 
			
		||||
      User.find_by(uid: att[:userID], name: att[:fullName])
 | 
			
		||||
    end
 | 
			
		||||
@@ -120,27 +119,18 @@ class Room < ApplicationRecord
 | 
			
		||||
    []
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Fetches all recordings for a room.
 | 
			
		||||
  def recordings(search_params = {}, ret_search_params = false)
 | 
			
		||||
    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" }]
 | 
			
		||||
  def recording_count
 | 
			
		||||
    bbb(owner.provider).get_recordings(meetingID: bbb_id)[:recordings].length
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def update_recording(record_id, meta)
 | 
			
		||||
    meta[:recordID] = record_id
 | 
			
		||||
    bbb.send_api_request("updateRecordings", meta)
 | 
			
		||||
    bbb(owner.provider).send_api_request("updateRecordings", meta)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Deletes a recording from a room.
 | 
			
		||||
  def delete_recording(record_id)
 | 
			
		||||
    bbb.delete_recordings(record_id)
 | 
			
		||||
    bbb(owner.provider).delete_recordings(record_id)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
@@ -155,7 +145,7 @@ class Room < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  # Deletes all recordings associated with the room.
 | 
			
		||||
  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?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ require 'bbb_api'
 | 
			
		||||
 | 
			
		||||
class User < ApplicationRecord
 | 
			
		||||
  rolify
 | 
			
		||||
  include ::APIConcern
 | 
			
		||||
  include ::BbbApi
 | 
			
		||||
 | 
			
		||||
  attr_accessor :reset_token
 | 
			
		||||
@@ -118,31 +117,8 @@ class User < ApplicationRecord
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def self.admins_order(column, direction)
 | 
			
		||||
    order("#{column} #{direction}")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
    # Arel.sql to avoid sql injection
 | 
			
		||||
    order(Arel.sql("#{column} #{direction}"))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Activates an account and initialize a users main room
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user