diff --git a/appinfo/info.xml b/appinfo/info.xml
index 0c2a11e..657c1d0 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -43,6 +43,10 @@ The official whiteboard app for Nextcloud. It allows users to create and share w
+
+ OCA\Whiteboard\BackgroundJob\WatchActiveUsers
+
+
OCA\Whiteboard\Settings\Admin
OCA\Whiteboard\Settings\Section
diff --git a/composer.json b/composer.json
index 5463952..4ef687e 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,8 @@
"license": "AGPL",
"require": {
"php": "^8.0",
- "firebase/php-jwt": "^6.10"
+ "firebase/php-jwt": "^6.10",
+ "ext-curl": "*"
},
"require-dev": {
"nextcloud/coding-standard": "^1.0",
diff --git a/lib/BackgrounJob/WatchActiveUsers.php b/lib/BackgrounJob/WatchActiveUsers.php
new file mode 100644
index 0000000..ffb0fcb
--- /dev/null
+++ b/lib/BackgrounJob/WatchActiveUsers.php
@@ -0,0 +1,65 @@
+setInterval(300);
+ }
+
+ protected function run($argument) {
+ $metricsData = $this->getMetricsData();
+ $activeUsers = $metricsData['totalUsers'] ?? 0;
+ $this->statsService->insertActiveUsersCount($activeUsers);
+ }
+
+ private function getMetricsData(): array {
+ $serverUrl = $this->configService->getCollabBackendUrl();
+ $metricToken = $this->configService->getCollabBackendMetricsToken();
+
+ if (!$serverUrl || !$metricToken) {
+ return [];
+ }
+
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $serverUrl . '/metrics');
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, [
+ 'Authorization: Bearer ' . $metricToken,
+ ]);
+ $response = curl_exec($curl);
+ curl_close($curl);
+
+ $metrics = [
+ 'totalUsers' => 0,
+ ];
+
+ foreach (explode("\n", $response) as $line) {
+ if (strpos($line, 'whiteboard_room_stats{stat="totalUsers"}') === false) {
+ continue;
+ }
+ $parts = explode(' ', $line);
+ $metrics['totalUsers'] = (int) $parts[1];
+ }
+
+ return $metrics;
+ }
+}
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php
index b36712e..96f18d3 100644
--- a/lib/Controller/SettingsController.php
+++ b/lib/Controller/SettingsController.php
@@ -36,6 +36,7 @@ public function update(): DataResponse {
$serverUrl = $this->request->getParam('serverUrl');
$secret = $this->request->getParam('secret');
$enableStatistics = $this->request->getParam('enableStatistics');
+ $metricsToken = $this->request->getParam('metricsToken');
if ($serverUrl !== null) {
$this->configService->setCollabBackendUrl($serverUrl);
@@ -49,6 +50,10 @@ public function update(): DataResponse {
$this->configService->setWhiteboardEnableStatistics($enableStatistics);
}
+ if ($metricsToken !== null) {
+ $this->configService->setCollabBackendMetricsToken($metricsToken);
+ }
+
return new DataResponse([
'jwt' => $this->jwtService->generateJWTFromPayload([ 'serverUrl' => $serverUrl ])
]);
diff --git a/lib/Controller/WhiteboardController.php b/lib/Controller/WhiteboardController.php
index a61cce2..79006bf 100644
--- a/lib/Controller/WhiteboardController.php
+++ b/lib/Controller/WhiteboardController.php
@@ -86,8 +86,8 @@ public function update(int $fileId, array $data): DataResponse {
$this->contentService->updateContent($file, $data);
- $event = new WhiteboardUpdatedEvent($file, $user, $data);
- $this->dispatcher->dispatchTyped($event);
+ $event = new WhiteboardUpdatedEvent($file, $user, $data);
+ $this->dispatcher->dispatchTyped($event);
return new DataResponse(['status' => 'success']);
} catch (Exception $e) {
diff --git a/lib/Events/AbstractWhiteboardEvent.php b/lib/Events/AbstractWhiteboardEvent.php
index 971462a..69222f4 100644
--- a/lib/Events/AbstractWhiteboardEvent.php
+++ b/lib/Events/AbstractWhiteboardEvent.php
@@ -1,10 +1,12 @@
userSession->getUser();
- $this->eventsService->insertEvent([
+ $this->statsService->insertEvent([
'user' => $currentUser ? $currentUser->getUID() : $node->getOwner()->getUID(),
'type' => 'created',
'share_token' => '',
diff --git a/lib/Listener/WhiteboardOpenedListener.php b/lib/Listener/WhiteboardOpenedListener.php
index 75618bc..16a3a8d 100644
--- a/lib/Listener/WhiteboardOpenedListener.php
+++ b/lib/Listener/WhiteboardOpenedListener.php
@@ -1,15 +1,17 @@
getFile();
$data = $event->getData();
- $this->eventsService->insertEvent([
+ $this->statsService->insertEvent([
'user' => $user->getUID(),
'type' => 'opened',
'share_token' => $user instanceof PublicSharingUser ? $user->getPublicSharingToken() : '',
diff --git a/lib/Listener/WhiteboardUpdatedListener.php b/lib/Listener/WhiteboardUpdatedListener.php
index c37ef30..7cf9e45 100644
--- a/lib/Listener/WhiteboardUpdatedListener.php
+++ b/lib/Listener/WhiteboardUpdatedListener.php
@@ -1,15 +1,17 @@
getFile();
$data = $event->getData();
- $this->eventsService->insertEvent([
+ $this->statsService->insertEvent([
'user' => $user->getUID(),
'type' => 'opened',
'share_token' => $user instanceof PublicSharingUser ? $user->getPublicSharingToken() : '',
diff --git a/lib/Migration/Version1000Date20241213132620.php b/lib/Migration/Version1000Date20241213132620.php
index ce27a7b..c638df5 100644
--- a/lib/Migration/Version1000Date20241213132620.php
+++ b/lib/Migration/Version1000Date20241213132620.php
@@ -76,6 +76,25 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table->addIndex(['fileid'], 'fileid_index');
}
+ if (!$schema->hasTable('whiteboard_active_users')) {
+ $table = $schema->createTable('whiteboard_active_users');
+ $table->addColumn('id', Types::BIGINT, [
+ 'autoincrement' => true,
+ 'notnull' => true,
+ 'length' => 20,
+ ]);
+ $table->addColumn('total_users', Types::INTEGER, [
+ 'notnull' => false,
+ 'length' => 11,
+ 'default' => 0,
+ ]);
+ $table->addColumn('timestamp', Types::INTEGER, [
+ 'notnull' => true,
+ 'length' => 11,
+ 'default' => 0,
+ ]);
+ }
+
return $schema;
}
diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php
index 92ae136..925b978 100644
--- a/lib/Service/ConfigService.php
+++ b/lib/Service/ConfigService.php
@@ -62,4 +62,21 @@ public function getWhiteboardEnableStatistics(): bool {
public function setWhiteboardEnableStatistics(bool $enableStatistics): void {
$this->appConfig->setAppValueBool('enable_statistics', $enableStatistics);
}
+
+ public function getCollabBackendMetricsToken(): string {
+ if (!method_exists($this->appConfig, 'getAppValueString')) {
+ return $this->appConfig->getAppValue('collabBackendMetricsToken');
+ }
+
+ return $this->appConfig->getAppValueString('collabBackendMetricsToken');
+ }
+
+ public function setCollabBackendMetricsToken(string $collabBackendMetricsToken): void {
+ if (!method_exists($this->appConfig, 'setAppValueString')) {
+ $this->appConfig->setAppValue('collabBackendMetricsToken', $collabBackendMetricsToken);
+ return;
+ }
+
+ $this->appConfig->setAppValueString('collabBackendMetricsToken', $collabBackendMetricsToken);
+ }
}
diff --git a/lib/Service/EventsService.php b/lib/Service/EventsService.php
deleted file mode 100644
index 56de18b..0000000
--- a/lib/Service/EventsService.php
+++ /dev/null
@@ -1,34 +0,0 @@
-connection->getQueryBuilder();
- $queryBuilder->insert('whiteboard_events')
- ->values([
- 'user' => $queryBuilder->createNamedParameter($data['user']),
- 'type' => $queryBuilder->createNamedParameter($data['type']),
- 'share_token' => $queryBuilder->createNamedParameter($data['share_token']),
- 'fileid' => $queryBuilder->createNamedParameter($data['fileid']),
- 'elements' => $queryBuilder->createNamedParameter($data['elements']),
- 'size' => $queryBuilder->createNamedParameter($data['size']),
- 'timestamp' => $queryBuilder->createNamedParameter($data['timestamp']),
- ])
- ->executeStatement();
- }
-}
diff --git a/lib/Service/StatsService.php b/lib/Service/StatsService.php
new file mode 100644
index 0000000..57b0cfc
--- /dev/null
+++ b/lib/Service/StatsService.php
@@ -0,0 +1,44 @@
+connection->getQueryBuilder();
+ $queryBuilder->insert('whiteboard_events')
+ ->values([
+ 'user' => $queryBuilder->createNamedParameter($data['user']),
+ 'type' => $queryBuilder->createNamedParameter($data['type']),
+ 'share_token' => $queryBuilder->createNamedParameter($data['share_token']),
+ 'fileid' => $queryBuilder->createNamedParameter($data['fileid']),
+ 'elements' => $queryBuilder->createNamedParameter($data['elements']),
+ 'size' => $queryBuilder->createNamedParameter($data['size']),
+ 'timestamp' => $queryBuilder->createNamedParameter($data['timestamp']),
+ ])
+ ->executeStatement();
+ }
+
+ public function insertActiveUsersCount(int $count): void {
+ $queryBuilder = $this->connection->getQueryBuilder();
+ $queryBuilder->insert('whiteboard_active_users')
+ ->values([
+ 'total_users' => $queryBuilder->createNamedParameter($count),
+ 'timestamp' => $queryBuilder->createNamedParameter(time()),
+ ])
+ ->executeStatement();
+ }
+}
diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php
index d3dff7d..6e98437 100644
--- a/lib/Settings/Admin.php
+++ b/lib/Settings/Admin.php
@@ -26,6 +26,7 @@ public function getForm(): TemplateResponse {
$this->initialState->provideInitialState('secret', $this->configService->getWhiteboardSharedSecret());
$this->initialState->provideInitialState('jwt', $this->jwtService->generateJWTFromPayload([]));
$this->initialState->provideInitialState('enable_statistics', $this->configService->getWhiteboardEnableStatistics());
+ $this->initialState->provideInitialState('metrics_token', $this->configService->getCollabBackendMetricsToken());
$response = new TemplateResponse(
'whiteboard',
'admin',
diff --git a/src/settings/Settings.vue b/src/settings/Settings.vue
index 2bf00d7..7647e37 100644
--- a/src/settings/Settings.vue
+++ b/src/settings/Settings.vue
@@ -38,6 +38,10 @@
{{ t('whiteboard', 'Enable statistics') }}
+
+
+