diff --git a/lib/Controller/PodcastController.php b/lib/Controller/PodcastController.php index e3f34bc..896f7b1 100644 --- a/lib/Controller/PodcastController.php +++ b/lib/Controller/PodcastController.php @@ -4,8 +4,9 @@ declare(strict_types=1); namespace OCA\RePod\Controller; +use OCA\GPodderSync\Core\PodcastData\PodcastData; +use OCA\GPodderSync\Core\PodcastData\PodcastDataReader; use OCA\RePod\AppInfo\Application; -use OCA\RePod\Core\PodcastData\PodcastData; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\Http\Client\IClientService; @@ -15,16 +16,24 @@ class PodcastController extends Controller { public function __construct( IRequest $request, - private IClientService $clientService + private IClientService $clientService, + private PodcastDataReader $podcastDataReader ) { parent::__construct(Application::APP_ID, $request); } public function index(string $url): JSONResponse { + $podcast = $this->podcastDataReader->tryGetCachedPodcastData($url); + + if ($podcast) { + return new JSONResponse($podcast); + } + $client = $this->clientService->newClient(); $feed = $client->get($url); $podcast = PodcastData::parseRssXml((string) $feed->getBody()); + $this->podcastDataReader->trySetCachedPodcastData($url, $podcast); - return new JSONResponse($podcast->toArrayWithExtras(), $feed->getStatusCode()); + return new JSONResponse($podcast, $feed->getStatusCode()); } } diff --git a/lib/Core/EpisodeAction/EpisodeActionReader.php b/lib/Core/EpisodeAction/EpisodeActionReader.php index ca1f14d..e217677 100644 --- a/lib/Core/EpisodeAction/EpisodeActionReader.php +++ b/lib/Core/EpisodeAction/EpisodeActionReader.php @@ -6,7 +6,6 @@ namespace OCA\RePod\Core\EpisodeAction; use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader as CoreEpisodeActionReader; use OCA\GPodderSync\Db\EpisodeAction\EpisodeActionRepository; -use OCA\RePod\Core\PodcastData\PodcastData; use OCA\RePod\Service\UserService; class EpisodeActionReader extends CoreEpisodeActionReader @@ -53,40 +52,40 @@ class EpisodeActionReader extends CoreEpisodeActionReader $name = (string) $item->title; // Get episode link - $link = PodcastData::stringOrNull($item->link); + $link = $this->stringOrNull($item->link); // Get episode image - $image = PodcastData::stringOrNull($item->image->url); + $image = $this->stringOrNull($item->image->url); if (!$image && $iTunesItemChildren) { $imageAttributes = $iTunesItemChildren->image->attributes(); - $image = PodcastData::stringOrNull($imageAttributes ? (string) $imageAttributes->href : ''); + $image = $this->stringOrNull($imageAttributes ? (string) $imageAttributes->href : ''); } if (!$image) { - $image = PodcastData::stringOrNull($channel->image->url); + $image = $this->stringOrNull($channel->image->url); } if (!$image && $iTunesChannelChildren) { $imageAttributes = $iTunesChannelChildren->image->attributes(); - $image = PodcastData::stringOrNull($imageAttributes ? (string) $imageAttributes->href : ''); + $image = $this->stringOrNull($imageAttributes ? (string) $imageAttributes->href : ''); } if (!$image) { preg_match('/stringOrNull($matches[1]); } // Get episode description $itemContent = $item->children('content', true); if ($itemContent) { - $description = PodcastData::stringOrNull($itemContent->encoded); + $description = $this->stringOrNull($itemContent->encoded); } else { - $description = PodcastData::stringOrNull($item->description); + $description = $this->stringOrNull($item->description); } if (!$description && $iTunesItemChildren) { - $description = PodcastData::stringOrNull($iTunesItemChildren->summary); + $description = $this->stringOrNull($iTunesItemChildren->summary); } // Remove tags @@ -94,9 +93,9 @@ class EpisodeActionReader extends CoreEpisodeActionReader // Get episode duration if ($iTunesItemChildren) { - $rawDuration = PodcastData::stringOrNull($iTunesItemChildren->duration); + $rawDuration = $this->stringOrNull($iTunesItemChildren->duration); } else { - $rawDuration = PodcastData::stringOrNull($item->duration); + $rawDuration = $this->stringOrNull($item->duration); } $splitDuration = array_reverse(explode(':', $rawDuration ?? '')); @@ -105,7 +104,7 @@ class EpisodeActionReader extends CoreEpisodeActionReader $duration += !empty($splitDuration[2]) ? (int) $splitDuration[2] * 60 : 0; // Get episode pubDate - $rawPubDate = PodcastData::stringOrNull($item->pubDate); + $rawPubDate = $this->stringOrNull($item->pubDate); $pubDate = $rawPubDate ? new \DateTime($rawPubDate) : null; $episodes[] = new EpisodeActionExtraData( @@ -127,4 +126,15 @@ class EpisodeActionReader extends CoreEpisodeActionReader return $episodes; } + + /** + * @param null|\SimpleXMLElement|string $value + */ + private function stringOrNull($value): ?string { + if ($value) { + return (string) $value; + } + + return null; + } } diff --git a/lib/Core/PodcastData/PodcastData.php b/lib/Core/PodcastData/PodcastData.php deleted file mode 100644 index 4aa71b3..0000000 --- a/lib/Core/PodcastData/PodcastData.php +++ /dev/null @@ -1,105 +0,0 @@ -channel; - - return new PodcastData( - self::stringOrNull($channel->title), - self::getXPathContent($xml, '/rss/channel/itunes:author'), - self::stringOrNull($channel->link), - self::stringOrNull($channel->description), - self::getXPathContent($xml, '/rss/channel/image/url') - ?? self::getXPathAttribute($xml, '/rss/channel/itunes:image/@href'), - $fetchedAtUnix ?? (new \DateTime())->getTimestamp(), - null, - self::getXPathContent($xml, '/rss/channel/atom:link/@href') - ); - } - - /** - * @param null|\SimpleXMLElement|string $value - */ - public static function stringOrNull($value): ?string { - if ($value) { - return (string) $value; - } - - return null; - } - - public function getAtomLink(): ?string { - return $this->atomLink; - } - - /** - * @return PodcastDataType - */ - public function toArrayWithExtras() { - return array_merge(parent::toArray(), [ - 'atomLink' => $this->atomLink, - ]); - } - - private static function getXPathContent(\SimpleXMLElement $xml, string $xpath): ?string { - $match = $xml->xpath($xpath); - if ($match) { - return (string) $match[0]; - } - - return null; - } - - private static function getXPathAttribute(\SimpleXMLElement $xml, string $xpath): ?string { - $match = $xml->xpath($xpath); - if ($match) { - return (string) $match[0][0]; - } - - return null; - } -} diff --git a/src/views/Feed.vue b/src/views/Feed.vue index 0074554..677b86d 100644 --- a/src/views/Feed.vue +++ b/src/views/Feed.vue @@ -26,7 +26,6 @@ import Episodes from '../components/Feed/Episodes.vue' import Loading from '../components/Atoms/Loading.vue' import axios from '@nextcloud/axios' import { generateUrl } from '@nextcloud/router' -import { toUrl } from '../utils/url.js' export default { name: 'Feed', @@ -53,11 +52,6 @@ export default { async mounted() { try { const podcastData = await axios.get(generateUrl('/apps/repod/podcast?url={url}', { url: this.url })) - - if (podcastData.data.atomLink && podcastData.data.atomLink !== this.url) { - this.$router.push(toUrl(podcastData.data.atomLink)) - } - this.feed = podcastData.data } catch (e) { this.failed = true