Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/notifications.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2020-07-09 12:33:04 +0300
committerGitHub <noreply@github.com>2020-07-09 12:33:04 +0300
commitddba5ec6923e8cdf8be22de3fdb1fcac1ef47bd9 (patch)
tree654ba0fbc5f8b1c410b7b3ed53c7856a13ef1ee8
parentd38c5bf17d29a19503ce70cbee7d89de2cdc3f8a (diff)
parentd54d5db30856bd6670a83c880dbe94ffbbf5be0b (diff)
Merge pull request #651 from nextcloud/feature/noid/allow-to-group-push-sending-for-a-whilev19.0.1RC1
[stable19] Allow to group push notifications via an event
-rw-r--r--lib/App.php18
-rw-r--r--lib/AppInfo/Application.php20
-rw-r--r--lib/Push.php41
3 files changed, 68 insertions, 11 deletions
diff --git a/lib/App.php b/lib/App.php
index 4744bba..248255f 100644
--- a/lib/App.php
+++ b/lib/App.php
@@ -50,12 +50,17 @@ class App implements IApp {
public function notify(INotification $notification): void {
$notificationId = $this->handler->add($notification);
+ $shouldFlush = $this->push->deferPayloads();
try {
$notificationToPush = $this->handler->getById($notificationId, $notification->getUser());
$this->push->pushToDevice($notificationId, $notificationToPush);
} catch (NotificationNotFoundException $e) {
throw new \InvalidArgumentException('Error while preparing push notification');
}
+
+ if ($shouldFlush) {
+ $this->push->flushPayloads();
+ }
}
/**
@@ -74,10 +79,23 @@ class App implements IApp {
public function markProcessed(INotification $notification): void {
$deleted = $this->handler->delete($notification);
+ $shouldFlush = $this->push->deferPayloads();
foreach ($deleted as $user => $notifications) {
foreach ($notifications as $notificationId) {
$this->push->pushDeleteToDevice($user, $notificationId);
}
}
+
+ if ($shouldFlush) {
+ $this->push->flushPayloads();
+ }
+ }
+
+ public function defer(): void {
+ $this->push->deferPayloads();
+ }
+
+ public function flush(): void {
+ $this->push->flushPayloads();
}
}
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 6a9de02..517827b 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -26,7 +26,10 @@ use OCA\Notifications\App;
use OCA\Notifications\Capabilities;
use OCA\Notifications\Handler;
use OCA\Notifications\Notifier\AdminNotifications;
+use OCA\Notifications\Push;
use OCP\AppFramework\IAppContainer;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Notification\IApp;
use OCP\Util;
class Application extends \OCP\AppFramework\App {
@@ -44,6 +47,7 @@ class Application extends \OCP\AppFramework\App {
public function register(): void {
$this->registerNotificationApp();
+ $this->registerTalkDeferPushing();
$this->registerAdminNotifications();
$this->registerUserInterface();
$this->registerUserDeleteHook();
@@ -77,6 +81,22 @@ class Application extends \OCP\AppFramework\App {
}
}
+ protected function registerTalkDeferPushing(): void {
+ /** @var IEventDispatcher $dispatcher */
+ $dispatcher = $this->getContainer()->getServer()->query(IEventDispatcher::class);
+
+ $dispatcher->addListener(IApp::class . '::defer', function() {
+ /** @var App $app */
+ $app = $this->getContainer()->query(App::class);
+ $app->defer();
+ });
+ $dispatcher->addListener(IApp::class . '::flush', function() {
+ /** @var App $app */
+ $app = $this->getContainer()->query(App::class);
+ $app->flush();
+ });
+ }
+
protected function registerUserDeleteHook(): void {
Util::connectHook('OC_User', 'post_deleteUser', $this, 'deleteUser');
}
diff --git a/lib/Push.php b/lib/Push.php
index 8e7c00e..67241e0 100644
--- a/lib/Push.php
+++ b/lib/Push.php
@@ -61,6 +61,10 @@ class Push {
protected $log;
/** @var OutputInterface */
protected $output;
+ /** @var array */
+ protected $payloadsToSend = [];
+ /** @var bool */
+ protected $deferPayloads = false;
public function __construct(IDBConnection $connection,
INotificationManager $notificationManager,
@@ -92,6 +96,17 @@ class Push {
}
}
+ public function deferPayloads(): bool {
+ $shouldFlush = !$this->deferPayloads;
+ $this->deferPayloads = true;
+ return $shouldFlush;
+ }
+
+ public function flushPayloads(): void {
+ $this->deferPayloads = false;
+ $this->sendNotificationsToProxies();
+ }
+
public function pushToDevice(int $id, INotification $notification, ?OutputInterface $output = null): void {
$user = $this->userManager->get($notification->getUser());
if (!($user instanceof IUser)) {
@@ -157,7 +172,6 @@ class Push {
// We don't push to devices that are older than 60 days
$maxAge = time() - 60 * 24 * 60 * 60;
- $pushNotifications = [];
foreach ($devices as $device) {
$this->printInfo('');
$this->printInfo('Device token:' . $device['token']);
@@ -171,17 +185,19 @@ class Push {
$payload = json_encode($this->encryptAndSign($userKey, $device, $id, $notification, $isTalkNotification));
$proxyServer = rtrim($device['proxyserver'], '/');
- if (!isset($pushNotifications[$proxyServer])) {
- $pushNotifications[$proxyServer] = [];
+ if (!isset($this->payloadsToSend[$proxyServer])) {
+ $this->payloadsToSend[$proxyServer] = [];
}
- $pushNotifications[$proxyServer][] = $payload;
+ $this->payloadsToSend[$proxyServer][] = $payload;
} catch (\InvalidArgumentException $e) {
// Failed to encrypt message for device: public key is invalid
$this->deletePushToken($device['token']);
}
}
- $this->sendNotificationsToProxies($pushNotifications);
+ if (!$this->deferPayloads) {
+ $this->sendNotificationsToProxies();
+ }
}
public function pushDeleteToDevice(string $userId, int $notificationId): void {
@@ -199,7 +215,6 @@ class Push {
$maxAge = time() - 60 * 24 * 60 * 60;
$userKey = $this->keyManager->getKey($user);
- $pushNotifications = [];
foreach ($devices as $device) {
if (!$this->validateToken($device['token'], $maxAge)) {
// Token does not exist anymore
@@ -210,20 +225,24 @@ class Push {
$payload = json_encode($this->encryptAndSignDelete($userKey, $device, $notificationId));
$proxyServer = rtrim($device['proxyserver'], '/');
- if (!isset($pushNotifications[$proxyServer])) {
- $pushNotifications[$proxyServer] = [];
+ if (!isset($this->payloadsToSend[$proxyServer])) {
+ $this->payloadsToSend[$proxyServer] = [];
}
- $pushNotifications[$proxyServer][] = $payload;
+ $this->payloadsToSend[$proxyServer][] = $payload;
} catch (\InvalidArgumentException $e) {
// Failed to encrypt message for device: public key is invalid
$this->deletePushToken($device['token']);
}
}
- $this->sendNotificationsToProxies($pushNotifications);
+ if (!$this->deferPayloads) {
+ $this->sendNotificationsToProxies();
+ }
}
- protected function sendNotificationsToProxies(array $pushNotifications): void {
+ protected function sendNotificationsToProxies(): void {
+ $pushNotifications = $this->payloadsToSend;
+ $this->payloadsToSend = [];
if (empty($pushNotifications)) {
return;
}