From 795a9253d2d282dc05edb032b3c149ae7d3f93d6 Mon Sep 17 00:00:00 2001 From: Jonathan Flueren <11487762+JonOfUs@users.noreply.github.com> Date: Tue, 5 Oct 2021 14:57:49 +0200 Subject: [PATCH] Adjust EpisodeAction upload to gpodder api, remove String upload Remove 3rd dimension of POST data by directly accessing request data - a simple EpisodeActions array has to be posted now. This way the api is closer to gpodder. Additionally, removed EpisodeAction upload as String, so it's now incompatible with older versions --- lib/Controller/EpisodeActionController.php | 36 +++++++++++- .../EpisodeAction/EpisodeActionReader.php | 49 ---------------- lib/Core/EpisodeAction/EpisodeActionSaver.php | 19 +++---- .../EpisodeAction/EpisodeActionReaderTest.php | 57 ------------------- 4 files changed, 40 insertions(+), 121 deletions(-) diff --git a/lib/Controller/EpisodeActionController.php b/lib/Controller/EpisodeActionController.php index a184635..8e139f1 100644 --- a/lib/Controller/EpisodeActionController.php +++ b/lib/Controller/EpisodeActionController.php @@ -22,6 +22,8 @@ class EpisodeActionController extends Controller { private $userId; private EpisodeActionSaver $episodeActionSaver; + protected $request; + public function __construct( string $AppName, IRequest $request, @@ -33,6 +35,7 @@ class EpisodeActionController extends Controller { $this->episodeActionRepository = $episodeActionRepository; $this->userId = $UserId; $this->episodeActionSaver = $episodeActionSaver; + $this->request = $request; } /** @@ -40,10 +43,15 @@ class EpisodeActionController extends Controller { * @NoAdminRequired * @NoCSRFRequired * - * @return Response + * @return JSONResponse */ - public function create($data) { - return $this->episodeActionSaver->saveEpisodeActions($data, $this->userId); + public function create(): JSONResponse { + + $episodeActionsArray = $this->filterEpisodesFromRequestParams($this->request->getParams()); + + $this->episodeActionSaver->saveEpisodeActions($episodeActionsArray, $this->userId); + + return new JSONResponse(["timestamp" => time()]); } /** @@ -67,4 +75,26 @@ class EpisodeActionController extends Controller { "timestamp" => time() ]); } + + /** + * @param array $requestParams + * + * @return array $episodeActionsArray + */ + public function filterEpisodesFromRequestParams(array $data): array { + return array_filter($data, "is_numeric", ARRAY_FILTER_USE_KEY); + } + + /** + * @param int|null $since + * + * @return DateTime + */ + private function createDateTimeFromTimestamp(?int $since): DateTime { + return ($since !== null) + ? (new \DateTime)->setTimestamp($since) + : (new \DateTime('-1 week')); + } + + } diff --git a/lib/Core/EpisodeAction/EpisodeActionReader.php b/lib/Core/EpisodeAction/EpisodeActionReader.php index 5bbcc30..2fb22db 100644 --- a/lib/Core/EpisodeAction/EpisodeActionReader.php +++ b/lib/Core/EpisodeAction/EpisodeActionReader.php @@ -5,55 +5,6 @@ namespace OCA\GPodderSync\Core\EpisodeAction; class EpisodeActionReader { - - const EPISODEACTION_IDENTIFIER = 'EpisodeAction{'; - - /** - * @param string $episodeActionsString - * @return EpisodeAction[] - */ - public function fromString(string $episodeActionsString): array - { - - - $patterns = [ - '/EpisodeAction{(podcast=\')(?.*?)(\', episode=\')(?.*?)(\', guid=\')(?.*?)(\', action=)(?.*?)(, timestamp=)(?.*?)(, started=)(?.*?)(, position=)(?.*?)(, total=)(?.*?)}]*/', - '/EpisodeAction{(podcast=\')(?.*?)(\', episode=\')(?.*?)(\', action=)(?.*?)(, timestamp=)(?.*?)(, started=)(?.*?)(, position=)(?.*?)(, total=)(?.*?)}]*/', - ]; - - $episodeActions = []; - - $episodeActionStrings = explode(self::EPISODEACTION_IDENTIFIER, $episodeActionsString); - array_shift($episodeActionStrings); - - foreach ($episodeActionStrings as $episodeActionString) { - foreach ($patterns as $pattern) { - preg_match( - $pattern, - self::EPISODEACTION_IDENTIFIER . $episodeActionString, - $matches - ); - - if ($matches["action"] !== null) { - $episodeActions[] = new EpisodeAction( - $matches["podcast"], - $matches["episode"], - $matches["action"], - $matches["timestamp"], - (int)$matches["started"], - (int)$matches["position"], - (int)$matches["total"], - $matches["guid"] ?? null, - null, - ); - break; - } - } - - } - return $episodeActions; - } - /** * @param $episodeActionsArray[] * @return EpisodeAction[] diff --git a/lib/Core/EpisodeAction/EpisodeActionSaver.php b/lib/Core/EpisodeAction/EpisodeActionSaver.php index 733bc45..c8b4a80 100644 --- a/lib/Core/EpisodeAction/EpisodeActionSaver.php +++ b/lib/Core/EpisodeAction/EpisodeActionSaver.php @@ -29,32 +29,27 @@ class EpisodeActionSaver } /** - * @param string|array $data + * @param array $episodeActionsArray * - * @return EpisodeActionEntity[] + * @return void */ - public function saveEpisodeActions($data, string $userId): array + public function saveEpisodeActions($episodeActionsArray, string $userId): void { - $episodeActionEntities = []; - - $episodeActions = is_array($data) - ? $this->episodeActionReader->fromArray($data) - : $this->episodeActionReader->fromString($data); + $episodeActions = $this->episodeActionReader->fromArray($episodeActionsArray); foreach ($episodeActions as $episodeAction) { $episodeActionEntity = $this->hydrateEpisodeActionEntity($episodeAction, $userId); try { - $episodeActionEntities[] = $this->episodeActionWriter->save($episodeActionEntity); + $this->episodeActionWriter->save($episodeActionEntity); } catch (UniqueConstraintViolationException $uniqueConstraintViolationException) { - $episodeActionEntities[] = $this->updateEpisodeAction($episodeActionEntity, $userId); + $this->updateEpisodeAction($episodeActionEntity, $userId); } catch (Exception $exception) { if ($exception->getReason() === Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { - $episodeActionEntities[] = $this->updateEpisodeAction($episodeActionEntity, $userId); + $this->updateEpisodeAction($episodeActionEntity, $userId); } } } - return $episodeActionEntities; } private function convertTimestampToUnixEpoch(string $timestamp): string diff --git a/tests/Unit/Core/EpisodeAction/EpisodeActionReaderTest.php b/tests/Unit/Core/EpisodeAction/EpisodeActionReaderTest.php index d51a848..84f839c 100644 --- a/tests/Unit/Core/EpisodeAction/EpisodeActionReaderTest.php +++ b/tests/Unit/Core/EpisodeAction/EpisodeActionReaderTest.php @@ -7,63 +7,6 @@ use OCA\GPodderSync\Core\EpisodeAction\EpisodeActionReader; use Test\TestCase; class EpisodeActionReaderTest extends TestCase { - public function testCreateFromString(): void { - $reader = new EpisodeActionReader(); - $episodeActions = $reader->fromString('[EpisodeAction{podcast=\'https://feeds.simplecast.com/wEl4UUJZ\', episode=\'https://chrt.fm/track/47G541/injector.simplecastaudio.com/f16c3da7-cf46-4a42-99b7-8467255c6086/episodes/e8e24c01-6157-40e8-9b5a-45d539aeb7e6/audio/128/default.mp3?aid=rss_feed&awCollectionId=f16c3da7-cf46-4a42-99b7-8467255c6086&awEpisodeId=e8e24c01-6157-40e8-9b5a-45d539aeb7e6&feed=wEl4UUJZ\', action=PLAY, timestamp=Tue May 18 23:45:11 GMT+02:00 2021, started=31, position=36, total=2474}]'); - $episodeAction = $episodeActions[0]; - $this->assertSame("https://feeds.simplecast.com/wEl4UUJZ", $episodeAction->getPodcast()); - $this->assertSame("https://chrt.fm/track/47G541/injector.simplecastaudio.com/f16c3da7-cf46-4a42-99b7-8467255c6086/episodes/e8e24c01-6157-40e8-9b5a-45d539aeb7e6/audio/128/default.mp3?aid=rss_feed&awCollectionId=f16c3da7-cf46-4a42-99b7-8467255c6086&awEpisodeId=e8e24c01-6157-40e8-9b5a-45d539aeb7e6&feed=wEl4UUJZ", $episodeAction->getEpisode()); - $this->assertSame("PLAY", $episodeAction->getAction()); - $this->assertSame("Tue May 18 23:45:11 GMT+02:00 2021", $episodeAction->getTimestamp()); - $this->assertNull($episodeAction->getGuid()); - $this->assertSame(31, $episodeAction->getStarted()); - $this->assertSame(36, $episodeAction->getPosition()); - $this->assertSame(2474, $episodeAction->getTotal()); - } - - public function testCreateFromStringWithGuid(): void { - $reader = new EpisodeActionReader(); - $episodeActions = $reader->fromString("[EpisodeAction{podcast='https://rss.art19.com/dr-death-s3-miracle-man', episode='https://dts.podtrac.com/redirect.mp3/chrt.fm/track/9EE2G/pdst.fm/e/rss.art19.com/episodes/db0e3500', guid='gid://art19-episode-locator/V0/KtdfKfLndyWetCZ6t2WhUEFOFArDXRExVIb4Z1fh-TU', action=PLAY, timestamp=Mon Aug 23 01:58:56 GMT+02:00 2021, started=47, position=54, total=2252}]"); - $episodeAction = $episodeActions[0]; - $this->assertSame("https://rss.art19.com/dr-death-s3-miracle-man", $episodeAction->getPodcast()); - $this->assertSame("https://dts.podtrac.com/redirect.mp3/chrt.fm/track/9EE2G/pdst.fm/e/rss.art19.com/episodes/db0e3500", $episodeAction->getEpisode()); - $this->assertSame("PLAY", $episodeAction->getAction()); - $this->assertSame("Mon Aug 23 01:58:56 GMT+02:00 2021", $episodeAction->getTimestamp()); - $this->assertSame("gid://art19-episode-locator/V0/KtdfKfLndyWetCZ6t2WhUEFOFArDXRExVIb4Z1fh-TU", $episodeAction->getGuid()); - $this->assertSame(47, $episodeAction->getStarted()); - $this->assertSame(54, $episodeAction->getPosition()); - $this->assertSame(2252, $episodeAction->getTotal()); - } - - public function testCreateFromMultipleEpisodesString(): void { - $reader = new EpisodeActionReader(); - $episodeActions = $reader->fromString('[EpisodeAction{podcast=\'https://example.com/feed.xml\', episode=\'https://example.com/episode1.mp3\', action=PLAY, timestamp=Tue May 18 23:45:11 GMT+02:00 2021, started=31, position=36, total=2474},EpisodeAction{podcast=\'https://example.com/feed.xml\', episode=\'https://example.com/episode2.mp3\', action=DOWNLOAD, timestamp=Tue May 18 23:46:42 GMT+02:00 2021, started=31, position=36, total=2474},EpisodeAction{podcast=\'https://example.org/feed.xml\', episode=\'https://chrt.fm/track/47G541/injector.simplecastaudio.com/f16c3da7-cf46-4a42-99b7-8467255c6086/episodes/e8e24c01-6157-40e8-9b5a-45d539aeb7e6/audio/128/default.mp3?aid=rss_feed&awCollectionId=f16c3da7-cf46-4a42-99b7-8467255c6086&awEpisodeId=e8e24c01-6157-40e8-9b5a-45d539aeb7e6&feed=wEl4UUJZ\', action=PLAY, timestamp=Tue May 18 23:45:14 GMT+02:00 2021, started=0, position=211, total=3121}]'); - - $this->assertSame("https://example.com/feed.xml", $episodeActions[0]->getPodcast()); - $this->assertSame("https://example.com/episode1.mp3", $episodeActions[0]->getEpisode()); - $this->assertSame("PLAY", $episodeActions[0]->getAction()); - $this->assertSame("Tue May 18 23:45:11 GMT+02:00 2021", $episodeActions[0]->getTimestamp()); - $this->assertSame(31, $episodeActions[0]->getStarted()); - $this->assertSame(36, $episodeActions[0]->getPosition()); - $this->assertSame(2474, $episodeActions[0]->getTotal()); - - $this->assertSame("https://example.com/feed.xml", $episodeActions[1]->getPodcast()); - $this->assertSame("https://example.com/episode2.mp3", $episodeActions[1]->getEpisode()); - $this->assertSame("DOWNLOAD", $episodeActions[1]->getAction()); - $this->assertSame("Tue May 18 23:46:42 GMT+02:00 2021", $episodeActions[1]->getTimestamp()); - $this->assertSame(31, $episodeActions[1]->getStarted()); - $this->assertSame(36, $episodeActions[1]->getPosition()); - $this->assertSame(2474, $episodeActions[1]->getTotal()); - - $this->assertSame("https://example.org/feed.xml", $episodeActions[2]->getPodcast()); - $this->assertSame("https://chrt.fm/track/47G541/injector.simplecastaudio.com/f16c3da7-cf46-4a42-99b7-8467255c6086/episodes/e8e24c01-6157-40e8-9b5a-45d539aeb7e6/audio/128/default.mp3?aid=rss_feed&awCollectionId=f16c3da7-cf46-4a42-99b7-8467255c6086&awEpisodeId=e8e24c01-6157-40e8-9b5a-45d539aeb7e6&feed=wEl4UUJZ", $episodeActions[2]->getEpisode()); - $this->assertSame("PLAY", $episodeActions[2]->getAction()); - $this->assertSame("Tue May 18 23:45:14 GMT+02:00 2021", $episodeActions[2]->getTimestamp()); - $this->assertSame(0, $episodeActions[2]->getStarted()); - $this->assertSame(211, $episodeActions[2]->getPosition()); - $this->assertSame(3121, $episodeActions[2]->getTotal()); - } - public function testCreateFromArray(): void { $reader = new EpisodeActionReader(); $episodeActions = $reader->fromArray([["podcast" => "https://example.org/feed.xml", "episode" => "https://example.org/episode1.mp3", "action" => "PLAY", "timestamp" => "Sun Oct 03 14:03:17 GMT+02:00 2021", "started" => 0, "position" => 50, "total"=> 3422]]);