diff --git a/lib/BackgroundJob/RetentionJob.php b/lib/BackgroundJob/RetentionJob.php index 48305a8c..61edca2a 100644 --- a/lib/BackgroundJob/RetentionJob.php +++ b/lib/BackgroundJob/RetentionJob.php @@ -44,6 +44,7 @@ public function __construct( parent::__construct($timeFactory); // Run once a day $this->setInterval(24 * 60 * 60); + $this->setTimeSensitivity(self::TIME_INSENSITIVE); } public function run($argument): void { @@ -119,7 +120,7 @@ public function run($argument): void { $deleted = $this->expireNode($node, $deleteBefore, $timeAfter); if ($notifyDayBefore && !$deleted) { - $this->notifyNode($node, $notifyBefore); + $this->notifyNode($node, $notifyBefore, $timeAfter); } } @@ -190,18 +191,28 @@ protected function getDeletableNodeFromMountPoint(ICachedMountFileInfo $mountPoi throw new NotPermittedException(); } - private function expireNode(Node $node, \DateTime $deleteBefore, int $timeAfter): bool { - $mtime = new \DateTime(); + protected function getDateFromNode(Node $node, int $timeAfter): \DateTime { + $time = new \DateTime(); // Fallback is the mtime - $mtime->setTimestamp($node->getMTime()); + $time->setTimestamp($node->getMTime()); // Use the upload time if we have it if ($timeAfter === Constants::MODE_CTIME && $node->getUploadTime() !== 0) { - $mtime->setTimestamp($node->getUploadTime()); + $time->setTimestamp($node->getUploadTime()); + } elseif ($timeAfter === Constants::MODE_MTIME && $node->getMTime() < $node->getUploadTime()) { + // Use the upload time if it's newer than the modification time + $time->setTimestamp($node->getUploadTime()); + $this->logger->debug('Upload time of file ' . $node->getId() . ' is newer than modification time, continuing with that'); } - if ($mtime < $deleteBefore) { + return $time; + } + + private function expireNode(Node $node, \DateTime $deleteBefore, int $timeAfter): bool { + $time = $this->getDateFromNode($node, $timeAfter); + + if ($time < $deleteBefore) { $this->logger->debug('Expiring file ' . $node->getId()); try { $node->delete(); @@ -218,18 +229,10 @@ private function expireNode(Node $node, \DateTime $deleteBefore, int $timeAfter) return false; } - private function notifyNode(Node $node, \DateTime $notifyBefore): void { - $mtime = new \DateTime(); - - // Fallback is the mtime - $mtime->setTimestamp($node->getMTime()); - - // Use the upload time if we have it - if ($node->getUploadTime() !== 0) { - $mtime->setTimestamp($node->getUploadTime()); - } + private function notifyNode(Node $node, \DateTime $notifyBefore, int $timeAfter): void { + $time = $this->getDateFromNode($node, $timeAfter); - if ($mtime < $notifyBefore) { + if ($time < $notifyBefore) { $this->logger->debug('Notifying about retention tomorrow for file ' . $node->getId()); try { $notification = $this->notificationManager->createNotification(); diff --git a/screenshots/1.png b/screenshots/1.png index 6aa29ef4..b7577ce0 100644 Binary files a/screenshots/1.png and b/screenshots/1.png differ diff --git a/tests/lib/BackgroundJob/RetentionJobTest.php b/tests/lib/BackgroundJob/RetentionJobTest.php index 7fb840a5..0ad3995e 100644 --- a/tests/lib/BackgroundJob/RetentionJobTest.php +++ b/tests/lib/BackgroundJob/RetentionJobTest.php @@ -91,30 +91,37 @@ private function addTag(int $tagId, int $timeunit, int $timeamount, int $timeaft public static function deleteTestCases(): array { return [ - [[1, Constants::UNIT_DAY], [0, Constants::UNIT_DAY], false, 0], - [[2, Constants::UNIT_WEEK], [0, Constants::UNIT_DAY], false, 0], - [[3, Constants::UNIT_MONTH], [0, Constants::UNIT_DAY], false, 1], - [[4, Constants::UNIT_YEAR], [0, Constants::UNIT_DAY], false, 1], - - [[1, Constants::UNIT_DAY], [2, Constants::UNIT_DAY], true, 0], - [[2, Constants::UNIT_WEEK], [2, Constants::UNIT_DAY], false, 0], - [[3, Constants::UNIT_MONTH], [2, Constants::UNIT_DAY], false, 1], - [[4, Constants::UNIT_YEAR], [2, Constants::UNIT_DAY], false, 1], - - [[1, Constants::UNIT_DAY], [21, Constants::UNIT_DAY], true, 0], - [[2, Constants::UNIT_WEEK], [21, Constants::UNIT_DAY], true, 0], - [[3, Constants::UNIT_MONTH], [21, Constants::UNIT_DAY], false, 1], - [[4, Constants::UNIT_YEAR], [21, Constants::UNIT_DAY], false, 1], - - [[1, Constants::UNIT_DAY], [180, Constants::UNIT_DAY], true, 0], - [[2, Constants::UNIT_WEEK], [180, Constants::UNIT_DAY], true, 0], - [[3, Constants::UNIT_MONTH], [180, Constants::UNIT_DAY], true, 1], - [[4, Constants::UNIT_YEAR], [180, Constants::UNIT_DAY], false, 1], - - [[1, Constants::UNIT_DAY], [10000, Constants::UNIT_DAY], true, 0], - [[2, Constants::UNIT_WEEK], [10000, Constants::UNIT_DAY], true, 0], - [[3, Constants::UNIT_MONTH], [10000, Constants::UNIT_DAY], true, 1], - [[4, Constants::UNIT_YEAR], [10000, Constants::UNIT_DAY], true, 1], + [[1, Constants::UNIT_DAY], [0, Constants::UNIT_DAY], false, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], [0, Constants::UNIT_DAY], false, Constants::MODE_CTIME], + [[3, Constants::UNIT_MONTH], [0, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + [[4, Constants::UNIT_YEAR], [0, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + + [[1, Constants::UNIT_DAY], [2, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], [2, Constants::UNIT_DAY], false, Constants::MODE_CTIME], + [[3, Constants::UNIT_MONTH], [2, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + [[4, Constants::UNIT_YEAR], [2, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + + [[1, Constants::UNIT_DAY], [21, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], [21, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[3, Constants::UNIT_MONTH], [21, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + [[4, Constants::UNIT_YEAR], [21, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + + [[1, Constants::UNIT_DAY], [180, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], [180, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[3, Constants::UNIT_MONTH], [180, Constants::UNIT_DAY], true, Constants::MODE_MTIME], + [[4, Constants::UNIT_YEAR], [180, Constants::UNIT_DAY], false, Constants::MODE_MTIME], + + [[1, Constants::UNIT_DAY], [10000, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], [10000, Constants::UNIT_DAY], true, Constants::MODE_CTIME], + [[3, Constants::UNIT_MONTH], [10000, Constants::UNIT_DAY], true, Constants::MODE_MTIME], + [[4, Constants::UNIT_YEAR], [10000, Constants::UNIT_DAY], true, Constants::MODE_MTIME], + + [[2, Constants::UNIT_WEEK], ['mtime' => 10, 'ctime' => 10], false, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], ['mtime' => 10, 'ctime' => 16], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], ['mtime' => 16, 'ctime' => 16], true, Constants::MODE_CTIME], + [[2, Constants::UNIT_WEEK], ['mtime' => 10, 'ctime' => 10], false, Constants::MODE_MTIME], + [[2, Constants::UNIT_WEEK], ['mtime' => 10, 'ctime' => 16], false, Constants::MODE_MTIME], + [[2, Constants::UNIT_WEEK], ['mtime' => 16, 'ctime' => 16], true, Constants::MODE_MTIME], ]; } @@ -136,17 +143,14 @@ public function testDeleteFile(array $retentionTime, array $fileTime, bool $dele ->willReturn([$mountPoint]); $user = $this->createMock(IUser::class); - $mountPoint->expects($this->once()) - ->method('getUser') + $mountPoint->method('getUser') ->willReturn($user); - $user->expects($this->once()) - ->method('getUID') + $user->method('getUID') ->willReturn('admin'); $userFolder = $this->createMock(Folder::class); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') + $this->rootFolder->method('getUserFolder') ->with('admin') ->willReturn($userFolder); @@ -156,19 +160,29 @@ public function testDeleteFile(array $retentionTime, array $fileTime, bool $dele ->with(1337) ->willReturn([$node]); - $delta = new \DateInterval('P' . $fileTime[0] . 'D'); - $now = new \DateTime(); - $now->setTimestamp($this->timestampbase); - $mtime = $now->sub($delta); + if (isset($fileTime['mtime'])) { + $delta = new \DateInterval('P' . $fileTime['mtime'] . 'D'); + $now = new \DateTime(); + $now->setTimestamp($this->timestampbase); + $mtime = $now->sub($delta); - $node->expects($this->once()) - ->method('getMTime') - ->willReturn($mtime->getTimestamp()); + $delta = new \DateInterval('P' . $fileTime['ctime'] . 'D'); + $now = new \DateTime(); + $now->setTimestamp($this->timestampbase); + $ctime = $now->sub($delta); + } else { + $delta = new \DateInterval('P' . $fileTime[0] . 'D'); + $now = new \DateTime(); + $now->setTimestamp($this->timestampbase); + $mtime = $ctime = $now->sub($delta); + } - $node->expects($after === 0 ? $this->exactly(2) : $this->never()) - ->method('getUploadTime') + $node->method('getMTime') ->willReturn($mtime->getTimestamp()); + $node->method('getUploadTime') + ->willReturn($ctime->getTimestamp()); + $node->method('isDeletable') ->willReturn(true);