Browse Source

Add repair step to register reminder index for existing events

Signed-off-by: Georg Ehrke <developer@georgehrke.com>
Georg Ehrke 4 years ago
parent
commit
2d6473e79b

+ 1 - 0
apps/dav/appinfo/info.xml

@@ -33,6 +33,7 @@
 			<step>OCA\DAV\Migration\CalDAVRemoveEmptyValue</step>
 			<step>OCA\DAV\Migration\BuildCalendarSearchIndex</step>
 			<step>OCA\DAV\Migration\RefreshWebcalJobRegistrar</step>
+			<step>OCA\DAV\Migration\RegisterBuildReminderIndexBackgroundJob</step>
 			<step>OCA\DAV\Migration\RemoveOrphanEventsAndContacts</step>
 			<step>OCA\DAV\Migration\RemoveClassifiedEventActivity</step>
 		</post-migration>

+ 2 - 0
apps/dav/composer/composer/autoload_classmap.php

@@ -11,6 +11,7 @@ return array(
     'OCA\\DAV\\Avatars\\AvatarHome' => $baseDir . '/../lib/Avatars/AvatarHome.php',
     'OCA\\DAV\\Avatars\\AvatarNode' => $baseDir . '/../lib/Avatars/AvatarNode.php',
     'OCA\\DAV\\Avatars\\RootCollection' => $baseDir . '/../lib/Avatars/RootCollection.php',
+    'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => $baseDir . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
     'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => $baseDir . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
     'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => $baseDir . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
     'OCA\\DAV\\BackgroundJob\\EventReminderJob' => $baseDir . '/../lib/BackgroundJob/EventReminderJob.php',
@@ -179,6 +180,7 @@ return array(
     'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => $baseDir . '/../lib/Migration/FixBirthdayCalendarComponent.php',
     'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => $baseDir . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
     'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => $baseDir . '/../lib/Migration/RegenerateBirthdayCalendars.php',
+    'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => $baseDir . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
     'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => $baseDir . '/../lib/Migration/RemoveClassifiedEventActivity.php',
     'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => $baseDir . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
     'OCA\\DAV\\Migration\\Version1004Date20170825134824' => $baseDir . '/../lib/Migration/Version1004Date20170825134824.php',

+ 2 - 0
apps/dav/composer/composer/autoload_static.php

@@ -26,6 +26,7 @@ class ComposerStaticInitDAV
         'OCA\\DAV\\Avatars\\AvatarHome' => __DIR__ . '/..' . '/../lib/Avatars/AvatarHome.php',
         'OCA\\DAV\\Avatars\\AvatarNode' => __DIR__ . '/..' . '/../lib/Avatars/AvatarNode.php',
         'OCA\\DAV\\Avatars\\RootCollection' => __DIR__ . '/..' . '/../lib/Avatars/RootCollection.php',
+        'OCA\\DAV\\BackgroundJob\\BuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/BuildReminderIndexBackgroundJob.php',
         'OCA\\DAV\\BackgroundJob\\CleanupDirectLinksJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupDirectLinksJob.php',
         'OCA\\DAV\\BackgroundJob\\CleanupInvitationTokenJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/CleanupInvitationTokenJob.php',
         'OCA\\DAV\\BackgroundJob\\EventReminderJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/EventReminderJob.php',
@@ -194,6 +195,7 @@ class ComposerStaticInitDAV
         'OCA\\DAV\\Migration\\FixBirthdayCalendarComponent' => __DIR__ . '/..' . '/../lib/Migration/FixBirthdayCalendarComponent.php',
         'OCA\\DAV\\Migration\\RefreshWebcalJobRegistrar' => __DIR__ . '/..' . '/../lib/Migration/RefreshWebcalJobRegistrar.php',
         'OCA\\DAV\\Migration\\RegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/Migration/RegenerateBirthdayCalendars.php',
+        'OCA\\DAV\\Migration\\RegisterBuildReminderIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/RegisterBuildReminderIndexBackgroundJob.php',
         'OCA\\DAV\\Migration\\RemoveClassifiedEventActivity' => __DIR__ . '/..' . '/../lib/Migration/RemoveClassifiedEventActivity.php',
         'OCA\\DAV\\Migration\\RemoveOrphanEventsAndContacts' => __DIR__ . '/..' . '/../lib/Migration/RemoveOrphanEventsAndContacts.php',
         'OCA\\DAV\\Migration\\Version1004Date20170825134824' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170825134824.php',

+ 134 - 0
apps/dav/lib/BackgroundJob/BuildReminderIndexBackgroundJob.php

@@ -0,0 +1,134 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright 2019 Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @author Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCA\DAV\BackgroundJob;
+
+use OC\BackgroundJob\QueuedJob;
+use OCA\DAV\CalDAV\Reminder\ReminderService;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\IJobList;
+use OCP\IDBConnection;
+use OCP\ILogger;
+
+/**
+ * Class BuildReminderIndexBackgroundJob
+ *
+ * @package OCA\DAV\BackgroundJob
+ */
+class BuildReminderIndexBackgroundJob extends QueuedJob {
+
+	/** @var IDBConnection */
+	private $db;
+
+	/** @var ReminderService */
+	private $reminderService;
+
+	/** @var ILogger */
+	private $logger;
+
+	/** @var IJobList */
+	private $jobList;
+
+	/** @var ITimeFactory */
+	private $timeFactory;
+
+	/**
+	 * BuildReminderIndexBackgroundJob constructor.
+	 *
+	 * @param IDBConnection $db
+	 * @param ReminderService $reminderService
+	 * @param ILogger $logger
+	 * @param IJobList $jobList
+	 * @param ITimeFactory $timeFactory
+	 */
+	public function __construct(IDBConnection $db,
+								ReminderService $reminderService,
+								ILogger $logger,
+								IJobList $jobList,
+								ITimeFactory $timeFactory) {
+		$this->db = $db;
+		$this->reminderService = $reminderService;
+		$this->logger = $logger;
+		$this->jobList = $jobList;
+		$this->timeFactory = $timeFactory;
+	}
+
+	/**
+	 * @param $arguments
+	 */
+	public function run($arguments) {
+		$offset = (int) $arguments['offset'];
+		$stopAt = (int) $arguments['stopAt'];
+
+		$this->logger->info('Building calendar reminder index (' . $offset .'/' . $stopAt . ')');
+
+		$offset = $this->buildIndex($offset, $stopAt);
+
+		if ($offset >= $stopAt) {
+			$this->logger->info('Building calendar reminder index done');
+		} else {
+			$this->jobList->add(self::class, [
+				'offset' => $offset,
+				'stopAt' => $stopAt
+			]);
+			$this->logger->info('Scheduled a new BuildReminderIndexBackgroundJob with offset ' . $offset);
+		}
+	}
+
+	/**
+	 * @param int $offset
+	 * @param int $stopAt
+	 * @return int
+	 */
+	private function buildIndex(int $offset, int $stopAt):int {
+		$startTime = $this->timeFactory->getTime();
+
+		$query = $this->db->getQueryBuilder();
+		$query->select('*')
+			->from('calendarobjects')
+			->where($query->expr()->lte('id', $query->createNamedParameter($stopAt)))
+			->andWhere($query->expr()->gt('id', $query->createNamedParameter($offset)))
+			->orderBy('id', 'ASC');
+
+		$stmt = $query->execute();
+		while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+			$offset = $row['id'];
+			if (is_resource($row['calendardata'])) {
+				$row['calendardata'] = stream_get_contents($row['calendardata']);
+			}
+			$row['component'] = $row['componenttype'];
+
+			try {
+				$this->reminderService->onTouchCalendarObject('\OCA\DAV\CalDAV\CalDavBackend::createCalendarObject', $row);
+			} catch(\Exception $ex) {
+				$this->logger->logException($ex);
+			}
+
+			if (($this->timeFactory->getTime() - $startTime) > 15) {
+				return $offset;
+			}
+		}
+
+		return $stopAt;
+	}
+}

+ 5 - 4
apps/dav/lib/CalDAV/Reminder/NotificationProvider/EmailProvider.php

@@ -108,7 +108,8 @@ class EmailProvider extends AbstractProvider {
 			if ($organizer) {
 				$message->setReplyTo($organizer);
 			}
-			$message->setBcc($emailAddresses);
+			$message->setTo([])
+				->setBcc($emailAddresses);
 
 			$template = $this->mailer->createEMailTemplate('dav.calendarReminder');
 			$template->addHeader();
@@ -185,7 +186,7 @@ class EmailProvider extends AbstractProvider {
 			return null;
 		}
 
-		$organizer = $vevent->ORGANZIER;
+		$organizer = $vevent->ORGANIZER;
 		if (strcasecmp($organizer->getValue(), 'mailto:') !== 0) {
 			return null;
 		}
@@ -309,7 +310,7 @@ class EmailProvider extends AbstractProvider {
 			}
 		}
 
-		if (isset($vevent->ORGANIZER)) {
+		if (isset($vevent->ORGANIZER) && $this->hasAttendeeMailURI($vevent->ORGANIZER)) {
 			$emailAddresses[$this->getEMailAddressOfAttendee($vevent->ORGANIZER)] = [];
 		}
 
@@ -349,7 +350,7 @@ class EmailProvider extends AbstractProvider {
 	 * @return bool
 	 */
 	private function hasAttendeeMailURI(VObject\Property $attendee):bool {
-		return strcasecmp($attendee->getValue(), 'mailto:') === 0;
+		return stripos($attendee->getValue(), 'mailto:') === 0;
 	}
 
 	/**

+ 96 - 0
apps/dav/lib/Migration/RegisterBuildReminderIndexBackgroundJob.php

@@ -0,0 +1,96 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright 2019 Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @author Georg Ehrke <oc.list@georgehrke.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCA\DAV\Migration;
+
+use OCA\DAV\BackgroundJob\BuildReminderIndexBackgroundJob;
+use OCP\BackgroundJob\IJobList;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+/**
+ * Class RegisterBuildReminderIndexBackgroundJob
+ *
+ * @package OCA\DAV\Migration
+ */
+class RegisterBuildReminderIndexBackgroundJob implements IRepairStep {
+
+	/** @var IDBConnection */
+	private $db;
+
+	/** @var IJobList */
+	private $jobList;
+
+	/** @var IConfig */
+	private $config;
+
+	/** @var string */
+	private const CONFIG_KEY = 'buildCalendarReminderIndex';
+
+	/**
+	 * @param IDBConnection $db
+	 * @param IJobList $jobList
+	 * @param IConfig $config
+	 */
+	public function __construct(IDBConnection $db,
+								IJobList $jobList,
+								IConfig $config) {
+		$this->db = $db;
+		$this->jobList = $jobList;
+		$this->config = $config;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getName() {
+		return 'Registering building of calendar reminder index as background job';
+	}
+
+	/**
+	 * @param IOutput $output
+	 */
+	public function run(IOutput $output) {
+		// only run once
+		if ($this->config->getAppValue('dav', self::CONFIG_KEY) === 'yes') {
+			$output->info('Repair step already executed');
+			return;
+		}
+
+		$query = $this->db->getQueryBuilder();
+		$query->select($query->createFunction('MAX(' . $query->getColumnName('id') . ')'))
+			->from('calendarobjects');
+		$maxId = (int)$query->execute()->fetchColumn();
+
+		$output->info('Add background job');
+		$this->jobList->add(BuildReminderIndexBackgroundJob::class, [
+			'offset' => 0,
+			'stopAt' => $maxId
+		]);
+
+		// if all were done, no need to redo the repair during next upgrade
+		$this->config->setAppValue('dav', self::CONFIG_KEY, 'yes');
+	}
+}