mirror of https://github.com/sualko/cloud_bbb
parent
ff91186b42
commit
e63cbaaed1
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\BigBlueButton\BackgroundJob;
|
||||||
|
|
||||||
|
use OCA\BigBlueButton\BigBlueButton\API;
|
||||||
|
use OCA\BigBlueButton\Service\RoomNotFound;
|
||||||
|
use OCA\BigBlueButton\Service\RoomService;
|
||||||
|
use OCP\AppFramework\Utility\ITimeFactory;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
|
use OCP\BackgroundJob\TimedJob;
|
||||||
|
|
||||||
|
class IsRunningJob extends TimedJob {
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
|
/** @var RoomService */
|
||||||
|
private $service;
|
||||||
|
|
||||||
|
/** @var API */
|
||||||
|
private $api;
|
||||||
|
|
||||||
|
public function __construct(ITimeFactory $time, IJobList $jobList, RoomService $service, API $api) {
|
||||||
|
parent::__construct($time);
|
||||||
|
|
||||||
|
$this->jobList = $jobList;
|
||||||
|
$this->service = $service;
|
||||||
|
$this->api = $api;
|
||||||
|
|
||||||
|
$this->setInterval(15 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function run($argument) {
|
||||||
|
try {
|
||||||
|
$room = $this->service->find($argument['id']);
|
||||||
|
} catch (RoomNotFound $e) {
|
||||||
|
$this->jobList->remove($this, $argument);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$room->running) {
|
||||||
|
$this->jobList->remove($this, $argument);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$isRunning = $this->api->isRunning($room);
|
||||||
|
|
||||||
|
if (!$isRunning) {
|
||||||
|
$this->service->updateRunning($room->id, $isRunning);
|
||||||
|
|
||||||
|
$this->jobList->remove($this, $argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,8 @@ class HookController extends Controller {
|
||||||
$recordingmarks = \boolval($recordingmarks);
|
$recordingmarks = \boolval($recordingmarks);
|
||||||
$room = $this->getRoom();
|
$room = $this->getRoom();
|
||||||
|
|
||||||
|
$this->service->updateRunning($room->getId(), false);
|
||||||
|
|
||||||
$this->avatarRepository->clearRoom($room->uid);
|
$this->avatarRepository->clearRoom($room->uid);
|
||||||
|
|
||||||
$this->eventDispatcher->dispatch(MeetingEndedEvent::class, new MeetingEndedEvent($room, $recordingmarks));
|
$this->eventDispatcher->dispatch(MeetingEndedEvent::class, new MeetingEndedEvent($room, $recordingmarks));
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace OCA\BigBlueButton\Controller;
|
namespace OCA\BigBlueButton\Controller;
|
||||||
|
|
||||||
|
use OCA\BigBlueButton\BackgroundJob\IsRunningJob;
|
||||||
use OCA\BigBlueButton\BigBlueButton\API;
|
use OCA\BigBlueButton\BigBlueButton\API;
|
||||||
use OCA\BigBlueButton\BigBlueButton\Presentation;
|
use OCA\BigBlueButton\BigBlueButton\Presentation;
|
||||||
use OCA\BigBlueButton\Db\Room;
|
use OCA\BigBlueButton\Db\Room;
|
||||||
|
@ -12,6 +13,7 @@ use OCA\BigBlueButton\Service\RoomService;
|
||||||
use OCP\AppFramework\Controller;
|
use OCP\AppFramework\Controller;
|
||||||
use OCP\AppFramework\Http\RedirectResponse;
|
use OCP\AppFramework\Http\RedirectResponse;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
use OCP\IUserSession;
|
use OCP\IUserSession;
|
||||||
|
@ -38,6 +40,9 @@ class JoinController extends Controller {
|
||||||
/** @var Permission */
|
/** @var Permission */
|
||||||
private $permission;
|
private $permission;
|
||||||
|
|
||||||
|
/** @var IJobList */
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $appName,
|
string $appName,
|
||||||
IRequest $request,
|
IRequest $request,
|
||||||
|
@ -45,7 +50,8 @@ class JoinController extends Controller {
|
||||||
IURLGenerator $urlGenerator,
|
IURLGenerator $urlGenerator,
|
||||||
IUserSession $userSession,
|
IUserSession $userSession,
|
||||||
API $api,
|
API $api,
|
||||||
Permission $permission
|
Permission $permission,
|
||||||
|
IJobList $jobList
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
|
|
||||||
|
@ -54,6 +60,7 @@ class JoinController extends Controller {
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
$this->api = $api;
|
$this->api = $api;
|
||||||
$this->permission = $permission;
|
$this->permission = $permission;
|
||||||
|
$this->jobList = $jobList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setToken(string $token): void {
|
public function setToken(string $token): void {
|
||||||
|
@ -129,6 +136,8 @@ class JoinController extends Controller {
|
||||||
$creationDate = $this->api->createMeeting($room, $presentation);
|
$creationDate = $this->api->createMeeting($room, $presentation);
|
||||||
$joinUrl = $this->api->createJoinUrl($room, $creationDate, $displayname, $isModerator, $userId);
|
$joinUrl = $this->api->createJoinUrl($room, $creationDate, $displayname, $isModerator, $userId);
|
||||||
|
|
||||||
|
$this->markAsRunning($room);
|
||||||
|
|
||||||
\OCP\Util::addHeader('meta', ['http-equiv' => 'refresh', 'content' => '3;url='.$joinUrl]);
|
\OCP\Util::addHeader('meta', ['http-equiv' => 'refresh', 'content' => '3;url='.$joinUrl]);
|
||||||
|
|
||||||
return new TemplateResponse($this->appName, 'forward', [
|
return new TemplateResponse($this->appName, 'forward', [
|
||||||
|
@ -153,4 +162,18 @@ class JoinController extends Controller {
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function markAsRunning(Room $room) {
|
||||||
|
if (!$room->running) {
|
||||||
|
$this->service->updateRunning($room->getId(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->jobList->has(IsRunningJob::class, [
|
||||||
|
'id' => $room->id,
|
||||||
|
])) {
|
||||||
|
$this->jobList->add(IsRunningJob::class, [
|
||||||
|
'id' => $room->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ use OCP\AppFramework\Db\Entity;
|
||||||
* @method bool getMediaCheck()
|
* @method bool getMediaCheck()
|
||||||
* @method bool getCleanLayout()
|
* @method bool getCleanLayout()
|
||||||
* @method bool getJoinMuted()
|
* @method bool getJoinMuted()
|
||||||
|
* @method bool getRunning()
|
||||||
* @method void setUid(string $uid)
|
* @method void setUid(string $uid)
|
||||||
* @method void setName(string $name)
|
* @method void setName(string $name)
|
||||||
* @method void setAttendeePassword(string $pw)
|
* @method void setAttendeePassword(string $pw)
|
||||||
|
@ -42,6 +43,7 @@ use OCP\AppFramework\Db\Entity;
|
||||||
* @method void setMediaCheck(bool $mediaCheck)
|
* @method void setMediaCheck(bool $mediaCheck)
|
||||||
* @method void setCleanLayout(bool $cleanLayout)
|
* @method void setCleanLayout(bool $cleanLayout)
|
||||||
* @method void setJoinMuted(bool $joinMuted)
|
* @method void setJoinMuted(bool $joinMuted)
|
||||||
|
* @method void setRunning(bool $running)
|
||||||
*/
|
*/
|
||||||
class Room extends Entity implements JsonSerializable {
|
class Room extends Entity implements JsonSerializable {
|
||||||
public const ACCESS_PUBLIC = 'public';
|
public const ACCESS_PUBLIC = 'public';
|
||||||
|
@ -71,6 +73,7 @@ class Room extends Entity implements JsonSerializable {
|
||||||
public $mediaCheck;
|
public $mediaCheck;
|
||||||
public $cleanLayout;
|
public $cleanLayout;
|
||||||
public $joinMuted;
|
public $joinMuted;
|
||||||
|
public $running;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->addType('maxParticipants', 'integer');
|
$this->addType('maxParticipants', 'integer');
|
||||||
|
@ -82,6 +85,7 @@ class Room extends Entity implements JsonSerializable {
|
||||||
$this->addType('mediaCheck', 'boolean');
|
$this->addType('mediaCheck', 'boolean');
|
||||||
$this->addType('cleanLayout', 'boolean');
|
$this->addType('cleanLayout', 'boolean');
|
||||||
$this->addType('joinMuted', 'boolean');
|
$this->addType('joinMuted', 'boolean');
|
||||||
|
$this->addType('running', 'boolean');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize(): array {
|
public function jsonSerialize(): array {
|
||||||
|
@ -103,6 +107,7 @@ class Room extends Entity implements JsonSerializable {
|
||||||
'mediaCheck' => boolval($this->mediaCheck),
|
'mediaCheck' => boolval($this->mediaCheck),
|
||||||
'cleanLayout' => boolval($this->cleanLayout),
|
'cleanLayout' => boolval($this->cleanLayout),
|
||||||
'joinMuted' => boolval($this->joinMuted),
|
'joinMuted' => boolval($this->joinMuted),
|
||||||
|
'running' => boolval($this->running),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\BigBlueButton\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated migration step: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
class Version000000Date20220316151400 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
* @return null|ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
if ($schema->hasTable('bbb_rooms')) {
|
||||||
|
$table = $schema->getTable('bbb_rooms');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('running')) {
|
||||||
|
$table->addColumn('running', 'boolean', [
|
||||||
|
'notnull' => false,
|
||||||
|
'default' => false
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,6 +163,21 @@ class RoomService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \OCP\AppFramework\Db\Entity|null
|
||||||
|
*/
|
||||||
|
public function updateRunning(int $id, bool $running) {
|
||||||
|
try {
|
||||||
|
$room = $this->mapper->find($id);
|
||||||
|
|
||||||
|
$room->setRunning($running);
|
||||||
|
|
||||||
|
return $this->mapper->update($room);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$this->handleException($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Room|null
|
* @return Room|null
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -11,6 +11,7 @@ use OCA\BigBlueButton\Service\RoomService;
|
||||||
use OCP\AppFramework\Http;
|
use OCP\AppFramework\Http;
|
||||||
use OCP\AppFramework\Http\RedirectResponse;
|
use OCP\AppFramework\Http\RedirectResponse;
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\BackgroundJob\IJobList;
|
||||||
use OCP\IRequest;
|
use OCP\IRequest;
|
||||||
use OCP\IURLGenerator;
|
use OCP\IURLGenerator;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
|
@ -26,6 +27,7 @@ class JoinControllerTest extends TestCase {
|
||||||
private $api;
|
private $api;
|
||||||
private $permission;
|
private $permission;
|
||||||
private $room;
|
private $room;
|
||||||
|
private $jobList;
|
||||||
|
|
||||||
public function setUp(): void {
|
public function setUp(): void {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
@ -36,6 +38,7 @@ class JoinControllerTest extends TestCase {
|
||||||
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
||||||
$this->api = $this->createMock(API::class);
|
$this->api = $this->createMock(API::class);
|
||||||
$this->permission = $this->createMock(Permission::class);
|
$this->permission = $this->createMock(Permission::class);
|
||||||
|
$this->jobList = $this->createMock(IJobList::class);
|
||||||
|
|
||||||
$this->controller = new JoinController(
|
$this->controller = new JoinController(
|
||||||
'bbb',
|
'bbb',
|
||||||
|
@ -44,10 +47,12 @@ class JoinControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->userSession,
|
$this->userSession,
|
||||||
$this->api,
|
$this->api,
|
||||||
$this->permission
|
$this->permission,
|
||||||
|
$this->jobList
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->room = new Room();
|
$this->room = new Room();
|
||||||
|
$this->room->id = 1;
|
||||||
$this->room->uid = 'uid_foo';
|
$this->room->uid = 'uid_foo';
|
||||||
$this->room->userId = 'user_foo';
|
$this->room->userId = 'user_foo';
|
||||||
$this->room->access = Room::ACCESS_PUBLIC;
|
$this->room->access = Room::ACCESS_PUBLIC;
|
||||||
|
|
|
@ -44,6 +44,7 @@ export interface Room {
|
||||||
mediaCheck: boolean,
|
mediaCheck: boolean,
|
||||||
cleanLayout: boolean,
|
cleanLayout: boolean,
|
||||||
joinMuted: boolean,
|
joinMuted: boolean,
|
||||||
|
running: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RoomShare {
|
export interface RoomShare {
|
||||||
|
|
|
@ -184,6 +184,10 @@ pre {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.name {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tfoot td {
|
tfoot td {
|
||||||
|
|
|
@ -187,9 +187,9 @@ const RoomRow: React.FC<Props> = (props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<tr className={showRecordings ? 'selected-row' : ''}>
|
<tr className={showRecordings ? 'selected-row' : ''}>
|
||||||
<td className="start icon-col">
|
<td className="start">
|
||||||
<a href={api.getRoomUrl(room)} className="action-item" target="_blank" rel="noopener noreferrer" title={t('bbb', 'Open room')}>
|
<a href={api.getRoomUrl(room)} className="button primary" target="_blank" rel="noopener noreferrer" title={t('bbb', 'Open room')}>
|
||||||
<span className="icon icon-play icon-visible"></span>
|
{room.running ? t('bbb', 'Join') : t('bbb', 'Start')}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td className="share icon-col">
|
<td className="share icon-col">
|
||||||
|
|
|
@ -65,7 +65,7 @@ async function openDialog(fileId: number, filename: string) {
|
||||||
const row = $('<tr>');
|
const row = $('<tr>');
|
||||||
const button = $('<button>');
|
const button = $('<button>');
|
||||||
|
|
||||||
button.text(t('bbb', 'Start'));
|
button.text(room.running ? t('bbb', 'Send to') : t('bbb', 'Start with'));
|
||||||
button.addClass('primary');
|
button.addClass('primary');
|
||||||
button.attr('type', 'button');
|
button.attr('type', 'button');
|
||||||
button.on('click', (ev) => {
|
button.on('click', (ev) => {
|
||||||
|
|
Loading…
Reference in New Issue