diff options
-rw-r--r-- | appinfo/routes/routesRecordingController.php | 4 | ||||
-rw-r--r-- | lib/Controller/RecordingController.php | 37 | ||||
-rw-r--r-- | src/components/AdminSettings/RecordingServer.vue | 90 | ||||
-rw-r--r-- | src/services/recordingService.js | 11 |
4 files changed, 142 insertions, 0 deletions
diff --git a/appinfo/routes/routesRecordingController.php b/appinfo/routes/routesRecordingController.php index ef1facc12..6d984ad3d 100644 --- a/appinfo/routes/routesRecordingController.php +++ b/appinfo/routes/routesRecordingController.php @@ -30,6 +30,10 @@ $requirements = [ return [ 'ocs' => [ + /** @see \OCA\Talk\Controller\RecordingController::getWelcomeMessage() */ + ['name' => 'Recording#getWelcomeMessage', 'url' => '/api/{apiVersion}/recording/welcome/{serverId}', 'verb' => 'GET', 'requirements' => array_merge($requirements, [ + 'serverId' => '\d+', + ])], /** @see \OCA\Talk\Controller\RecordingController::start() */ ['name' => 'Recording#start', 'url' => '/api/{apiVersion}/recording/{token}', 'verb' => 'POST', 'requirements' => $requirements], /** @see \OCA\Talk\Controller\RecordingController::stop() */ diff --git a/lib/Controller/RecordingController.php b/lib/Controller/RecordingController.php index d5ed53fa0..15b17b115 100644 --- a/lib/Controller/RecordingController.php +++ b/lib/Controller/RecordingController.php @@ -26,12 +26,14 @@ declare(strict_types=1); namespace OCA\Talk\Controller; use InvalidArgumentException; +use GuzzleHttp\Exception\ConnectException; use OCA\Talk\Config; use OCA\Talk\Exceptions\UnauthorizedException; use OCA\Talk\Service\RecordingService; use OCA\Talk\Service\SIPBridgeService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; +use OCP\Http\Client\IClientService; use OCP\IRequest; class RecordingController extends AEnvironmentAwareController { @@ -40,11 +42,46 @@ class RecordingController extends AEnvironmentAwareController { IRequest $request, private Config $talkConfig, private SIPBridgeService $SIPBridgeService, + private IClientService $clientService, private RecordingService $recordingService ) { parent::__construct($appName, $request); } + public function getWelcomeMessage(int $serverId): DataResponse { + $recordingServers = $this->talkConfig->getRecordingServers(); + if (empty($recordingServers) || !isset($recordingServers[$serverId])) { + return new DataResponse([], Http::STATUS_NOT_FOUND); + } + + $url = rtrim($recordingServers[$serverId]['server'], '/'); + + $client = $this->clientService->newClient(); + try { + $response = $client->get($url . '/api/v1/welcome', [ + 'verify' => (bool) $recordingServers[$serverId]['verify'], + 'nextcloud' => [ + 'allow_local_address' => true, + ], + ]); + + $body = $response->getBody(); + $data = json_decode($body, true); + + if (!is_array($data)) { + return new DataResponse([ + 'error' => 'JSON_INVALID', + ], Http::STATUS_INTERNAL_SERVER_ERROR); + } + + return new DataResponse($data); + } catch (ConnectException $e) { + return new DataResponse(['error' => 'CAN_NOT_CONNECT'], Http::STATUS_INTERNAL_SERVER_ERROR); + } catch (\Exception $e) { + return new DataResponse(['error' => $e->getCode()], Http::STATUS_INTERNAL_SERVER_ERROR); + } + } + /** * @PublicPage * @RequireModeratorParticipant diff --git a/src/components/AdminSettings/RecordingServer.vue b/src/components/AdminSettings/RecordingServer.vue index 06956b9a0..cab3d78a8 100644 --- a/src/components/AdminSettings/RecordingServer.vue +++ b/src/components/AdminSettings/RecordingServer.vue @@ -45,6 +45,17 @@ <Delete :size="20" /> </template> </NcButton> + + <div v-if="server"> + <div class="testing-icon"> + <NcLoadingIcon v-if="!checked" :size="20" /> + <AlertCircle v-else-if="errorMessage" :size="20" :fill-color="'#E9322D'" /> + <Check v-else :size="20" :fill-color="'#46BA61'" /> + </div> + <div class="testing-label"> + {{ connectionState }} + </div> + </div> </div> </template> @@ -52,7 +63,10 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js' import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' +import AlertCircle from 'vue-material-design-icons/AlertCircle.vue' +import Check from 'vue-material-design-icons/Check.vue' import Delete from 'vue-material-design-icons/Delete.vue' +import { getWelcomeMessage } from '../../services/recordingService.js' export default { name: 'RecordingServer', @@ -61,6 +75,8 @@ export default { NcButton, NcCheckboxRadioSwitch, NcLoadingIcon, + AlertCircle, + Check, Delete, }, @@ -86,6 +102,42 @@ export default { }, }, + data() { + return { + checked: false, + errorMessage: '', + versionFound: '', + } + }, + + computed: { + connectionState() { + if (!this.checked) { + return t('spreed', 'Status: Checking connection') + } + if (this.errorMessage) { + return this.errorMessage + } + return t('spreed', 'OK: Running version: {version}', { + version: this.versionFound, + }) + }, + }, + + watch: { + loading(isLoading) { + if (!isLoading) { + this.checkServerVersion() + } + }, + }, + + mounted() { + if (this.server) { + this.checkServerVersion() + } + }, + methods: { removeServer() { this.$emit('remove-server', this.index) @@ -96,6 +148,30 @@ export default { updateVerify(checked) { this.$emit('update:verify', checked) }, + + async checkServerVersion() { + this.checked = false + + this.errorMessage = '' + this.versionFound = '' + + try { + const response = await getWelcomeMessage(this.index) + this.checked = true + this.versionFound = response.data.ocs.data.version + } catch (exception) { + this.checked = true + if (exception.response.data.ocs.data.error === 'CAN_NOT_CONNECT') { + this.errorMessage = t('spreed', 'Error: Cannot connect to server') + } else if (exception.response.data.ocs.data.error === 'JSON_INVALID') { + this.errorMessage = t('spreed', 'Error: Server did not respond with proper JSON') + } else if (exception.response.data.ocs.data.error) { + this.errorMessage = t('spreed', 'Error: Server responded with: {error}', exception.response.data.ocs.data) + } else { + this.errorMessage = t('spreed', 'Error: Unknown error occurred') + } + } + }, }, } </script> @@ -110,5 +186,19 @@ export default { margin: 0 20px; display: inline-block; } + + .testing-icon{ + display: inline-block; + height: 20px; + line-height: 44px; + vertical-align: middle; + } + + .testing-label { + display: inline-block; + height: 44px; + line-height: 44px; + vertical-align: middle; + } } </style> diff --git a/src/services/recordingService.js b/src/services/recordingService.js index b663b8a81..f56b2757e 100644 --- a/src/services/recordingService.js +++ b/src/services/recordingService.js @@ -24,6 +24,16 @@ import axios from '@nextcloud/axios' import { generateOcsUrl } from '@nextcloud/router' /** + * Get welcome message from the recording server + * + * @param {number} serverId the index in the list of configured recording + * servers + */ +const getWelcomeMessage = async (serverId) => { + return axios.get(generateOcsUrl('apps/spreed/api/v1/recording/welcome/{serverId}', { serverId })) +} + +/** * Start call recording * * @param {string} token conversation token @@ -46,6 +56,7 @@ const stopCallRecording = async (token) => { } export { + getWelcomeMessage, startCallRecording, stopCallRecording, } |