Skip to content

Commit

Permalink
GIT-718: Implement offset pagination for getRecordings
Browse files Browse the repository at this point in the history
  • Loading branch information
git-lama committed Oct 22, 2021
1 parent e2eb7ef commit f955b3e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ These variables are used by the service startup scripts in the Docker images, bu
* `PROTECTED_RECORDINGS_ENABLED`: Applies to the recording import process. If set to "true", then newly imported recordings will have protected links enabled. Default is "false".
* `PROTECTED_RECORDINGS_TOKEN_TIMEOUT`: Protected recording link token timeout in minutes. This is the amount of time that the one-time-use link returned in `getRecordings` calls will be valid for. Defaults to 60 minutes (1 hour).
* `PROTECTED_RECORDINGS_TIMEOUT`: Protected recordings resource access cookie timeout in minutes. This is the amount of time that a user will be granted access to view a recording for after clicking on the one-time-use link. Defaults to 360 minutes (6 hours).
* `PAGINATION_ENABLED`: Enable pagination feature for GET_RECORDINGS API by setting this to true. Defaults to `false`.
* `DEFAULT_PAGINATION_LIMIT`: The number of records that will be displayed per page, if the limit is not specified in API params. Defaults to 10.

### Redis Connection (`config/redis_store.yml`)

Expand Down
8 changes: 8 additions & 0 deletions app/controllers/bigbluebutton_api_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def get_recordings
end

query = Recording.includes(playback_formats: [:thumbnails], metadata: []).references(:metadata)

query = if params[:state].present?
states = params[:state].split(',')
states.include?('any') ? query : query.where(state: states)
Expand All @@ -293,6 +294,13 @@ def get_recordings
query = query.with_recording_id_prefixes(params[:recordID].split(',')) if params[:recordID].present?
query = query.where(meeting_id: params[:meetingID].split(',')) if params[:meetingID].present?

if Rails.configuration.x.pagination_enabled
page = params[:page]&.to_i || 0
limit = params[:limit]&.to_i || Rails.configuration.x.default_pagination_limit
offset = page * limit
query = query.offset(offset).limit(limit)
end

@recordings = query.order(starttime: :desc).all
@url_prefix = "#{request.protocol}#{request.host}"

Expand Down
6 changes: 6 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,11 @@ class Application < Rails::Application
config.x.recording_token_ttl = ENV.fetch('PROTECTED_RECORDINGS_TOKEN_TIMEOUT', '60').to_i.minutes
# Protected recordings resource access cookie timeout in minutes. Defaults to 360 (6 hours)
config.x.recording_cookie_ttl = ENV.fetch('PROTECTED_RECORDINGS_TIMEOUT', '360').to_i.minutes

# Enable pagination for get_recordings api. Defaults to false.
config.x.pagination_enabled = ENV.fetch('PAGINATION_ENABLED', 'false').casecmp?('true')

# Set pagination limit for get_recordings api. Defaults to 10.
config.x.default_pagination_limit = ENV.fetch('DEFAULT_PAGINATION_LIMIT', '10').to_i
end
end
57 changes: 57 additions & 0 deletions test/controllers/bigbluebutton_api_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,63 @@ class BigBlueButtonApiControllerTest < ActionDispatch::IntegrationTest
assert_select 'response>recordings>recording', 1
end

test 'getRecordings returns paginated recordings if pagination is enabled' do
create_list(:recording, 12, state: 'published')

params = encode_bbb_params('getRecordings', { page: 0, limit: 4 }.to_query)

Rails.configuration.x.stub(:pagination_enabled, true) do
get bigbluebutton_api_get_recordings_url, params: params
end

assert_response :success
assert_select 'response>returncode', 'SUCCESS'
assert_select 'response>recordings>recording', 4
end

test 'getRecordings returns paginated recordings if pagination is enabled and page & limit value is given' do
list = create_list(:recording, 30, state: 'unpublished')
offset_zero = list.first(15).last
offset_five = list.first(11).last

params = encode_bbb_params('getRecordings', { page: 3, limit: 5 }.to_query)

Rails.configuration.x.stub(:pagination_enabled, true) do
get bigbluebutton_api_get_recordings_url, params: params
end

assert_response :success
assert_select 'response>returncode', 'SUCCESS'
assert_select 'response>recordings>recording', 5
response_xml = Nokogiri::XML(@response.body)
first_rec_id = response_xml.xpath('/response/recordings/recording').first.xpath('.//recordID').text
last_rec_id = response_xml.xpath('/response/recordings/recording').last.xpath('.//recordID').text
assert_equal first_rec_id, offset_zero.record_id
assert_equal last_rec_id, offset_five.record_id
end

test 'getRecordings returns paginated recordings based on default values of limit=10 & page=0' do
create_list(:recording, 10, state: 'published')
list = create_list(:recording, 10, state: 'unpublished')
offset_zero = list.last
offset_ten = list.first

Rails.configuration.x.stub(:pagination_enabled, true) do
BigBlueButtonApiController.stub_any_instance(:verify_checksum, nil) do
get bigbluebutton_api_get_recordings_url
end
end

assert_response :success
assert_select 'response>returncode', 'SUCCESS'
assert_select 'response>recordings>recording', 10
response_xml = Nokogiri::XML(@response.body)
first_rec_id = response_xml.xpath('/response/recordings/recording').first.xpath('.//recordID').text
last_rec_id = response_xml.xpath('/response/recordings/recording').last.xpath('.//recordID').text
assert_equal first_rec_id, offset_zero.record_id
assert_equal last_rec_id, offset_ten.record_id
end

test 'getRecordings with get_recordings_api_filtered filters based on recording states' do
create_list(:recording, 5, state: 'deleted')
r1 = create(:recording, state: 'published')
Expand Down

0 comments on commit f955b3e

Please sign in to comment.