aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Command
diff options
context:
space:
mode:
authorSebastianKrupinski <krupinskis05@gmail.com>2025-04-03 19:54:08 -0400
committerDaniel Kesselberg <mail@danielkesselberg.de>2025-05-06 11:09:33 +0200
commita2d4f8d3f13a1f94db24d05c477815d2fe0b16f6 (patch)
tree77a75f74d3736ddd2a72caf84b037c1e43b21133 /apps/dav/lib/Command
parentcd9f0350b0c8201b528f5f86883e68928018e512 (diff)
downloadnextcloud-server-a2d4f8d3f13a1f94db24d05c477815d2fe0b16f6.tar.gz
nextcloud-server-a2d4f8d3f13a1f94db24d05c477815d2fe0b16f6.zip
feat: Calendar Exportfeat/issue-563-calendar-export
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
Diffstat (limited to 'apps/dav/lib/Command')
-rw-r--r--apps/dav/lib/Command/ExportCalendar.php95
1 files changed, 95 insertions, 0 deletions
diff --git a/apps/dav/lib/Command/ExportCalendar.php b/apps/dav/lib/Command/ExportCalendar.php
new file mode 100644
index 00000000000..5758cd4fa87
--- /dev/null
+++ b/apps/dav/lib/Command/ExportCalendar.php
@@ -0,0 +1,95 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\DAV\Command;
+
+use InvalidArgumentException;
+use OCA\DAV\CalDAV\Export\ExportService;
+use OCP\Calendar\CalendarExportOptions;
+use OCP\Calendar\ICalendarExport;
+use OCP\Calendar\IManager;
+use OCP\IUserManager;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Calendar Export Command
+ *
+ * Used to export data from supported calendars to disk or stdout
+ */
+#[AsCommand(
+ name: 'calendar:export',
+ description: 'Export calendar data from supported calendars to disk or stdout',
+ hidden: false
+)]
+class ExportCalendar extends Command {
+ public function __construct(
+ private IUserManager $userManager,
+ private IManager $calendarManager,
+ private ExportService $exportService,
+ ) {
+ parent::__construct();
+ }
+
+ protected function configure(): void {
+ $this->setName('calendar:export')
+ ->setDescription('Export calendar data from supported calendars to disk or stdout')
+ ->addArgument('uid', InputArgument::REQUIRED, 'Id of system user')
+ ->addArgument('uri', InputArgument::REQUIRED, 'Uri of calendar')
+ ->addOption('format', null, InputOption::VALUE_REQUIRED, 'Format of output (ical, jcal, xcal) defaults to ical', 'ical')
+ ->addOption('location', null, InputOption::VALUE_REQUIRED, 'Location of where to write the output. defaults to stdout');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $userId = $input->getArgument('uid');
+ $calendarId = $input->getArgument('uri');
+ $format = $input->getOption('format');
+ $location = $input->getOption('location');
+
+ if (!$this->userManager->userExists($userId)) {
+ throw new InvalidArgumentException("User <$userId> not found.");
+ }
+ // retrieve calendar and evaluate if export is supported
+ $calendars = $this->calendarManager->getCalendarsForPrincipal('principals/users/' . $userId, [$calendarId]);
+ if ($calendars === []) {
+ throw new InvalidArgumentException("Calendar <$calendarId> not found.");
+ }
+ $calendar = $calendars[0];
+ if (!$calendar instanceof ICalendarExport) {
+ throw new InvalidArgumentException("Calendar <$calendarId> does not support exporting");
+ }
+ // construct options object
+ $options = new CalendarExportOptions();
+ // evaluate if provided format is supported
+ if (!in_array($format, ExportService::FORMATS, true)) {
+ throw new InvalidArgumentException("Format <$format> is not valid.");
+ }
+ $options->setFormat($format);
+ // evaluate is a valid location was given and is usable otherwise output to stdout
+ if ($location !== null) {
+ $handle = fopen($location, 'wb');
+ if ($handle === false) {
+ throw new InvalidArgumentException("Location <$location> is not valid. Can not open location for write operation.");
+ }
+
+ foreach ($this->exportService->export($calendar, $options) as $chunk) {
+ fwrite($handle, $chunk);
+ }
+ fclose($handle);
+ } else {
+ foreach ($this->exportService->export($calendar, $options) as $chunk) {
+ $output->writeln($chunk);
+ }
+ }
+
+ return self::SUCCESS;
+ }
+}