Skip to content

Commit

Permalink
CONTRIB-9569: Fix dismissed recordings (#627)
Browse files Browse the repository at this point in the history
* Added check that recording was successfully retrieved from BBB server before marking it as dismissed because no metadata exists
  • Loading branch information
ssj365 authored Jul 8, 2024
1 parent 182d83c commit a002931
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 54 deletions.
85 changes: 41 additions & 44 deletions classes/local/proxy/recording_proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ public static function update_recording(string $recordid, array $params): bool {
* @return null|array
*/
public static function fetch_recording(string $recordingid): ?array {
$data = self::fetch_recordings([$recordingid]);

$result = self::fetch_recordings([$recordingid]);
$data = $result['recordings'];
if (array_key_exists($recordingid, $data)) {
return $data[$recordingid];
}
Expand Down Expand Up @@ -179,17 +179,18 @@ public static function fetch_recordings(array $keyids = []): array {

// If $ids is empty return array() to prevent a getRecordings with meetingID and recordID set to ''.
if (empty($keyids)) {
return $recordings;
return ['recordings' => $recordings, 'unfetchedids' => []];
}
$cache = cache::make('mod_bigbluebuttonbn', 'recordings');
$currentfetchcache = cache::make('mod_bigbluebuttonbn', 'currentfetch');
$recordings = array_filter($cache->get_many($keyids));
$missingkeys = array_diff(array_values($keyids), array_keys($recordings));

$recordings += self::do_fetch_recordings($missingkeys);
$result = self::do_fetch_recordings($missingkeys);
$recordings += $result['recordings'];
$cache->set_many($recordings);
$currentfetchcache->set_many(array_flip(array_keys($recordings)));
return $recordings;
return ['recordings' => $recordings, 'unfetchedids' => $result['unfetchedids']];
}

/**
Expand All @@ -203,10 +204,9 @@ public static function fetch_recording_by_meeting_id(array $keyids = []): array

// If $ids is empty return array() to prevent a getRecordings with meetingID and recordID set to ''.
if (empty($keyids)) {
return $recordings;
return ['recordings' => $recordings, 'unfetchedids' => []];
}
$recordings = self::do_fetch_recordings($keyids, 'meetingID');
return $recordings;
return self::do_fetch_recordings($keyids, 'meetingID');
}

/**
Expand All @@ -218,61 +218,58 @@ public static function fetch_recording_by_meeting_id(array $keyids = []): array
*/
private static function do_fetch_recordings(array $keyids = [], string $key = 'recordID'): array {
$recordings = [];
$unfetchedids = [];
$pagesize = 25;
while ($ids = array_splice($keyids, 0, $pagesize)) {
$fetchrecordings = self::fetch_recordings_page($ids, $key);
$recordings += $fetchrecordings;
$result = self::fetch_recordings_page($ids, $key);
if (!$result['success']) {
$unfetchedids = array_merge($unfetchedids, $ids);
continue; // Skip this page as the response is not valid but we will keep record of all unfetched ids.
}
$recordings += $result['recordings'];
}
return $recordings;
return ['recordings' => $recordings, 'unfetchedids' => $unfetchedids];
}
/**
* Helper function to fetch a page of recordings from the remote server.
*
* @param array $ids
* @param string $key
* @return array
* @return array an associative array containing recordings list and fetch success.
*/
private static function fetch_recordings_page(array $ids, $key = 'recordID'): array {
// The getRecordings call is executed using a method GET (supported by all versions of BBB).
$xml = self::fetch_endpoint_xml('getRecordings', [$key => implode(',', $ids), 'state' => 'any']);

if (!$xml) {
return [];
}

if ($xml->returncode != 'SUCCESS') {
return [];
}

if (!isset($xml->recordings)) {
return [];
}

$recordings = [];
// If there were recordings already created.
foreach ($xml->recordings->recording as $recordingxml) {
$recording = self::parse_recording($recordingxml);
$recordings[$recording['recordID']] = $recording;
// Check if there are any child.
if (isset($recordingxml->breakoutRooms->breakoutRoom)) {
$breakoutrooms = [];
foreach ($recordingxml->breakoutRooms->breakoutRoom as $breakoutroom) {
$breakoutrooms[] = trim((string) $breakoutroom);
}
if ($breakoutrooms) {
$xml = self::fetch_endpoint_xml('getRecordings', ['recordID' => implode(',', $breakoutrooms)]);
if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
// If there were already created meetings.
foreach ($xml->recordings->recording as $subrecordingxml) {
$recording = self::parse_recording($subrecordingxml);
$recordings[$recording['recordID']] = $recording;
// Response from the server must be valid.
if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
$recordings = [];
// If there were recordings already created.
foreach ($xml->recordings->recording as $recordingxml) {
$recording = self::parse_recording($recordingxml);
$recordings[$recording['recordID']] = $recording;
// Check if there are any child.
if (isset($recordingxml->breakoutRooms->breakoutRoom)) {
$breakoutrooms = [];
foreach ($recordingxml->breakoutRooms->breakoutRoom as $breakoutroom) {
$breakoutrooms[] = trim((string) $breakoutroom);
}
if ($breakoutrooms) {
$xml = self::fetch_endpoint_xml('getRecordings', ['recordID' => implode(',', $breakoutrooms)]);
if ($xml && $xml->returncode == 'SUCCESS' && isset($xml->recordings)) {
// If there were already created meetings.
foreach ($xml->recordings->recording as $subrecordingxml) {
$recording = self::parse_recording($subrecordingxml);
$recordings[$recording['recordID']] = $recording;
}
}
}
}
}
return ['recordings' => $recordings, 'success' => true];
}

return $recordings;
debugging('getRecordings API call failed', DEBUG_DEVELOPER);
return ['recordings' => [], 'success' => false];
}

/**
Expand Down
13 changes: 8 additions & 5 deletions classes/recording.php
Original file line number Diff line number Diff line change
Expand Up @@ -700,14 +700,16 @@ protected static function fetch_records(array $selects, array $params): array {
}, $recordings));

// Fetch all metadata for these recordings.
$metadatas = recording_proxy::fetch_recordings($recordingids);
$result = recording_proxy::fetch_recordings($recordingids);
$metadatas = $result['recordings'];
$failedids = $result['unfetchedids'];

// Return the instances.
return array_filter(array_map(function ($recording) use ($metadatas, $withindays) {
return array_filter(array_map(function ($recording) use ($metadatas, $withindays, $failedids) {
// Filter out if no metadata was fetched.
if (!array_key_exists($recording->recordingid, $metadatas)) {
// Mark it as dismissed if it is older than 30 days.
if ($withindays > $recording->timecreated) {
// If the recording was successfully fetched, mark it as dismissed if it is older than 30 days.
if (!in_array($recording->recordingid, $failedids) && $withindays > $recording->timecreated) {
$recording = new self(0, $recording, null);
$recording->set_status(self::RECORDING_STATUS_DISMISSED);
}
Expand Down Expand Up @@ -795,7 +797,8 @@ public static function sync_pending_recordings_from_server($dismissedonly = fals

// Fetch all metadata for these recordings.
mtrace("=> Fetching recording metadata from server");
$metadatas = recording_proxy::fetch_recordings($recordingids);
$result = recording_proxy::fetch_recordings($recordingids);
$metadatas = $result['recordings'];

$foundcount = 0;
foreach ($metadatas as $recordingid => $metadata) {
Expand Down
3 changes: 2 additions & 1 deletion classes/task/upgrade_recordings_task.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ protected function process_bigbluebuttonbn_logs(string $meetingid, bool $isimpor
return false;
}
// Retrieve recordings from the servers for this meeting.
$recordings = recording_proxy::fetch_recording_by_meeting_id([$meetingid]);
$result = recording_proxy::fetch_recording_by_meeting_id([$meetingid]);
$recordings = $result['recordings'];
// Sort recordings by meetingId, then startTime.
uasort($recordings, function($a, $b) {
return $b['startTime'] - $a['startTime'];
Expand Down
3 changes: 2 additions & 1 deletion classes/test/testcase_helper_trait.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ protected function create_legacy_log_entries(
$baselogdata['meetingid'] = $instance->get_meeting_id();
if ($importedrecordings) {
// Fetch the data.
$data = recording_proxy::fetch_recordings([$recording->recordingid]);
$result = recording_proxy::fetch_recordings([$recording->recordingid]);
$data = $result['recordings'];
$data = end($data);
if ($data) {
$metaonly = array_filter($data, function($key) {
Expand Down
3 changes: 2 additions & 1 deletion cli/update_dismissed_recordings.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@
$recordingkeys = array_map(function($rec) {
return $rec->get('recordingid');
}, $recordings);
$recordingmeta = \mod_bigbluebuttonbn\local\proxy\recording_proxy::fetch_recordings($recordingkeys);
$result = \mod_bigbluebuttonbn\local\proxy\recording_proxy::fetch_recordings($recordingkeys);
$recordingmeta = $result['recordings'];
if (empty($recordings)) {
cli_writeln("\t->No dimissed recordings found ...");
} else {
Expand Down
6 changes: 4 additions & 2 deletions tests/local/proxy/recording_proxy_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public function test_fetch_recordings() {
$recordingsid = array_map(function ($r) {
return $r->recordingid;
}, $recordings);
$recordings = recording_proxy::fetch_recordings($recordingsid);
$result = recording_proxy::fetch_recordings($recordingsid);
$recordings = $result['recordings'];
$this->assertCount(2, $recordings);
}

Expand Down Expand Up @@ -90,7 +91,8 @@ public function test_fetch_recordings_breakoutroom() {
$recordingsid = array_map(function ($r) {
return $r->recordingid;
}, $recordings);
$recordings = recording_proxy::fetch_recordings([$recordingsid[0]]);
$result = recording_proxy::fetch_recordings([$recordingsid[0]]);
$recordings = $result['recordings'];
$this->assertCount(3, $recordings);
}
}

0 comments on commit a002931

Please sign in to comment.