<?php declare(strict_types=1); namespace OCA\RePod\Controller; use OCA\GPodderSync\Core\PodcastData\PodcastDataReader; use OCA\GPodderSync\Core\PodcastData\PodcastMetricsReader; use OCA\GPodderSync\Core\SubscriptionChange\SubscriptionChangeSaver; use OCA\RePod\AppInfo\Application; use OCA\RePod\Service\UserService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataDownloadResponse; use OCP\AppFramework\Http\Response; use OCP\IL10N; use OCP\IRequest; class OpmlController extends Controller { public function __construct( IRequest $request, private IL10N $l10n, private PodcastDataReader $podcastDataReader, private PodcastMetricsReader $podcastMetricsReader, private SubscriptionChangeSaver $subscriptionChangeSaver, private UserService $userService ) { parent::__construct(Application::APP_ID, $request); } /** * @NoAdminRequired * @NoCSRFRequired */ public function export(): DataDownloadResponse { // https://github.com/AntennaPod/AntennaPod/blob/master/core/src/main/java/de/danoeh/antennapod/core/export/opml/OpmlWriter.java $xml = new \SimpleXMLElement('<opml/>', namespaceOrPrefix: 'http://xmlpull.org/v1/doc/features.html#indent-output'); $xml->addAttribute('version', '2.0'); $dateCreated = new \DateTime(); $head = $xml->addChild('head'); if (isset($head)) { $head->addChild('title', $this->l10n->t('RePod Subscriptions')); $head->addChild('dateCreated', $dateCreated->format(\DateTime::RFC822)); } $body = $xml->addChild('body'); if (isset($body)) { $subscriptions = $this->podcastMetricsReader->metrics($this->userService->getUserUID()); foreach ($subscriptions as $subscription) { try { $podcast = $this->podcastDataReader->getCachedOrFetchPodcastData($subscription->getUrl(), $this->userService->getUserUID()); } catch (\Exception $e) { continue; } if ($podcast) { $outline = $body->addChild('outline'); if (isset($outline)) { $outline->addAttribute('xmlUrl', $subscription->getUrl()); $title = $podcast->getTitle(); $link = $podcast->getLink(); if (isset($title)) { $outline->addAttribute('text', $title); $outline->addAttribute('title', $title); } if (isset($link)) { $outline->addAttribute('htmlUrl', $link); } } } } } return new DataDownloadResponse((string) $xml->asXML(), 'repod-'.$dateCreated->getTimestamp().'.opml', ' application/xml'); } /** * @NoAdminRequired * @NoCSRFRequired */ public function import(): Response { $file = $this->request->getUploadedFile('import'); if ($file) { $xml = new \SimpleXMLElement(file_get_contents((string) $file['tmp_name'])); /** @var \SimpleXMLElement[] $outlines */ $outlines = $xml->body->children(); $toSubscribe = []; foreach ($outlines as $outline) { $toSubscribe[] = (string) $outline['xmlUrl']; } $this->subscriptionChangeSaver->saveSubscriptionChanges($toSubscribe, [], $this->userService->getUserUID()); } return new Response(); } }