diff options
author | SebastianKrupinski <krupinskis05@gmail.com> | 2025-05-08 15:06:07 -0400 |
---|---|---|
committer | SebastianKrupinski <krupinskis05@gmail.com> | 2025-05-08 15:06:07 -0400 |
commit | 652bbf7cc598132da73ddb7e75850561526c070a (patch) | |
tree | 8ac1ea7ca1ef1345fae1effaad0189f0e2ac0d1c | |
parent | be42c1eafee2421cee967d0eeefc48824bd83c12 (diff) | |
download | nextcloud-server-feat/issue-563-calendar-import.tar.gz nextcloud-server-feat/issue-563-calendar-import.zip |
fixup! feat: Calendar Importfeat/issue-563-calendar-import
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
-rw-r--r-- | apps/dav/appinfo/info.xml | 2 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/CalendarImpl.php | 5 | ||||
-rw-r--r-- | apps/dav/lib/Command/ImportCalendar.php | 53 | ||||
-rw-r--r-- | apps/dav/tests/unit/CalDAV/Import/ImportServiceTest.php | 12 | ||||
-rw-r--r-- | lib/public/Calendar/CalendarImportOptions.php | 5 |
5 files changed, 42 insertions, 35 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml index 6caae313dc8..65858e49088 100644 --- a/apps/dav/appinfo/info.xml +++ b/apps/dav/appinfo/info.xml @@ -62,6 +62,7 @@ <command>OCA\DAV\Command\DeleteSubscription</command> <command>OCA\DAV\Command\ExportCalendar</command> <command>OCA\DAV\Command\FixCalendarSyncCommand</command> + <command>OCA\DAV\Command\ImportCalendar</command> <command>OCA\DAV\Command\ListAddressbooks</command> <command>OCA\DAV\Command\ListCalendars</command> <command>OCA\DAV\Command\ListSubscriptions</command> @@ -71,7 +72,6 @@ <command>OCA\DAV\Command\SendEventReminders</command> <command>OCA\DAV\Command\SyncBirthdayCalendar</command> <command>OCA\DAV\Command\SyncSystemAddressBook</command> - <command>OCA\DAV\Command\ImportCalendar</command> </commands> <settings> diff --git a/apps/dav/lib/CalDAV/CalendarImpl.php b/apps/dav/lib/CalDAV/CalendarImpl.php index a12fe5604a8..b45a35a7847 100644 --- a/apps/dav/lib/CalDAV/CalendarImpl.php +++ b/apps/dav/lib/CalDAV/CalendarImpl.php @@ -9,16 +9,17 @@ declare(strict_types=1); namespace OCA\DAV\CalDAV; use Exception; -use InvalidArgumentException; use Generator; +use InvalidArgumentException; use OCA\DAV\CalDAV\Auth\CustomPrincipalPlugin; use OCA\DAV\CalDAV\InvitationResponse\InvitationResponseServer; +use OCP\Calendar\CalendarExportOptions; use OCP\Calendar\CalendarImportOptions; use OCP\Calendar\Exceptions\CalendarException; use OCP\Calendar\ICalendarExport; +use OCP\Calendar\ICalendarImport; use OCP\Calendar\ICalendarIsShared; use OCP\Calendar\ICalendarIsWritable; -use OCP\Calendar\ICalendarImport; use OCP\Calendar\ICreateFromString; use OCP\Calendar\IHandleImipMessage; use OCP\Constants; diff --git a/apps/dav/lib/Command/ImportCalendar.php b/apps/dav/lib/Command/ImportCalendar.php index a1ac4021d11..990a4b953f2 100644 --- a/apps/dav/lib/Command/ImportCalendar.php +++ b/apps/dav/lib/Command/ImportCalendar.php @@ -47,8 +47,8 @@ class ImportCalendar extends Command { ->setDescription('Import calendar data to supported calendars from disk or stdin') ->addArgument('uid', InputArgument::REQUIRED, 'Id of system user') ->addArgument('cid', InputArgument::REQUIRED, 'Id of calendar') - ->addArgument('format', InputArgument::OPTIONAL, 'Format of output (iCal, jCal, xCal) default to iCal') - ->addArgument('location', InputArgument::OPTIONAL, 'location of where to write the output. defaults to stdin') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'Format of input (ical, jcal, xcal) defaults to ical', 'ical') + ->addOption('location', null, InputOption::VALUE_REQUIRED, 'Location of where to write the input. defaults to stdin') ->addOption('errors', null, InputOption::VALUE_REQUIRED, 'how to handel item errors (0 - continue, 1 - fail)') ->addOption('validation', null, InputOption::VALUE_REQUIRED, 'how to handel item validation (0 - no validation, 1 - validate and skip on issue, 2 - validate and fail on issue)') ->addOption('supersede', null, InputOption::VALUE_NONE, 'override/replace existing items') @@ -65,11 +65,11 @@ class ImportCalendar extends Command { $location = $input->getArgument('location'); $errors = is_numeric($input->getOption('errors')) ? (int)$input->getOption('errors') : null; $validation = is_numeric($input->getOption('validation')) ? (int)$input->getOption('validation') : null; - $supersede = $input->getOption('supersede') ? true : false; - $showCreated = $input->getOption('show-created') ? true : false; - $showUpdated = $input->getOption('show-updated') ? true : false; - $showSkipped = $input->getOption('show-skipped') ? true : false; - $showErrors = $input->getOption('show-errors') ? true : false; + $supersede = $input->getOption('supersede'); + $showCreated = $input->getOption('show-created'); + $showUpdated = $input->getOption('show-updated'); + $showSkipped = $input->getOption('show-skipped'); + $showErrors = $input->getOption('show-errors'); if (!$this->userManager->userExists($userId)) { throw new InvalidArgumentException("User <$userId> not found."); @@ -105,41 +105,38 @@ class ImportCalendar extends Command { $options->setValidate($validation); } // evaluate if provided format is supported - if ($format !== null && !in_array($format, $this->importService::FORMATS, true)) { + if (!in_array($format, ImportService::FORMATS, true)) { throw new InvalidArgumentException("Format <$format> is not valid."); - } else { - $options->setFormat($format ?? 'ical'); } + $options->setFormat($format); // evaluate if a valid location was given and is usable otherwise default to stdin $timeStarted = microtime(true); if ($location !== null) { $input = fopen($location, 'r'); if ($input === false) { throw new InvalidArgumentException("Location <$location> is not valid. Can not open location for read operation."); - } else { - try { - $outcome = $this->importService->import($input, $calendar, $options); - } finally { - fclose($input); - } + } + try { + $outcome = $this->importService->import($input, $calendar, $options); + } finally { + fclose($input); } } else { $input = fopen('php://stdin', 'r'); if ($input === false) { throw new InvalidArgumentException('Can not open stdin for read operation.'); - } else { - try { - $tempPath = $this->tempManager->getTemporaryFile(); - $tempFile = fopen($tempPath, 'w+'); - while (!feof($input)) { - fwrite($tempFile, fread($input, 8192)); - } - fseek($tempFile, 0); - $outcome = $this->importService->import($tempFile, $calendar, $options); - } finally { - fclose($input); - fclose($tempFile); + } + try { + $tempPath = $this->tempManager->getTemporaryFile(); + $tempFile = fopen($tempPath, 'w+'); + while (!feof($input)) { + fwrite($tempFile, fread($input, 8192)); } + fseek($tempFile, 0); + $outcome = $this->importService->import($tempFile, $calendar, $options); + } finally { + fclose($input); + fclose($tempFile); } } $timeFinished = microtime(true); diff --git a/apps/dav/tests/unit/CalDAV/Import/ImportServiceTest.php b/apps/dav/tests/unit/CalDAV/Import/ImportServiceTest.php index 8b2c22c27d3..b7889cdd563 100644 --- a/apps/dav/tests/unit/CalDAV/Import/ImportServiceTest.php +++ b/apps/dav/tests/unit/CalDAV/Import/ImportServiceTest.php @@ -33,6 +33,7 @@ class ImportServiceTest extends \Test\TestCase { } public function testImport(): void { + // Arrange // construct calendar with a 1 hour event and same start/end time zones $vCalendar = new VCalendar(); /** @var VEvent $vEvent */ @@ -58,14 +59,18 @@ class ImportServiceTest extends \Test\TestCase { $this->calendar->expects($this->once()) ->method('import') ->willReturnCallback($this->mockCollector(...)); - // test import + + // Act $this->service->import($stream, $this->calendar, $options); + + // Assert $this->assertCount(1, $this->mockImportCollection, 'Imported items count is invalid'); $this->assertTrue(isset($this->mockImportCollection[0]->VEVENT), 'Imported item missing VEVENT'); $this->assertCount(1, $this->mockImportCollection[0]->VEVENT, 'Imported items count is invalid'); } public function testImportWithMultiLineUID(): void { + // Arrange // construct calendar with a 1 hour event and same start/end time zones $vCalendar = new VCalendar(); /** @var VEvent $vEvent */ @@ -91,8 +96,11 @@ class ImportServiceTest extends \Test\TestCase { $this->calendar->expects($this->once()) ->method('import') ->willReturnCallback($this->mockCollector(...)); - // test import + + // Act $this->service->import($stream, $this->calendar, $options); + + // Assert $this->assertCount(1, $this->mockImportCollection, 'Imported items count is invalid'); $this->assertTrue(isset($this->mockImportCollection[0]->VEVENT), 'Imported item missing VEVENT'); $this->assertCount(1, $this->mockImportCollection[0]->VEVENT, 'Imported items count is invalid'); diff --git a/lib/public/Calendar/CalendarImportOptions.php b/lib/public/Calendar/CalendarImportOptions.php index 2cbb1bfb917..6b05074cae0 100644 --- a/lib/public/Calendar/CalendarImportOptions.php +++ b/lib/public/Calendar/CalendarImportOptions.php @@ -29,6 +29,7 @@ final class CalendarImportOptions { self::ERROR_FAIL, ]; + /** @var 'ical'|'jcal'|'xcal' */ private string $format = 'ical'; private bool $supersede = false; private int $errors = self::ERROR_FAIL; @@ -37,7 +38,7 @@ final class CalendarImportOptions { /** * Gets the import format * - * @return string ical, jcal, xcal, etc, defaults to ical + * @return 'ical'|'jcal'|'xcal' (defaults to ical) */ public function getFormat(): string { return $this->format; @@ -46,7 +47,7 @@ final class CalendarImportOptions { /** * Sets the import format * - * @param string $format ical, jcal, xcal, etc, defaults to ical + * @param 'ical'|'jcal'|'xcal' $format */ public function setFormat(string $format): void { $this->format = $format; |