Skip to content

Commit

Permalink
Add Opencast Playlists (#955)
Browse files Browse the repository at this point in the history
* Add Opencast Playlists, ref #784

* Load opencast playlist in backend

* Update playlist in backend

* Add playlist in backend

* Delete playlist in backend

* Update playlist videos in backend

* Remove unused code

* Remove lti roles for playlists

* Update endpoints in migration

* Ignore unknown playlists and check playlist acl in cronjob

* Create playlist copy in opencast when copying

* Add description for playlist migration

* Migrate playlist to its associated server

* Ensure that all opencast servers support playlists api

* Update library opencast-api to 1.6

Version 1.6 adds support for playlists api

* Remove unused code

* Clean up frontend code

* Add failure check in playlist cronjob

* Sort videos in opencast

---------

Co-authored-by: Dennis Benz <dennis.benz@uos.de>
Co-authored-by: Till <tgloeggl@uos.de>
  • Loading branch information
3 people committed May 10, 2024
1 parent bee1a40 commit 9c73929
Show file tree
Hide file tree
Showing 40 changed files with 1,262 additions and 294 deletions.
118 changes: 118 additions & 0 deletions cronjobs/opencast_sync_playlists.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

require_once __DIR__ . '/../bootstrap.php';
require_once __DIR__ . '/../vendor/autoload.php';

use Opencast\Models\Config;
use Opencast\Models\Playlists;
use Opencast\Models\REST\ApiPlaylistsClient;
use Opencast\Models\REST\Config as OCConfig;

class OpencastSyncPlaylists extends CronJob
{
public static function getName()
{
return _('Opencast - Wiedergabelisten synchronisieren');
}

public static function getDescription()
{
return _('Opencast: Synchronisiert Wiedergabelisten aus Opencast mit allen Wiedergabelisten in Stud.IP, indem bestehende Wiedergabelisten aktualisiert und nicht vorhandene Wiedergabelisten entfernt werden.');
}

public function execute($last_result, $parameters = array())
{
$db = DBManager::get();
$stmt_ids = $db->prepare("
SELECT service_playlist_id FROM oc_playlist WHERE config_id = :config_id
");

// iterate over all active configured oc instances
$configs = Config::findBySql('active = 1');

foreach ($configs as $config) {
// check, if this opencast instance is accessible
$version = false;

echo 'working on config ' . $config->id . "\n";
$version = OCConfig::getOCBaseVersion($config->id);

if (!$version) {
echo 'cannot connect to opencast, skipping!' . "\n";
continue;
} else {
echo "found opencast with version $version, continuing\n";
}

// call opencast to get all playlists
$api_client = ApiPlaylistsClient::getInstance($config['id']);
echo 'instantiated api_client' . "\n";

// Assume the admin user has access to all playlists
$response = $api_client->getAll();
if ($response === false) {
echo 'cannot load playlists from opencast' . "\n";
continue;
}

$playlists = [];
$playlist_ids = [];
foreach ($response as $playlist) {
$playlist_ids[] = $playlist->id;
$playlists[$playlist->id] = $playlist;
}

// check if these playlist_ids have a corresponding playlist in Stud.IP

$stmt_ids->execute([':config_id' => $config['id']]);

$local_playlist_ids = $stmt_ids->fetchAll(PDO::FETCH_COLUMN);

// Update existing playlists
foreach ($playlist_ids as $playlist_id) {
$playlist = Playlists::findOneBySQL(
'config_id = ? AND service_playlist_id = ?',
[$config['id'], $playlist_id]
);

if (is_null($playlist)) {
// Ignore unknown playlists possibly created externally
continue;
}

echo 'update playlist of Opencast #'. $config['id'] .': ' . $playlist_id . ' (' . $playlists[$playlist_id]->title . ")\n";

// Update playlist data
$playlist->setData([
'config_id' => $config['id'],
'service_playlist_id' => $playlist_id,
'title' => $playlists[$playlist_id]->title,
'description' => $playlists[$playlist_id]->description,
'creator' => $playlists[$playlist_id]->creator,
'updated' => date('Y-m-d H:i:s', strtotime($playlists[$playlist_id]->updated)),
]);
$playlist->store();

// Update playlist entries
$playlist->setEntries($playlists[$playlist_id]->entries);

// Check ACLs for playlist
Playlists::checkPlaylistACL($playlists[$playlist_id], $playlist);
}

// Check if local playlists are no longer available in OC
foreach (array_diff($local_playlist_ids, $playlist_ids) as $playlist_id) {
echo 'delete non-existent playlist in Opencast #'. $config['id'] .': ' . $playlist_id . ' (' . $playlists[$playlist_id]->title . ")\n";
$playlist = Playlists::findOneBySQL(
'config_id = ? AND service_playlist_id = ?',
[$config['id'], $playlist_id]
);

// Need null check for archived playlists
if ($playlist) {
$playlist->delete();
}
}
}
}
}
26 changes: 20 additions & 6 deletions lib/Models/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,25 @@ class Config extends \SimpleOrMap
{
use RelationshipTrait;

protected const allowed_settings_fields = [
protected const ALLOWED_SETTINGS_FIELDS = [
'lti_consumerkey', 'lti_consumersecret', 'debug'
];

const SERVICES = [
"apievents", // alles admin-node
"apiseries",
"apiworkflows",
"apiplaylists",
"capture-admin",
"ingest",
"recordings",
"search", // ausser hier: engage-node
"series",
"services",
"upload",
"workflow",
];

protected static function configure($config = [])
{
$config['db_table'] = 'oc_config';
Expand Down Expand Up @@ -108,7 +123,7 @@ public static function getConfigIdForCourse($course_id)
public function sanitizeSettings($event)
{
foreach ($this->settings as $key => $value) {
if (in_array($key, self::allowed_settings_fields) === false) {
if (in_array($key, self::ALLOWED_SETTINGS_FIELDS) === false) {
unset($this->settings[$key]);
}
}
Expand Down Expand Up @@ -159,10 +174,9 @@ public function updateSettings($json)
/**
* load and update endpoihnts for reference OC server
*
* @param Container $container
* @return void
* @return void|array message
*/
public function updateEndpoints($container)
public function updateEndpoints()
{
$service_url = parse_url($this->service_url);

Expand Down Expand Up @@ -253,7 +267,7 @@ public function updateEndpoints($container)
foreach($services as $service_url => $service_type) {
if (in_array(
strtolower($service_type),
$container->get('opencast')['services']
self::SERVICES
) !== false
) {
Endpoints::setEndpoint($this->id, $service_url, $service_type);
Expand Down
Loading

0 comments on commit 9c73929

Please sign in to comment.