From 7b3d57b94a33ba95fd1f599ad53a50f6d312b413 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sat, 21 Jun 2025 23:26:55 -0500 Subject: [PATCH 1/8] fix: prepends episode/season number to filename if doesn't exist. should fix monitors repeatedly downloading episodes --- assets/controllers/download_button_controller.js | 2 ++ src/Download/Action/Input/DownloadMediaInput.php | 3 +++ .../Framework/Controller/ApiController.php | 8 ++++++++ src/Twig/Extensions/UtilExtension.php | 14 ++++++++++++++ templates/torrentio/partial/option-table.html.twig | 5 +++-- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/assets/controllers/download_button_controller.js b/assets/controllers/download_button_controller.js index 75cd145..9f35315 100644 --- a/assets/controllers/download_button_controller.js +++ b/assets/controllers/download_button_controller.js @@ -12,6 +12,7 @@ export default class extends Controller { filename: String, mediaType: String, imdbId: String, + episodeId: String } download() { @@ -27,6 +28,7 @@ export default class extends Controller { filename: this.filenameValue, mediaType: this.mediaTypeValue, imdbId: this.imdbIdValue, + episodeId: this.episodeIdValue }) }) .then(res => res.json()) diff --git a/src/Download/Action/Input/DownloadMediaInput.php b/src/Download/Action/Input/DownloadMediaInput.php index ebb6a4d..cce60a4 100644 --- a/src/Download/Action/Input/DownloadMediaInput.php +++ b/src/Download/Action/Input/DownloadMediaInput.php @@ -26,6 +26,9 @@ class DownloadMediaInput implements InputInterface #[SourceRequest('imdbId')] public string $imdbId, + #[SourceRequest('episodeId', nullify: true)] + public ?string $episodeId = null, + public ?int $userId = null, public ?int $downloadId = null, diff --git a/src/Download/Framework/Controller/ApiController.php b/src/Download/Framework/Controller/ApiController.php index 5b94c5b..ca76fee 100644 --- a/src/Download/Framework/Controller/ApiController.php +++ b/src/Download/Framework/Controller/ApiController.php @@ -11,6 +11,7 @@ use App\Download\Action\Input\PauseDownloadInput; use App\Download\Action\Input\ResumeDownloadInput; use App\Download\Framework\Repository\DownloadRepository; use App\Util\Broadcaster; +use Nihilarr\PTN; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Messenger\MessageBusInterface; @@ -28,6 +29,13 @@ class ApiController extends AbstractController public function download( DownloadMediaInput $input, ): Response { + $ptn = (object) new Ptn()->parse($input->filename); + if ($input->mediaType === "tvshows" && + !property_exists($ptn, 'episode') && !property_exists($ptn, 'season') + ) { + $input->filename = $input->episodeId . '_' . $input->filename; + } + $download = $this->downloadRepository->insert( $this->getUser(), $input->url, diff --git a/src/Twig/Extensions/UtilExtension.php b/src/Twig/Extensions/UtilExtension.php index 144830b..fe80928 100644 --- a/src/Twig/Extensions/UtilExtension.php +++ b/src/Twig/Extensions/UtilExtension.php @@ -4,7 +4,10 @@ namespace App\Twig\Extensions; use App\Monitor\Framework\Entity\Monitor; use App\Monitor\Service\MediaFiles; +use App\Torrentio\Action\Result\GetTvShowOptionsResult; +use App\Torrentio\Result\TorrentioResult; use ChrisUllyott\FileSize; +use Tmdb\Model\Tv\Episode; use Twig\Attribute\AsTwigFilter; use Twig\Attribute\AsTwigFunction; @@ -45,4 +48,15 @@ class UtilExtension $path ); } + + #[AsTwigFilter('episode_id_from_results')] + public function episodeId($result): ?string + { + if (!$result instanceof GetTvShowOptionsResult) { + return null; + } + + return "S". str_pad($result->season, 2, "0", STR_PAD_LEFT) . + "E". str_pad($result->episode, 2, "0", STR_PAD_LEFT); + } } diff --git a/templates/torrentio/partial/option-table.html.twig b/templates/torrentio/partial/option-table.html.twig index bfc4d33..485dae2 100644 --- a/templates/torrentio/partial/option-table.html.twig +++ b/templates/torrentio/partial/option-table.html.twig @@ -34,7 +34,7 @@ {% for result in results.results %} - + {{ result.size }} @@ -60,7 +60,8 @@ title: results.media.title, filename: result.filename, mediaType: results.media.mediaType, - imdbId: results.media.imdbId + imdbId: results.media.imdbId, + episodeId: results|episode_id_from_results }) }} {{ stimulus_action('download_button', 'download', 'click') }} > From 0b56ee937d2154cac711fdb934c1fe4a406d5152 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 10:08:23 -0500 Subject: [PATCH 2/8] fix: removes upcoming episodes component from monitors page --- templates/monitor/index.html.twig | 6 ------ 1 file changed, 6 deletions(-) diff --git a/templates/monitor/index.html.twig b/templates/monitor/index.html.twig index 370f247..417f244 100644 --- a/templates/monitor/index.html.twig +++ b/templates/monitor/index.html.twig @@ -15,11 +15,5 @@ -
- - - -
- {% endblock %} From 774d6f49996535cb93449524e93698fef32bb848 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 14:06:01 -0500 Subject: [PATCH 3/8] fix: caches tmdb data --- composer.json | 1 + composer.lock | 370 +++++++++++++++++++++++++++++++++++++++++++++- src/Tmdb/Tmdb.php | 13 +- 3 files changed, 381 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 389d5c9..a9d6ccf 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "nihilarr/parse-torrent-name": "^0.0.1", "nyholm/psr7": "*", "p3k/emoji-detector": "^1.2", + "php-http/cache-plugin": "^2.0", "php-tmdb/api": "^4.1", "predis/predis": "^2.4", "runtime/frankenphp-symfony": "^0.2.0", diff --git a/composer.lock b/composer.lock index 43097d6..bc70748 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3b0840f4e60d44d341c934f6ca153944", + "content-hash": "67e697578f7237f60726c0d93bfed001", "packages": [ { "name": "1tomany/rich-bundle", @@ -285,6 +285,72 @@ }, "time": "2021-10-17T22:52:23+00:00" }, + { + "name": "clue/stream-filter", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/clue/stream-filter.git", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.7.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2023-12-20T15:40:13+00:00" + }, { "name": "composer/semver", "version": "3.4.3", @@ -2865,6 +2931,130 @@ }, "time": "2024-02-19T18:29:05+00:00" }, + { + "name": "php-http/cache-plugin", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/cache-plugin.git", + "reference": "5c591e9e04602cec12307e3e1be3abefeb005e29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/cache-plugin/zipball/5c591e9e04602cec12307e3e1be3abefeb005e29", + "reference": "5c591e9e04602cec12307e3e1be3abefeb005e29", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/client-common": "^1.9 || ^2.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/http-factory-implementation": "^1.0", + "symfony/options-resolver": "^2.6 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "require-dev": { + "nyholm/psr7": "^1.6.1", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Common\\Plugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "PSR-6 Cache plugin for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "cache", + "http", + "httplug", + "plugin" + ], + "support": { + "issues": "https://github.com/php-http/cache-plugin/issues", + "source": "https://github.com/php-http/cache-plugin/tree/2.0.1" + }, + "time": "2024-10-02T11:25:38+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/0cfe9858ab9d3b213041b947c881d5b19ceeca46", + "reference": "0cfe9858ab9d3b213041b947c881d5b19ceeca46", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "phpspec/prophecy": "^1.10.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "support": { + "issues": "https://github.com/php-http/client-common/issues", + "source": "https://github.com/php-http/client-common/tree/2.7.2" + }, + "time": "2024-09-24T06:21:48+00:00" + }, { "name": "php-http/discovery", "version": "1.20.0", @@ -2944,6 +3134,184 @@ }, "time": "2024-10-02T11:20:13+00:00" }, + { + "name": "php-http/httplug", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/5cad731844891a4c282f3f3e1b582c46839d22f4", + "reference": "5cad731844891a4c282f3f3e1b582c46839d22f4", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.1" + }, + "time": "2024-09-23T11:39:58+00:00" + }, + { + "name": "php-http/message", + "version": "1.16.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/06dd5e8562f84e641bf929bfe699ee0f5ce8080a", + "reference": "06dd5e8562f84e641bf929bfe699ee0f5ce8080a", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.5", + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.6", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0 || ^2.0", + "laminas/laminas-diactoros": "^2.0 || ^3.0", + "php-http/message-factory": "^1.0.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "slim/slim": "^3.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "laminas/laminas-diactoros": "Used with Diactoros Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation" + }, + "type": "library", + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/1.16.2" + }, + "time": "2024-10-02T11:34:13+00:00" + }, + { + "name": "php-http/promise", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "reference": "fc85b1fba37c169a69a07ef0d5a8075770cc1f83", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.3.1" + }, + "time": "2024-03-15T13:55:21+00:00" + }, { "name": "php-tmdb/api", "version": "4.1.3", diff --git a/src/Tmdb/Tmdb.php b/src/Tmdb/Tmdb.php index 35ed087..587cd1a 100644 --- a/src/Tmdb/Tmdb.php +++ b/src/Tmdb/Tmdb.php @@ -6,6 +6,8 @@ use Aimeos\Map; use App\Enum\MediaType; use App\ValueObject\ResultFactory; use Carbon\Carbon; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Cache\CacheInterface; @@ -13,6 +15,7 @@ use Symfony\Contracts\Cache\ItemInterface; use Tmdb\Api\Find; use Tmdb\Client; use Tmdb\Event\BeforeRequestEvent; +use Tmdb\Event\Listener\Psr6CachedRequestListener; use Tmdb\Event\Listener\Request\AcceptJsonRequestListener; use Tmdb\Event\Listener\Request\ApiTokenRequestListener; use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener; @@ -41,7 +44,7 @@ class Tmdb const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500"; public function __construct( - private readonly CacheInterface $cache, + private readonly CacheItemPoolInterface $cache, private readonly EventDispatcherInterface $eventDispatcher, #[Autowire(env: 'TMDB_API')] string $apiKey, ) { @@ -72,7 +75,13 @@ class Tmdb /** * Required event listeners and events to be registered with the PSR-14 Event Dispatcher. */ - $requestListener = new RequestListener($this->client->getHttpClient(), $this->eventDispatcher); + $requestListener = new Psr6CachedRequestListener( + $this->client->getHttpClient(), + $this->eventDispatcher, + $cache, + $this->client->getHttpClient()->getPsr17StreamFactory(), + [] + ); $this->eventDispatcher->addListener(RequestEvent::class, $requestListener); $apiTokenListener = new ApiTokenRequestListener($this->client->getToken()); From ba092ab3c2e7397b2c18201c0d264fd96d5084ad Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 15:12:37 -0500 Subject: [PATCH 4/8] chore: remove line --- src/Controller/SearchController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Controller/SearchController.php b/src/Controller/SearchController.php index bcfeaf6..ce93d37 100644 --- a/src/Controller/SearchController.php +++ b/src/Controller/SearchController.php @@ -40,8 +40,6 @@ final class SearchController extends AbstractController ): Response { $result = $this->getMediaInfoHandler->handle($input->toCommand()); -// $this->warmDownloadOptionCache($result->media); - return $this->render('search/result.html.twig', [ 'results' => $result, 'filter' => [ From cc39e46bfd00bb7516cc57d2ca9ad714f6ec16df Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 15:50:09 -0500 Subject: [PATCH 5/8] fix: broken delete monitor --- src/Monitor/Framework/Controller/ApiController.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Monitor/Framework/Controller/ApiController.php b/src/Monitor/Framework/Controller/ApiController.php index 599ae2f..a3e2226 100644 --- a/src/Monitor/Framework/Controller/ApiController.php +++ b/src/Monitor/Framework/Controller/ApiController.php @@ -2,17 +2,13 @@ namespace App\Monitor\Framework\Controller; -use App\Download\Action\Input\DeleteDownloadInput; use App\Monitor\Action\Handler\AddMonitorHandler; use App\Monitor\Action\Handler\DeleteMonitorHandler; use App\Monitor\Action\Input\AddMonitorInput; use App\Monitor\Action\Input\DeleteMonitorInput; use App\Util\Broadcaster; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Bundle\SecurityBundle\Security; -use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Mercure\HubInterface; -use Symfony\Component\Mercure\Update; use Symfony\Component\Routing\Attribute\Route; class ApiController extends AbstractController @@ -46,19 +42,9 @@ class ApiController extends AbstractController public function deleteMonitor( DeleteMonitorInput $input, DeleteMonitorHandler $handler, - HubInterface $hub, ) { $response = $handler->handle($input->toCommand()); - $hub->publish(new Update( - 'alerts', - $this->renderer->render('broadcast/Alert.stream.html.twig', [ - 'alert_id' => uniqid(), - 'title' => 'Success', - 'message' => "New monitor added for {$response->monitor->getTitle()}", - ]) - )); - return $this->json([ 'status' => 200, 'message' => $response From d95ab854154c58a37745bdb5142ddd88c060faa0 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 16:21:04 -0500 Subject: [PATCH 6/8] fix: udpates example compose --- docs/examples/.env | 2 +- docs/examples/compose.yml | 35 +++++++++++++---------------------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/docs/examples/.env b/docs/examples/.env index 31de7de..c474e18 100644 --- a/docs/examples/.env +++ b/docs/examples/.env @@ -27,7 +27,7 @@ DATABASE_URL="mysql://root:password@database:3306/app?serverVersion=10.6.19.2-Ma # Popular Movies and TV Shows section. #TMDB_API= -REAL_DEBRID_KEY="QYYBR7OSQ4VEFKWASDEZ2B4VO67KHUJY6IWOT7HHA7ATXO7QCYDQ" +REAL_DEBRID_KEY="" TMDB_API=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI0ZTJjYjJhOGUzOGJhNjdiNjVhOGU1NGM0ZWI1MzhmOCIsIm5iZiI6MTczNzkyNjA0NC41NjQsInN1YiI6IjY3OTZhNTljYzdiMDFiNzJjNzIzZWM5YiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.e8DbNe9qrSBC1y-ANRv-VWBAtls-ZS2r7aNCiI68mpw diff --git a/docs/examples/compose.yml b/docs/examples/compose.yml index 4bd8d11..167eba1 100644 --- a/docs/examples/compose.yml +++ b/docs/examples/compose.yml @@ -11,6 +11,13 @@ services: - '8006:80' env_file: - .env + volumes: + - /mnt/media/downloads/movies:/var/download/movies + - /mnt/media/downloads/tvshows:/var/download/tvshows + environment: + TZ: America/Chicago + MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' + MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' depends_on: database: condition: service_healthy @@ -27,6 +34,8 @@ services: volumes: - /mnt/media/downloads/movies:/var/download/movies - /mnt/media/downloads/tvshows:/var/download/tvshows + environment: + TZ: America/Chicago command: -vvv env_file: - .env @@ -43,35 +52,17 @@ services: scheduler: image: code.caldwell.digital/home/torsearch-scheduler:latest volumes: - - ./downloads:/var/download + - /mnt/media/downloads/movies:/var/download/movies + - /mnt/media/downloads/tvshows:/var/download/tvshows env_file: - .env + environment: + TZ: America/Chicago restart: always depends_on: app: condition: service_healthy - # This container facilitates viewing the progress of downloads - # in realtime. It also handles sending alerts and notifications. - # The MERCURE_PUBLISHER_JWT key & MERCURE_SUBSCRIBER_JWT_KEY should - # match the MERCURE_JWT_SECRET environment variable. - mercure: - image: dunglas/mercure - restart: unless-stopped - ports: - - "3001:80" - environment: - SERVER_NAME: ':80' - MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_EXTRA_DIRECTIVES: | - cors_origins * - anonymous - command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile - volumes: - - mercure_data:/data - - mercure_config:/config - database: image: mariadb:10.11.2 volumes: From 5938d33c896399dd0ffe62d5a3bdb32a0a4ac781 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 16:40:43 -0500 Subject: [PATCH 7/8] fix: alert topic id not being set after getting started controller --- .../Framework/Controller/Web/RegistrationController.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/User/Framework/Controller/Web/RegistrationController.php b/src/User/Framework/Controller/Web/RegistrationController.php index 6d1531e..fae7d08 100644 --- a/src/User/Framework/Controller/Web/RegistrationController.php +++ b/src/User/Framework/Controller/Web/RegistrationController.php @@ -17,13 +17,16 @@ use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\Attribute\Route; class RegistrationController extends AbstractController { - public function __construct(private readonly RegisterUserHandler $registerUserHandler) + public function __construct(private readonly RegisterUserHandler $registerUserHandler, + private readonly RequestStack $requestStack + ) { } @@ -71,6 +74,7 @@ class RegistrationController extends AbstractController )); $security->login($user->user); + $this->requestStack->getCurrentRequest()->getSession()->set('mercure_alert_topic', 'alerts_' . uniqid()); return $this->redirectToRoute('app_index'); } From 2dc53c52700695b9f9b23c0c0b43f3dea6de9504 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 22 Jun 2025 22:08:08 -0500 Subject: [PATCH 8/8] feat: tags torrentio cache --- src/Torrentio/Client/Torrentio.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Torrentio/Client/Torrentio.php b/src/Torrentio/Client/Torrentio.php index 109012f..d9fef60 100644 --- a/src/Torrentio/Client/Torrentio.php +++ b/src/Torrentio/Client/Torrentio.php @@ -10,8 +10,8 @@ use App\Torrentio\Exception\TorrentioRateLimitException; use GuzzleHttp\Client; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\Attribute\Autowire; -use Symfony\Contracts\Cache\CacheInterface; use Symfony\Contracts\Cache\ItemInterface; +use Symfony\Contracts\Cache\TagAwareCacheInterface; class Torrentio { @@ -23,7 +23,7 @@ class Torrentio public function __construct( #[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey, - private CacheInterface $cache, + private TagAwareCacheInterface $cache, private LoggerInterface $logger, ) { $this->searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl); @@ -36,8 +36,9 @@ class Torrentio { $cacheKey = "torrentio.{$imdbCode}"; - $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbCode) { + $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbCode, $type) { $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0)); + $item->tag(['torrentio', $type, $imdbCode]); try { $response = $this->client->get("$this->searchUrl/$imdbCode.json"); return json_decode( @@ -63,6 +64,7 @@ class Torrentio $cacheKey = "torrentio.$imdbId.$season.$episode"; $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) { $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0)); + $item->tag(['torrentio', 'tvshows', 'torrentio.tvshows', $imdbId, "torrentio.$imdbId", "$imdbId.$season", "torrentio.$imdbId.$season", "$imdbId.$season.$episode", "torrentio.$imdbId.$season.$episode"]); try { $response = $this->client->get("$this->searchUrl/$imdbId:$season:$episode.json"); return json_decode(