From f9ddd706688acb03ac9d154799906a0448f38ba3 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 31 Aug 2025 09:06:29 -0500 Subject: [PATCH] wip: apparently torrentio doesn't need configuration --- assets/styles/app.css | 1 + .../Framework/Command/SeedDatabaseCommand.php | 10 +- src/Torrentio/Client/Torrentio.php | 43 ++++---- src/Torrentio/Client/TorrentioUrl.php | 55 ++++++++--- .../Form/TorrentioPreferencesForm.php | 99 +++++++++++++++++++ .../SaveUserTorrentioPreferencesCommand.php | 14 +++ .../SaveUserTorrentioPreferencesHandler.php | 48 +++++++++ src/User/Database/ProviderList.php | 27 +++-- .../Controller/Web/PreferencesController.php | 30 ++++++ src/User/Framework/Entity/User.php | 8 ++ src/User/Framework/Entity/UserPreference.php | 2 +- src/Values/TorrentioDebridProviderChoices.php | 27 +++++ src/Values/TorrentioExcludeQualityChoices.php | 34 +++++++ src/Values/TorrentioLanguageChoices.php | 60 +++++++++++ src/Values/TorrentioProviderChoices.php | 41 ++++++++ src/Values/TorrentioSortChoices.php | 23 +++++ templates/components/SubmitButton.html.twig | 2 +- templates/user/preferences.html.twig | 26 +++++ 18 files changed, 505 insertions(+), 45 deletions(-) create mode 100644 src/Torrentio/Framework/Form/TorrentioPreferencesForm.php create mode 100644 src/User/Action/Command/SaveUserTorrentioPreferencesCommand.php create mode 100644 src/User/Action/Handler/SaveUserTorrentioPreferencesHandler.php create mode 100644 src/Values/TorrentioDebridProviderChoices.php create mode 100644 src/Values/TorrentioExcludeQualityChoices.php create mode 100644 src/Values/TorrentioLanguageChoices.php create mode 100644 src/Values/TorrentioProviderChoices.php create mode 100644 src/Values/TorrentioSortChoices.php diff --git a/assets/styles/app.css b/assets/styles/app.css index 8bcc165..3928f21 100644 --- a/assets/styles/app.css +++ b/assets/styles/app.css @@ -168,6 +168,7 @@ dialog[data-dialog-target="dialog"][closing] { background: transparent; } +form[name="torrentio_preferences_form"], #filter { .ts-wrapper { box-shadow: none !important; diff --git a/src/Base/Framework/Command/SeedDatabaseCommand.php b/src/Base/Framework/Command/SeedDatabaseCommand.php index 0371342..76de836 100644 --- a/src/Base/Framework/Command/SeedDatabaseCommand.php +++ b/src/Base/Framework/Command/SeedDatabaseCommand.php @@ -4,7 +4,6 @@ namespace App\Base\Framework\Command; use App\User\Framework\Entity\Preference; use App\User\Framework\Entity\UserPreference; -use App\User\Framework\Repository\PreferenceOptionRepository; use App\User\Framework\Repository\PreferencesRepository; use App\User\Framework\Repository\UserRepository; use Symfony\Component\Console\Attribute\AsCommand; @@ -139,9 +138,16 @@ class SeedDatabaseCommand extends Command 'id' => 'enable_ical_up_ep', 'name' => 'Enable a publicly available iCal calendar?', 'description' => 'Enable a publicly accessible iCal URL for your upcoming episodes.', - 'enabled' => false, + 'enabled' => true, 'type' => 'calendar' ], + [ + 'id' => 'torrentio_url', + 'name' => 'A custom Torrentio URL', + 'description' => 'If you want to use a custom Torrentio URL, enter it here. Otherwise, leave it blank to use the one provided as an environment variable.', + 'enabled' => true, + 'type' => 'torrentio' + ], ]; } } diff --git a/src/Torrentio/Client/Torrentio.php b/src/Torrentio/Client/Torrentio.php index 3ab0d3d..f4eaeec 100644 --- a/src/Torrentio/Client/Torrentio.php +++ b/src/Torrentio/Client/Torrentio.php @@ -9,13 +9,14 @@ use Carbon\Carbon; use App\Torrentio\Exception\TorrentioRateLimitException; use GuzzleHttp\Client; use Psr\Log\LoggerInterface; +use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Contracts\Cache\ItemInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; class Torrentio { - private string $baseUrl = 'https://torrentio.strem.fun/providers%253Dyts%252Ceztv%252Crarbg%252C1337x%252Cthepiratebay%252Ckickasstorrents%252Ctorrentgalaxy%252Cmagnetdl%252Chorriblesubs%252Cnyaasi%7Csort%253Dqualitysize%7Cqualityfilter%253D480p%252Cscr%252Ccam%7Crealdebrid={realDebridKey}/stream/movie'; + private string $baseUrl = 'https://torrentio.strem.fun/realdebrid={realDebridKey}/stream/movie'; private string $searchUrl; @@ -25,8 +26,15 @@ class Torrentio #[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey, private TagAwareCacheInterface $cache, private LoggerInterface $logger, + private Security $security, ) { - $this->searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl); +// $this->searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl); + $user = $this->security->getUser(); + $this->searchUrl = $user->getUserPreference('torrentio_url')->getPreferenceValue() . '/stream/movie'; + +// dd($this->searchUrl); + + $this->client = new Client([ 'base_uri' => $this->searchUrl, ]); @@ -36,25 +44,26 @@ class Torrentio { $cacheKey = "torrentio.{$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]); +// $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( + $results = json_decode( $response->getBody()->getContents(), true ); +// dd($results); } catch (\Throwable $exception) { if ($exception->getCode() === 429) { $this->logger->warning("> [TorrentioClient] Rate limit exceeded"); - return null; + throw $exception; } } $this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents()); - return []; - }); +// return []; +// }); if (true === $parseResults) { return $this->parse($results); @@ -65,26 +74,26 @@ class Torrentio public function fetchEpisodeResults(string $imdbId, int $season, int $episode, bool $parseResults = true): array { - $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"]); +// $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( + $results = json_decode( $response->getBody()->getContents(), true ); } catch (\Throwable $exception) { if ($exception->getCode() === 429) { $this->logger->warning("> [TorrentioClient] Rate limit exceeded"); - return null; + throw $exception; } } $this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents()); - return []; - }); +// return []; +// }); if (null === $results) { throw new TorrentioRateLimitException(); diff --git a/src/Torrentio/Client/TorrentioUrl.php b/src/Torrentio/Client/TorrentioUrl.php index 790d995..d022bca 100644 --- a/src/Torrentio/Client/TorrentioUrl.php +++ b/src/Torrentio/Client/TorrentioUrl.php @@ -2,25 +2,48 @@ namespace App\Torrentio\Client; -class TorrentioUrlFactory -{ - // stremio://torrentio.strem.fun/providers=yts,eztv,rarbg,1337x,thepiratebay,kickasstorrents,torrentgalaxy,magnetdl,horriblesubs,nyaasi,tokyotosho,anidex|language=croatian,greek,norwegian|qualityfilter=other,scr|limit=100|sizefilter=1000|realdebrid=TEST/manifest.json - public static function create( - ?array $providers = null, - ?array $language = null, - ?array $qualityfilter = null, - ?string $debridProvider = null, - ?string $limit = null, - ?string $sizefilter = null, - ?string $debridToken = null, - ): string { - $result = ""; +use App\Values\TorrentioDebridProviderChoices; - if (null !== $providers) { - $result .= "providers=". strtolower(implode(",", $providers)); +class TorrentioUrl +{ + const BASE_URL = "https://torrentio.strem.fun/"; + + public ?array $providers = null; + public ?array $language = null; + public ?array $qualityfilter = null; + public ?string $sorting = null; + public ?string $debridProvider = null; + public ?string $limit = null; + public ?string $sizefilter = null; + public ?string $debridToken = null; + + public function __toString(): string + { + $result = ""; + if (null !== $this->debridProvider && null !== $this->debridToken) { + $result .= "$this->debridProvider=$this->debridToken"; } - + return static::BASE_URL . $result; + } + + public static function fromString(string $url): self + { + $arrayData = ['providers', 'language', 'qualityfilter']; + $data = explode('|', str_replace('/', '', urldecode(urldecode(parse_url($url)['path'])))); + + $result = new self(); + foreach ($data as $item) {$item = explode('=', $item); + if (count($item) !== 2) continue; + if (in_array($item[0], array_keys(TorrentioDebridProviderChoices::$providers))) { + $result->debridProvider = $item[0]; + $result->debridToken = $item[1]; + } elseif (in_array($item[0], $arrayData)) { + $result->{$item[0]} = explode(',', $item[1]); + } else { + $result->{$item[0]} = $item[1]; + } + } return $result; } diff --git a/src/Torrentio/Framework/Form/TorrentioPreferencesForm.php b/src/Torrentio/Framework/Form/TorrentioPreferencesForm.php new file mode 100644 index 0000000..357d62a --- /dev/null +++ b/src/Torrentio/Framework/Form/TorrentioPreferencesForm.php @@ -0,0 +1,99 @@ +addChoiceField($builder, 'providers', TorrentioProviderChoices::asSelectOptions()); + $this->addChoiceField($builder, 'sorting', TorrentioSortChoices::asSelectOptions(), 1); + $this->addChoiceField($builder, 'language', TorrentioLanguageChoices::asSelectOptions()); + $this->addChoiceField($builder, 'qualityfilter', TorrentioExcludeQualityChoices::asSelectOptions()); + $this->addTextField($builder, 'limit'); + $this->addTextField($builder, 'sizefilter'); + $this->addChoiceField($builder, 'debridProvider', TorrentioDebridProviderChoices::asSelectOptions(), 1); + $this->addTextField($builder, 'debridToken'); + } + + private function addChoiceField(FormBuilderInterface $builder, string $fieldName, array $choices, ?int $maxItems = null): void + { + $question = [ + 'attr' => [ + 'class' => 'min-w-24 text-input mb-4', + ], + 'row_attr' => [ + 'class' => 'filter-label text-white' + ], + 'label_attr' => ['class' => 'block font-semibold mb-2'], + 'choices' => $choices, + 'required' => false, + ]; + + if (null === $maxItems) { + $question['multiple'] = true; + $question['attr'] += [ + 'data-result-filter-target' => $fieldName, + 'data-controller' => 'symfony--ux-autocomplete--autocomplete', + 'data-symfony--ux-autocomplete--autocomplete-tom-select-options-value' => json_encode([ + 'highlight' => false, + 'maxItems' => $maxItems, + ]), + ]; + } else { + $question += [ + 'multiple' => false, + 'expanded' => false, + ]; + } + + $builder->add($fieldName, ChoiceType::class, $question); + } + + public function addTextField(FormBuilderInterface $builder, string $fieldName, ?array $options = null): void + { + $optinos = $options ?? [ + 'required' => false, + 'attr' => [ + 'method' => 'post', + 'action' => $this->urlGenerator->generate('app.torrentio-preferences.save'), + 'class' => 'min-w-24 text-input mb-4 block', + ] + ]; + + $builder->add( + $fieldName, + TextType::class, + $optinos, + ); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'id' => 'torrentio-preferences-form', +// 'action' => $this->urlGenerator->generate('app_user_media_preferences_submit'), + 'attr' => [ + 'class' => 'filter-items w-full p-4 text-md dark:text-gray-50 rounded-lg', + ] + ]); + } +} diff --git a/src/User/Action/Command/SaveUserTorrentioPreferencesCommand.php b/src/User/Action/Command/SaveUserTorrentioPreferencesCommand.php new file mode 100644 index 0000000..1e85c3c --- /dev/null +++ b/src/User/Action/Command/SaveUserTorrentioPreferencesCommand.php @@ -0,0 +1,14 @@ + */ +class SaveUserTorrentioPreferencesCommand implements CommandInterface +{ + public function __construct( + public TorrentioUrl $torrentioUrl, + ) {} +} \ No newline at end of file diff --git a/src/User/Action/Handler/SaveUserTorrentioPreferencesHandler.php b/src/User/Action/Handler/SaveUserTorrentioPreferencesHandler.php new file mode 100644 index 0000000..8ba9df9 --- /dev/null +++ b/src/User/Action/Handler/SaveUserTorrentioPreferencesHandler.php @@ -0,0 +1,48 @@ + */ +class SaveUserTorrentioPreferencesHandler implements HandlerInterface +{ + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly PreferencesRepository $preferenceRepository, + private readonly Security $token, + ) {} + + public function handle(C $command): R + { + /** @var User $user */ + $user = $this->token->getUser(); + + if ($user->hasUserPreference('torrentio_url')) { + $user->updateUserPreference('torrentio_url', (string) $command->torrentioUrl); + $this->entityManager->flush(); + } else { + $preference = $this->preferenceRepository->find('torrentio_url'); + $user->addUserPreference( + (new UserPreference()) + ->setUser($user) + ->setPreference($preference) + ->setPreferenceValue((string) $command->torrentioUrl) + ); + } + + $this->entityManager->flush(); + + return new SaveUserDownloadPreferencesResult($user->getDownloadPreferences()); + } +} diff --git a/src/User/Database/ProviderList.php b/src/User/Database/ProviderList.php index 6374020..b4c7390 100644 --- a/src/User/Database/ProviderList.php +++ b/src/User/Database/ProviderList.php @@ -5,20 +5,31 @@ namespace App\User\Database; class ProviderList { public static $providers = [ - '1337x', - 'Comando', + 'YTS', 'EZTV', - 'ilCorSaRoNeRo', - 'MagnetDL', - 'MejorTorrent', 'RARBG', - 'Rutor', - 'Rutracker', + '1337x', 'ThePirateBay', - 'Torrent9', + 'KickassTorrents', 'TorrentGalaxy', + 'MagnetDL', + 'HorribleSubs', + 'NyaaSi', + 'TokyoTosho', + 'AniDex', + '🇷🇺 Rutor', + '🇷🇺 Rutracker', + '🇵🇹 Comando', + '🇵🇹 BluDV', + '🇫🇷 Torrent9', + '🇮🇹 ilCorSaRoNeRo', + '🇪🇸 MejorTorrent', + '🇪🇸 Wolfmax4k', + '🇲🇽 Cinecalidad', + '🇵🇱 BestTorrents' ]; + public static function getProviders() { return self::$providers; diff --git a/src/User/Framework/Controller/Web/PreferencesController.php b/src/User/Framework/Controller/Web/PreferencesController.php index 2e80ee4..214b931 100644 --- a/src/User/Framework/Controller/Web/PreferencesController.php +++ b/src/User/Framework/Controller/Web/PreferencesController.php @@ -5,10 +5,14 @@ declare(strict_types=1); namespace App\User\Framework\Controller\Web; use App\Base\Service\Broadcaster; +use App\Torrentio\Client\TorrentioUrl; +use App\Torrentio\Framework\Form\TorrentioPreferencesForm; use App\User\Action\Command\SaveUserMediaPreferencesCommand; +use App\User\Action\Command\SaveUserTorrentioPreferencesCommand; use App\User\Action\Handler\SaveUserCalendarPreferencesHandler; use App\User\Action\Handler\SaveUserDownloadPreferencesHandler; use App\User\Action\Handler\SaveUserMediaPreferencesHandler; +use App\User\Action\Handler\SaveUserTorrentioPreferencesHandler; use App\User\Action\Input\SaveUserCalendarPreferencesInput; use App\User\Action\Input\SaveUserDownloadPreferencesInput; use App\User\Action\Input\SaveUserMediaPreferencesInput; @@ -38,6 +42,9 @@ class PreferencesController extends AbstractController $calendarPreferences = $this->getUser()->getCalendarPreferences(); $formData = (array) UserPreferencesFactory::createFromUser($this->getUser()); $form = $this->createForm(UserMediaPreferencesForm::class, $formData); + $torrentioForm = $this->createForm(TorrentioPreferencesForm::class, TorrentioUrl::fromString( + $this->getUser()->getUserPreference('torrentio_url')->getPreferenceValue() + )); return $this->render( 'user/preferences.html.twig', @@ -45,6 +52,7 @@ class PreferencesController extends AbstractController 'downloadPreferences' => $downloadPreferences, 'calendarPreferences' => $calendarPreferences, 'preferences_form' => $form, + 'torrentio_form' => $torrentioForm, ] ); } @@ -131,4 +139,26 @@ class PreferencesController extends AbstractController ] ); } + + #[Route('/user/preferences/torrentio', 'app.torrentio-preferences.save', methods: ['POST'])] + public function saveTorrentioPreferences(Request $request, SaveUserTorrentioPreferencesHandler $handler) + { + $form = $this->createForm(TorrentioPreferencesForm::class, new TorrentioUrl()); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $command = new SaveUserTorrentioPreferencesCommand( + $form->getData(), + ); + $handler->handle($command); + $this->broadcaster->alert('Success', 'Your Torrentio preferences have been saved.'); + } + + return $this->render( + 'user/preferences.html.twig', + [ + 'preferences_form' => $form, + ] + ); + } } diff --git a/src/User/Framework/Entity/User.php b/src/User/Framework/Entity/User.php index 680ac2a..b3d81ac 100644 --- a/src/User/Framework/Entity/User.php +++ b/src/User/Framework/Entity/User.php @@ -5,6 +5,7 @@ namespace App\User\Framework\Entity; use Aimeos\Map; use App\Download\Framework\Entity\Download; use App\Monitor\Framework\Entity\Monitor; +use App\Torrentio\Client\TorrentioUrl; use App\User\Framework\Repository\UserRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -342,4 +343,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this->hasUserPreference('enable_ical_up_ep') && (bool) $this->getUserPreference('enable_ical_up_ep')->getPreferenceValue() === true; } + + public function getTorrentioUrl() + { + return $this->hasUserPreference('torrentio_url') + ? TorrentioUrl::fromString($this->getUserPreference('torrentio_url')->getPreferenceValue()) + : null; + } } diff --git a/src/User/Framework/Entity/UserPreference.php b/src/User/Framework/Entity/UserPreference.php index 472aa74..6140ecb 100644 --- a/src/User/Framework/Entity/UserPreference.php +++ b/src/User/Framework/Entity/UserPreference.php @@ -21,7 +21,7 @@ class UserPreference #[ORM\JoinColumn(nullable: false)] private ?Preference $preference = null; - #[ORM\Column(length: 255, nullable: true)] + #[ORM\Column(length: 1024, nullable: true)] private ?string $preference_value = null; public function getId(): ?int diff --git a/src/Values/TorrentioDebridProviderChoices.php b/src/Values/TorrentioDebridProviderChoices.php new file mode 100644 index 0000000..f933c42 --- /dev/null +++ b/src/Values/TorrentioDebridProviderChoices.php @@ -0,0 +1,27 @@ + 'RealDebrid', + 'premiumize' => 'Premiumize', + 'alldebrid' => 'AllDebrid', + 'debridlink' => 'DebridLink', + 'easydebrid' => 'EasyDebrid', + 'offcloud' => 'Offcloud', + 'torbox' => 'TorBox', + 'putio' => 'Put.io', + ]; + + public static function getProviders(): array + { + return self::$providers; + } + + public static function asSelectOptions(): array + { + return array_flip(self::$providers); + } +} diff --git a/src/Values/TorrentioExcludeQualityChoices.php b/src/Values/TorrentioExcludeQualityChoices.php new file mode 100644 index 0000000..ba6447e --- /dev/null +++ b/src/Values/TorrentioExcludeQualityChoices.php @@ -0,0 +1,34 @@ + 'BluRay REMUX', + 'hdrall' => 'HDR/HDR10+/Dolby Vision', + 'dolbyvision' => 'Dolby Vision', + 'dolbyvisionwithhdr' => 'Dolby Vision + HDR', + 'threed' => '3D', + 'nonthreed' => 'Non 3D (DO NOT SELECT IF NOT SURE)', + '4k' => '4k', + '1080p' => '1080p', + '720p' => '720p', + '480p' => '480p', + 'other' => 'Other (DVDRip/HDRip/BDRip...)', + 'scr' => 'Screener', + 'cam' => 'Cam', + 'unknown' => 'Unknown' + ]; + + + public static function getChoices(): array + { + return self::$choices; + } + + public static function asSelectOptions(): array + { + return array_flip(self::$choices); + } +} diff --git a/src/Values/TorrentioLanguageChoices.php b/src/Values/TorrentioLanguageChoices.php new file mode 100644 index 0000000..9b13899 --- /dev/null +++ b/src/Values/TorrentioLanguageChoices.php @@ -0,0 +1,60 @@ + '🇯🇵 Japanese', + 'russian' => '🇷🇺 Russian', + 'italian' => '🇮🇹 Italian', + 'portuguese' => '🇵🇹 Portuguese', + 'spanish' => '🇪🇸 Spanish', + 'latino' => '🇲🇽 Latino', + 'korean' => '🇰🇷 Korean', + 'chinese' => '🇨🇳 Chinese', + 'taiwanese' => '🇹🇼 Taiwanese', + 'french' => '🇫🇷 French', + 'german' => '🇩🇪 German', + 'dutch' => '🇳🇱 Dutch', + 'hindi' => '🇮🇳 Hindi', + 'telugu' => '🇮🇳 Telugu', + 'tamil' => '🇮🇳 Tamil', + 'polish' => '🇵🇱 Polish', + 'lithuanian' => '🇱🇹 Lithuanian', + 'latvian' => '🇱🇻 Latvian', + 'estonian' => '🇪🇪 Estonian', + 'czech' => '🇨🇿 Czech', + 'slovakian' => '🇸🇰 Slovakian', + 'slovenian' => '🇸🇮 Slovenian', + 'hungarian' => '🇭🇺 Hungarian', + 'romanian' => '🇷🇴 Romanian', + 'bulgarian' => '🇧🇬 Bulgarian', + 'serbian' => '🇷🇸 Serbian', + 'croatian' => '🇭🇷 Croatian', + 'ukrainian' => '🇺🇦 Ukrainian', + 'greek' => '🇬🇷 Greek', + 'danish' => '🇩🇰 Danish', + 'finnish' => '🇫🇮 Finnish', + 'swedish' => '🇸🇪 Swedish', + 'norwegian' => '🇳🇴 Norwegian', + 'turkish' => '🇹🇷 Turkish', + 'arabic' => '🇸🇦 Arabic', + 'persian' => '🇮🇷 Persian', + 'hebrew' => '🇮🇱 Hebrew', + 'vietnamese' => '🇻🇳 Vietnamese', + 'indonesian' => '🇮🇩 Indonesian', + 'malay' => '🇲🇾 Malay', + 'thai' => '🇹🇭 Thai' + ]; + + public static function getLanguages(): array + { + return self::$languages; + } + + public static function asSelectOptions(): array + { + return array_flip(self::$languages); + } +} diff --git a/src/Values/TorrentioProviderChoices.php b/src/Values/TorrentioProviderChoices.php new file mode 100644 index 0000000..34fc447 --- /dev/null +++ b/src/Values/TorrentioProviderChoices.php @@ -0,0 +1,41 @@ + 'YTS', + 'eztv' => 'EZTV', + 'rarbg' => 'RARBG', + '1337x' => '1337x', + 'thepiratebay' => 'ThePirateBay', + 'kickasstorrents' => 'KickassTorrents', + 'torrentgalaxy' => 'TorrentGalaxy', + 'magnetdl' => 'MagnetDL', + 'horriblesubs' => 'HorribleSubs', + 'nyaasi' => 'NyaaSi', + 'tokyotosho' => 'TokyoTosho', + 'anidex' => 'AniDex', + 'rutor' => '🇷🇺 Rutor', + 'rutracker' => '🇷🇺 Rutracker', + 'comando' => '🇵🇹 Comando', + 'bludv' => '🇵🇹 BluDV', + 'torrent9' => '🇫🇷 Torrent9', + 'ilcorsaronero' => '🇮🇹 ilCorSaRoNeRo', + 'mejortorrent' => '🇪🇸 MejorTorrent', + 'wolfmax4k' => '🇪🇸 Wolfmax4k', + 'cinecalidad' => '🇲🇽 Cinecalidad', + 'besttorrents' => '🇵🇱 BestTorrents' + ]; + + public static function getChoices(): array + { + return self::$choices; + } + + public static function asSelectOptions(): array + { + return array_flip(self::$choices); + } +} diff --git a/src/Values/TorrentioSortChoices.php b/src/Values/TorrentioSortChoices.php new file mode 100644 index 0000000..3434070 --- /dev/null +++ b/src/Values/TorrentioSortChoices.php @@ -0,0 +1,23 @@ + 'By quality then seeders', + 'qualitysize' => 'By quality then size', + 'seeders' => 'By seeders', + 'size' => 'By size', + ]; + + public static function getChoices(): array + { + return self::$choices; + } + + public static function asSelectOptions(): array + { + return array_flip(self::$choices); + } +} diff --git a/templates/components/SubmitButton.html.twig b/templates/components/SubmitButton.html.twig index e0024be..6111561 100644 --- a/templates/components/SubmitButton.html.twig +++ b/templates/components/SubmitButton.html.twig @@ -1,4 +1,4 @@ -