%PDF- %PDF-
Direktori : /home2/vacivi36/ava/mod/bigbluebuttonbn/classes/task/ |
Current File : //home2/vacivi36/ava/mod/bigbluebuttonbn/classes/task/upgrade_recordings_task.php |
<?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace mod_bigbluebuttonbn\task; use core\task\adhoc_task; use core\task\manager; use Matrix\Exception; use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\local\proxy\recording_proxy; use mod_bigbluebuttonbn\logger; use mod_bigbluebuttonbn\recording; use moodle_exception; /** * Class containing the scheduled task for converting recordings for the BigBlueButton version 2.5 in Moodle 4.0. * * @package mod_bigbluebuttonbn * @copyright 2021 Jesus Federico, Blindside Networks Inc <jesus at blindsidenetworks dot com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class upgrade_recordings_task extends adhoc_task { /** * Run the migration task. */ public function execute() { $info = $this->get_custom_data(); $meetingid = $info->meetingid; $isimported = $info->isimported ?? 0; $this->process_bigbluebuttonbn_logs($meetingid, $isimported); } /** * Process all bigbluebuttonbn logs looking for entries which should be converted to meetings. * * @param string $meetingid * @param bool $isimported * @return bool Whether any more logs are waiting to be processed * @throws \dml_exception * @throws moodle_exception */ protected function process_bigbluebuttonbn_logs(string $meetingid, bool $isimported): bool { global $DB; $classname = static::class; mtrace("Executing {$classname} for meeting {$meetingid}..."); // Fetch the logs queued for upgrade. mtrace("Fetching logs for conversion"); // Each log is ordered by timecreated. [$select, $params] = $this->get_sql_query_for_logs($meetingid, $isimported); $logsrs = $DB->get_recordset_select('bigbluebuttonbn_logs', $select, $params, 'timecreated DESC', 'id, meetingid, timecreated, log'); if (!$logsrs->valid()) { mtrace("No logs were found for conversion."); // No more logs. Stop queueing. return false; } // Retrieve recordings from the servers for this meeting. $recordings = recording_proxy::fetch_recording_by_meeting_id([$meetingid]); // Sort recordings by meetingId, then startTime. uasort($recordings, function($a, $b) { return $b['startTime'] - $a['startTime']; }); // Create an instance of bigbluebuttonbn_recording per valid recording. mtrace("Creating new recording records..."); $recordingcount = 0; foreach ($recordings as $recordingid => $recording) { $importeddata = $isimported ? '' : json_encode($recording); try { $instance = instance::get_from_meetingid($recording['meetingID']); } catch (Exception $e) { mtrace("Unable to parse meetingID " . $e->getMessage()); continue; } if ($instance) { $newrecording = [ 'courseid' => $instance->get_course_id(), 'bigbluebuttonbnid' => $instance->get_instance_id(), 'groupid' => $instance->get_group_id(), // The groupid should be taken from the meetingID. 'recordingid' => $recordingid, 'status' => recording::RECORDING_STATUS_PROCESSED, ]; } else { mtrace("Unable to find an activity for {$recording['meetingID']}. This recording is headless."); // This instance does not exist any more. // Use the data in the log instead of the instance. $meetingdata = instance::parse_meetingid($recording['meetingID']); $newrecording = [ 'courseid' => $meetingdata['courseid'], 'bigbluebuttonbnid' => $meetingdata['instanceid'], 'groupid' => 0, 'recordingid' => $recordingid, 'status' => recording::RECORDING_STATUS_PROCESSED, ]; if (array_key_exists('groupid', $meetingdata)) { $newrecording['groupid'] = $meetingdata['groupid']; } } if ($DB->record_exists('bigbluebuttonbn_recordings', $newrecording)) { mtrace("A recording already exists for {$recording['recordID']}. Skipping."); // A recording matching these characteristics alreay exists. continue; } // Recording has not been imported, check if we still have more logs. // We try to guess which logs matches which recordings are they are classed in the same order. // But this is just an attempt. $log = null; if ($logsrs->valid()) { $log = $logsrs->current(); $logsrs->next(); } $timecreated = empty($log) ? time() : $log->timecreated; $newrecording['imported'] = $isimported; $newrecording['headless'] = 0; $newrecording['importeddata'] = $importeddata; $newrecording['timecreated'] = $newrecording['timemodified'] = $timecreated; // If we could not match with a log, we still create the recording. $DB->insert_record('bigbluebuttonbn_recordings', $newrecording); $recordingcount++; } mtrace("Migrated {$recordingcount} recordings."); // Now deactivate logs by marking all of them as migrated. // Reason for this is that we don't want to run another migration here and we don't know // which logs matches which recordings. $DB->set_field_select('bigbluebuttonbn_logs', 'log', $isimported ? logger::EVENT_IMPORT_MIGRATED : logger::EVENT_CREATE_MIGRATED, $select, $params ); $logsrs->close(); return true; } /** * Get the query (records_select) for the logs to convert. * * Each log is ordered by timecreated. * * @param string $meetingid * @param bool $isimported * @return array */ protected function get_sql_query_for_logs(string $meetingid, bool $isimported): array { global $DB; if ($isimported) { return [ 'log = :logmatch AND meetingid = :meetingid', ['logmatch' => logger::EVENT_IMPORT, 'meetingid' => $meetingid], ]; } return [ 'log = :logmatch AND meetingid = :meetingid AND ' . $DB->sql_like('meta', ':match'), [ 'logmatch' => logger::EVENT_CREATE, 'match' => '%true%', 'meetingid' => $meetingid ], ]; } /** * Schedule all upgrading tasks. * * @param bool $importedrecordings * @return void * @throws \dml_exception */ public static function schedule_upgrade_per_meeting($importedrecordings = false) { global $DB; $meetingids = $DB->get_fieldset_sql( 'SELECT DISTINCT meetingid FROM {bigbluebuttonbn_logs} WHERE log = :createorimport', ['createorimport' => $importedrecordings ? logger::EVENT_IMPORT : logger::EVENT_CREATE] ); foreach ($meetingids as $mid) { $createdrecordingtask = new static(); $createdrecordingtask->set_custom_data((object) ['meetingid' => $mid, 'isimported' => $importedrecordings]); manager::queue_adhoc_task($createdrecordingtask); } } }