From 4771a52b630fa8f0d96e6166e58ed17d48a5ff8c Mon Sep 17 00:00:00 2001 From: Kalle Fagerberg Date: Sat, 17 Sep 2022 18:12:13 +0200 Subject: [PATCH] Extracted PodcastData to its own endpoint --- appinfo/routes.php | 1 + lib/Controller/PersonalSettingsController.php | 25 +++++++++++++++++- ...astDataCache.php => PodcastDataReader.php} | 26 ++++++++++++++----- lib/Core/PodcastData/PodcastMetrics.php | 11 -------- lib/Core/PodcastData/PodcastMetricsReader.php | 20 +------------- .../SubscriptionChangeMapper.php | 3 ++- .../SubscriptionChangeRepository.php | 2 +- 7 files changed, 48 insertions(+), 40 deletions(-) rename lib/Core/PodcastData/{PodcastDataCache.php => PodcastDataReader.php} (58%) diff --git a/appinfo/routes.php b/appinfo/routes.php index 731a7d1..1e49c26 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -15,5 +15,6 @@ return [ ['name' => 'subscription_change#list', 'url' => '/subscriptions', 'verb' => 'GET'], ['name' => 'subscription_change#create', 'url' => '/subscription_change/create', 'verb' => 'POST'], ['name' => 'personal_settings#metrics', 'url' => '/personal_settings/metrics', 'verb' => 'GET'], + ['name' => 'personal_settings#podcastData', 'url' => '/personal_settings/podcast_data', 'verb' => 'GET'], ] ]; diff --git a/lib/Controller/PersonalSettingsController.php b/lib/Controller/PersonalSettingsController.php index 3e1cb05..ae676dc 100644 --- a/lib/Controller/PersonalSettingsController.php +++ b/lib/Controller/PersonalSettingsController.php @@ -3,10 +3,11 @@ declare(strict_types=1); namespace OCA\GPodderSync\Controller; -use OCA\GPodderSync\Core\PodcastData\PodcastMetrics; +use OCA\GPodderSync\Core\PodcastData\PodcastDataReader; use OCA\GPodderSync\Core\PodcastData\PodcastMetricsReader; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; @@ -14,16 +15,19 @@ class PersonalSettingsController extends Controller { private string $userId; private PodcastMetricsReader $metricsReader; + private PodcastDataReader $dataReader; public function __construct( string $AppName, IRequest $request, string $UserId, PodcastMetricsReader $metricsReader, + PodcastDataReader $dataReader, ) { parent::__construct($AppName, $request); $this->userId = $UserId ?? ''; $this->metricsReader = $metricsReader; + $this->dataReader = $dataReader; } /** @@ -39,4 +43,23 @@ class PersonalSettingsController extends Controller { 'subscriptions' => $metrics, ]); } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * @param string $url + * @return JsonResponse + */ + public function podcastData(string $url = ''): JsonResponse { + if ($url === '') { + return new JSONResponse([ + 'message' => "Missing query parameter 'url'.", + 'data' => null, + ], statusCode: Http::STATUS_BAD_REQUEST); + } + return new JsonResponse([ + 'data' => $this->dataReader->getCachedOrFetchPodcastData($url, $this->userId), + ]); + } } diff --git a/lib/Core/PodcastData/PodcastDataCache.php b/lib/Core/PodcastData/PodcastDataReader.php similarity index 58% rename from lib/Core/PodcastData/PodcastDataCache.php rename to lib/Core/PodcastData/PodcastDataReader.php index 1003fea..0dbdbb0 100644 --- a/lib/Core/PodcastData/PodcastDataCache.php +++ b/lib/Core/PodcastData/PodcastDataReader.php @@ -3,39 +3,51 @@ declare(strict_types=1); namespace OCA\GPodderSync\Core\PodcastData; +use OCA\GPodderSync\Db\SubscriptionChange\SubscriptionChangeRepository; use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; use OCP\ICache; use OCP\ICacheFactory; -class PodcastDataCache { +class PodcastDataReader { private ?ICache $cache = null; private IClient $httpClient; + private SubscriptionChangeRepository $subscriptionChangeRepository; public function __construct( ICacheFactory $cacheFactory, IClientService $httpClientService, + SubscriptionChangeRepository $subscriptionChangeRepository, ) { if ($cacheFactory->isLocalCacheAvailable()) { $this->cache = $cacheFactory->createLocal('GPodderSync-Podcasts'); } $this->httpClient = $httpClientService->newClient(); + $this->subscriptionChangeRepository = $subscriptionChangeRepository; } - public function getCachedOrFetchPodcastData(string $url): PodcastData { + public function getCachedOrFetchPodcastData(string $url, string $userId): ?PodcastData { if ($this->cache == null) { - return $this->fetchPodcastData($url); + return $this->fetchPodcastData($url, $userId); } $oldData = $this->tryGetCachedPodcastData($url); if ($oldData) { return $oldData; } - $newData = $this->fetchPodcastData($url); + $newData = $this->fetchPodcastData($url, $userId); $this->trySetCachedPodcastData($url, $newData); return $newData; } - public function fetchPodcastData(string $url): PodcastData { + private function userHasPodcast(string $url, string $userId): bool { + $subscriptionChanges = $this->subscriptionChangeRepository->findByUrl($url, $userId); + return $subscriptionChanges !== null; + } + + public function fetchPodcastData(string $url, string $userId): PodcastData { + if (!$this->userHasPodcast($url, $userId)) { + return null; + } $resp = $this->httpClient->get($url); $statusCode = $resp->getStatusCode(); if ($statusCode < 200 || $statusCode >= 300) { @@ -53,7 +65,7 @@ class PodcastDataCache { return PodcastData::fromArray($oldData); } - public function trySetCachedPodcastData(string $url, PodcastData $data) { - $this->cache->set($url, $data->toArray()); + public function trySetCachedPodcastData(string $url, PodcastData $data): bool { + return $this->cache->set($url, $data->toArray()); } } diff --git a/lib/Core/PodcastData/PodcastMetrics.php b/lib/Core/PodcastData/PodcastMetrics.php index 927cade..be23301 100644 --- a/lib/Core/PodcastData/PodcastMetrics.php +++ b/lib/Core/PodcastData/PodcastMetrics.php @@ -9,18 +9,15 @@ class PodcastMetrics implements JsonSerializable { private string $url; private int $listenedSeconds; private PodcastActionCounts $actionCounts; - private ?PodcastData $podcastData; public function __construct( string $url, int $listenedSeconds = 0, ?PodcastActionCounts $actionCounts = null, - ?PodcastData $podcastData = null, ) { $this->url = $url; $this->actionCounts = $actionCounts ?? new PodcastActionCounts; $this->listenedSeconds = $listenedSeconds; - $this->podcastData = $podcastData; } /** @@ -51,13 +48,6 @@ class PodcastMetrics implements JsonSerializable { $this->listenedSeconds += $seconds; } - /** - * @return PodcastData|null - */ - public function getPodcastData(): ?PodcastData { - return $this->podcastData; - } - /** * @return array */ @@ -67,7 +57,6 @@ class PodcastMetrics implements JsonSerializable { 'url' => $this->url, 'listenedSeconds' => $this->listenedSeconds, 'actionCounts' => $this->actionCounts->toArray(), - 'podcastData' => $this->podcastData->toArray(), ]; } diff --git a/lib/Core/PodcastData/PodcastMetricsReader.php b/lib/Core/PodcastData/PodcastMetricsReader.php index a532499..619e32b 100644 --- a/lib/Core/PodcastData/PodcastMetricsReader.php +++ b/lib/Core/PodcastData/PodcastMetricsReader.php @@ -13,21 +13,15 @@ use Psr\Log\LoggerInterface; class PodcastMetricsReader { - private LoggerInterface $logger; private SubscriptionChangeRepository $subscriptionChangeRepository; private EpisodeActionRepository $episodeActionRepository; - private PodcastDataCache $cache; public function __construct( - LoggerInterface $logger, SubscriptionChangeRepository $subscriptionChangeRepository, EpisodeActionRepository $episodeActionRepository, - PodcastDataCache $cache, ) { - $this->logger = $logger; $this->subscriptionChangeRepository = $subscriptionChangeRepository; $this->episodeActionRepository = $episodeActionRepository; - $this->cache = $cache; } /** @@ -69,24 +63,12 @@ class PodcastMetricsReader { return $subscriptions; } - private function tryGetParsedPodcastData(string $url): ?PodcastData { - try { - return $this->cache->getCachedOrFetchPodcastData($url); - } catch (\Exception $e) { - $this->logger->error("Failed to get podcast data.", [ - 'exception' => $e, - 'podcastUrl' => $url, - ]); - return null; - } - } - private function createMetricsForUrl(string $url): PodcastMetrics { return new PodcastMetrics( url: $url, listenedSeconds: 0, actionCounts: new PodcastActionCounts(), - podcastData: $this->tryGetParsedPodcastData($url), ); } + } diff --git a/lib/Db/SubscriptionChange/SubscriptionChangeMapper.php b/lib/Db/SubscriptionChange/SubscriptionChangeMapper.php index 7094352..700c778 100644 --- a/lib/Db/SubscriptionChange/SubscriptionChangeMapper.php +++ b/lib/Db/SubscriptionChange/SubscriptionChangeMapper.php @@ -25,7 +25,7 @@ class SubscriptionChangeMapper extends \OCP\AppFramework\Db\QBMapper { return $this->findEntities($qb); } - public function findByUrl(string $url, string $userId): SubscriptionChangeEntity { + public function findByUrl(string $url, string $userId): ?SubscriptionChangeEntity { $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -42,6 +42,7 @@ class SubscriptionChangeMapper extends \OCP\AppFramework\Db\QBMapper { } catch (DoesNotExistException $e) { } catch (MultipleObjectsReturnedException $e) { } + return null; } public function remove(SubscriptionChangeEntity $subscriptionChangeEntity) { diff --git a/lib/Db/SubscriptionChange/SubscriptionChangeRepository.php b/lib/Db/SubscriptionChange/SubscriptionChangeRepository.php index f36a65f..f8db410 100644 --- a/lib/Db/SubscriptionChange/SubscriptionChangeRepository.php +++ b/lib/Db/SubscriptionChange/SubscriptionChangeRepository.php @@ -18,7 +18,7 @@ class SubscriptionChangeRepository { return $this->subscriptionChangeMapper->findAll(); } - public function findByUrl(string $episode, string $userId): SubscriptionChangeEntity { + public function findByUrl(string $episode, string $userId): ?SubscriptionChangeEntity { return $this->subscriptionChangeMapper->findByUrl($episode, $userId); }