RePod-Nextcloud-App/lib/Controller/OpmlController.php
2024-11-12 10:11:21 +01:00

110 lines
3.3 KiB
PHP

<?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\Attribute\FrontpageRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
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 readonly IL10N $l10n,
private readonly PodcastDataReader $podcastDataReader,
private readonly PodcastMetricsReader $podcastMetricsReader,
private readonly SubscriptionChangeSaver $subscriptionChangeSaver,
private readonly UserService $userService
) {
parent::__construct(Application::APP_ID, $request);
}
#[NoAdminRequired]
#[NoCSRFRequired]
#[FrontpageRoute(verb: 'GET', url: '/opml/export')]
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) {
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]
#[FrontpageRoute(verb: 'POST', url: '/opml/import')]
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();
}
}