Fix determination of cron job run

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/32576/head
Joas Schilling 2022-05-24 14:11:42 +07:00
parent 251f450df6
commit fdcf3eafd6
No known key found for this signature in database
GPG Key ID: 7076EA9751AACDDA
3 changed files with 95 additions and 8 deletions

@ -22,6 +22,7 @@ return array(
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => $baseDir . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => $baseDir . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => $baseDir . '/../lib/BackgroundJob/UploadCleanup.php',
'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => $baseDir . '/../lib/BackgroundJob/UserStatusAutomation.php',
'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => $baseDir . '/../lib/BulkUpload/BulkUploadPlugin.php',
'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => $baseDir . '/../lib/BulkUpload/MultipartRequestParser.php',
'OCA\\DAV\\CalDAV\\Activity\\Backend' => $baseDir . '/../lib/CalDAV/Activity/Backend.php',
@ -247,6 +248,7 @@ return array(
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => $baseDir . '/../lib/Listener/ClearPhotoCacheListener.php',
'OCA\\DAV\\Listener\\SubscriptionListener' => $baseDir . '/../lib/Listener/SubscriptionListener.php',
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => $baseDir . '/../lib/Listener/TrustedServerRemovedListener.php',
'OCA\\DAV\\Listener\\UserPreferenceListener' => $baseDir . '/../lib/Listener/UserPreferenceListener.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => $baseDir . '/../lib/Migration/BuildSocialSearchIndex.php',

@ -37,6 +37,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\BackgroundJob\\RegisterRegenerateBirthdayCalendars' => __DIR__ . '/..' . '/../lib/BackgroundJob/RegisterRegenerateBirthdayCalendars.php',
'OCA\\DAV\\BackgroundJob\\UpdateCalendarResourcesRoomsBackgroundJob' => __DIR__ . '/..' . '/../lib/BackgroundJob/UpdateCalendarResourcesRoomsBackgroundJob.php',
'OCA\\DAV\\BackgroundJob\\UploadCleanup' => __DIR__ . '/..' . '/../lib/BackgroundJob/UploadCleanup.php',
'OCA\\DAV\\BackgroundJob\\UserStatusAutomation' => __DIR__ . '/..' . '/../lib/BackgroundJob/UserStatusAutomation.php',
'OCA\\DAV\\BulkUpload\\BulkUploadPlugin' => __DIR__ . '/..' . '/../lib/BulkUpload/BulkUploadPlugin.php',
'OCA\\DAV\\BulkUpload\\MultipartRequestParser' => __DIR__ . '/..' . '/../lib/BulkUpload/MultipartRequestParser.php',
'OCA\\DAV\\CalDAV\\Activity\\Backend' => __DIR__ . '/..' . '/../lib/CalDAV/Activity/Backend.php',
@ -262,6 +263,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => __DIR__ . '/..' . '/../lib/Listener/ClearPhotoCacheListener.php',
'OCA\\DAV\\Listener\\SubscriptionListener' => __DIR__ . '/..' . '/../lib/Listener/SubscriptionListener.php',
'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/TrustedServerRemovedListener.php',
'OCA\\DAV\\Listener\\UserPreferenceListener' => __DIR__ . '/..' . '/../lib/Listener/UserPreferenceListener.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndex.php',

@ -23,14 +23,19 @@ declare(strict_types=1);
namespace OCA\DAV\BackgroundJob;
use DateTime;
use OCA\DAV\CalDAV\Schedule\Plugin;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\IJobList;
use OCP\BackgroundJob\TimedJob;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\IDBConnection;
use Psr\Log\LoggerInterface;
use Sabre\VObject\Component\Available;
use Sabre\VObject\Component\VAvailability;
use Sabre\VObject\Reader;
use Sabre\VObject\Recur\RRuleIterator;
class UserStatusAutomation extends TimedJob {
protected IDBConnection $connection;
@ -49,7 +54,9 @@ class UserStatusAutomation extends TimedJob {
$this->logger = $logger;
$this->config = $config;
$this->setInterval(1); // FIXME $this->setInterval(240);
// Interval 0 might look weird, but the last_checked is always moved
// to the next time we need this and then it's 0 seconds ago.
$this->setInterval(0);
}
/**
@ -70,6 +77,88 @@ class UserStatusAutomation extends TimedJob {
return;
}
$property = $this->getAvailabilityFromPropertiesTable($userId);
if (!$property) {
$this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the user has no availability settings');
$this->jobList->remove(self::class, $argument);
return;
}
$isCurrentlyAvailable = false;
$nextPotentialToggles = [];
$now = new \DateTime('now');
$lastMidnight = (clone $now)->setTime(0, 0);
$vObject = Reader::read($property);
foreach ($vObject->getComponents() as $component) {
if ($component->name !== 'VAVAILABILITY') {
continue;
}
/** @var VAvailability $component */
$availables = $component->getComponents();
foreach ($availables as $available) {
/** @var Available $available */
if ($available->name === 'AVAILABLE') {
/** @var \DateTimeInterface $effectiveStart */
/** @var \DateTimeInterface $effectiveEnd */
[$effectiveStart, $effectiveEnd] = $available->getEffectiveStartEnd();
try {
$it = new RRuleIterator((string) $available->RRULE, $effectiveStart);
$it->fastForward($lastMidnight);
$startToday = $it->current();
if ($startToday && $startToday <= $now) {
$duration = $effectiveStart->diff($effectiveEnd);
$endToday = $startToday->add($duration);
if ($endToday > $now) {
// User is currently available
// Also queuing the end time as next status toggle
$isCurrentlyAvailable = true;
$nextPotentialToggles[] = $endToday->getTimestamp();
}
// Availability enabling already done for today,
// so jump to the next recurrence to find the next status toggle
$it->next();
}
if ($it->current()) {
$nextPotentialToggles[] = $it->current()->getTimestamp();
}
} catch (\Exception $e) {
$this->logger->error($e->getMessage(), ['exception' => $e]);
}
}
}
}
$nextAutomaticToggle = min($nextPotentialToggles);
$this->setLastRunToNextToggleTime($userId, $nextAutomaticToggle - 1);
// FIXME Currently available so disable DND
$isCurrentlyAvailable = (bool)$isCurrentlyAvailable;
$this->logger->debug('User status automation ran');
}
protected function setLastRunToNextToggleTime(string $userId, int $timestamp): void {
$query = $this->connection->getQueryBuilder();
$query->update('jobs')
->set('last_run', $query->createNamedParameter($timestamp, IQueryBuilder::PARAM_INT))
->where($query->expr()->eq('id', $query->createNamedParameter($this->getId(), IQueryBuilder::PARAM_INT)));
$query->executeStatement();
$this->logger->debug('Updated user status automation last_run to ' . $timestamp . ' for user ' . $userId);
}
/**
* @param string $userId
* @return false|string
*/
protected function getAvailabilityFromPropertiesTable(string $userId) {
$propertyPath = 'calendars/' . $userId . '/inbox';
$propertyName = '{' . Plugin::NS_CALDAV . '}calendar-availability';
@ -85,12 +174,6 @@ class UserStatusAutomation extends TimedJob {
$property = $result->fetchOne();
$result->closeCursor();
if (!$property) {
$this->logger->info('Removing ' . self::class . ' background job for user "' . $userId . '" because the user has no availability settings');
$this->jobList->remove(self::class, $argument);
return;
}
$this->logger->debug('User status automation ran');
return $property;
}
}