Compare commits
4 Commits
dev-torren
...
v0.32.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 662e2600f6 | |||
| aa042e8275 | |||
| 57498b1abf | |||
| fed1e1e122 |
@@ -168,7 +168,6 @@ dialog[data-dialog-target="dialog"][closing] {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
form[name="torrentio_preferences_form"],
|
|
||||||
#filter {
|
#filter {
|
||||||
.ts-wrapper {
|
.ts-wrapper {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Base\Framework\Command;
|
|||||||
|
|
||||||
use App\User\Framework\Entity\Preference;
|
use App\User\Framework\Entity\Preference;
|
||||||
use App\User\Framework\Entity\UserPreference;
|
use App\User\Framework\Entity\UserPreference;
|
||||||
|
use App\User\Framework\Repository\PreferenceOptionRepository;
|
||||||
use App\User\Framework\Repository\PreferencesRepository;
|
use App\User\Framework\Repository\PreferencesRepository;
|
||||||
use App\User\Framework\Repository\UserRepository;
|
use App\User\Framework\Repository\UserRepository;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
@@ -138,16 +139,9 @@ class SeedDatabaseCommand extends Command
|
|||||||
'id' => 'enable_ical_up_ep',
|
'id' => 'enable_ical_up_ep',
|
||||||
'name' => 'Enable a publicly available iCal calendar?',
|
'name' => 'Enable a publicly available iCal calendar?',
|
||||||
'description' => 'Enable a publicly accessible iCal URL for your upcoming episodes.',
|
'description' => 'Enable a publicly accessible iCal URL for your upcoming episodes.',
|
||||||
'enabled' => true,
|
'enabled' => false,
|
||||||
'type' => 'calendar'
|
'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'
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
55
src/Torrentio/Client/HttpClient.php
Normal file
55
src/Torrentio/Client/HttpClient.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Torrentio\Client;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use GuzzleHttp\Client as GuzzleClient;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
use Symfony\Contracts\Cache\ItemInterface;
|
||||||
|
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||||
|
|
||||||
|
class HttpClient
|
||||||
|
{
|
||||||
|
private GuzzleClient $client;
|
||||||
|
|
||||||
|
private string $baseUrl = 'https://torrentio.strem.fun/realdebrid=%s/';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
#[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey,
|
||||||
|
private TagAwareCacheInterface $cache,
|
||||||
|
private LoggerInterface $logger,
|
||||||
|
) {
|
||||||
|
$this->client = new GuzzleClient([
|
||||||
|
'base_uri' => sprintf($this->baseUrl, $this->realDebridKey),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(string $imdbId, array $cacheTags = []): array
|
||||||
|
{
|
||||||
|
$cacheKey = str_replace(":", ".", "torrentio.{$imdbId}");
|
||||||
|
|
||||||
|
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $cacheTags) {
|
||||||
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
|
if (count($cacheTags) > 0) {
|
||||||
|
$item->tag($cacheTags);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$response = $this->client->get("stream/movie/$imdbId.json");
|
||||||
|
return json_decode(
|
||||||
|
$response->getBody()->getContents(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} catch (\Throwable $exception) {
|
||||||
|
dd($exception);
|
||||||
|
if ($exception->getCode() === 429) {
|
||||||
|
$this->logger->warning("> [TorrentioClient] Rate limit exceeded");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents());
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,68 +2,19 @@
|
|||||||
|
|
||||||
namespace App\Torrentio\Client;
|
namespace App\Torrentio\Client;
|
||||||
|
|
||||||
use App\Torrentio\Client\Rule\DownloadOptionFilter\Resolution;
|
|
||||||
use App\Torrentio\Client\Rule\RuleEngine;
|
|
||||||
use App\Torrentio\Result\ResultFactory;
|
use App\Torrentio\Result\ResultFactory;
|
||||||
use Carbon\Carbon;
|
|
||||||
use App\Torrentio\Exception\TorrentioRateLimitException;
|
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
|
class Torrentio
|
||||||
{
|
{
|
||||||
private string $baseUrl = 'https://torrentio.strem.fun/realdebrid={realDebridKey}/stream/movie';
|
|
||||||
|
|
||||||
private string $searchUrl;
|
|
||||||
|
|
||||||
private Client $client;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
#[Autowire(env: 'REAL_DEBRID_KEY')] private string $realDebridKey,
|
private readonly HttpClient $client,
|
||||||
private TagAwareCacheInterface $cache,
|
) {}
|
||||||
private LoggerInterface $logger,
|
|
||||||
private Security $security,
|
|
||||||
) {
|
|
||||||
// $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,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function search(string $imdbCode, string $type, bool $parseResults = true): array
|
public function search(string $imdbCode, string $type, bool $parseResults = true): array
|
||||||
{
|
{
|
||||||
$cacheKey = "torrentio.{$imdbCode}";
|
$cacheTags = ['torrentio', $type, $imdbCode];
|
||||||
|
$results = $this->client->get($imdbCode, $cacheTags);
|
||||||
// $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");
|
|
||||||
$results = json_decode(
|
|
||||||
$response->getBody()->getContents(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
// dd($results);
|
|
||||||
} catch (\Throwable $exception) {
|
|
||||||
if ($exception->getCode() === 429) {
|
|
||||||
$this->logger->warning("> [TorrentioClient] Rate limit exceeded");
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents());
|
|
||||||
// return [];
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (true === $parseResults) {
|
if (true === $parseResults) {
|
||||||
return $this->parse($results);
|
return $this->parse($results);
|
||||||
@@ -74,26 +25,8 @@ class Torrentio
|
|||||||
|
|
||||||
public function fetchEpisodeResults(string $imdbId, int $season, int $episode, bool $parseResults = true): array
|
public function fetchEpisodeResults(string $imdbId, int $season, int $episode, bool $parseResults = true): array
|
||||||
{
|
{
|
||||||
// $cacheKey = "torrentio.$imdbId.$season.$episode";
|
$cacheTags = ['torrentio', 'tvshows', 'torrentio.tvshows', $imdbId, "torrentio.$imdbId", "$imdbId.$season", "torrentio.$imdbId.$season", "$imdbId.$season.$episode", "torrentio.$imdbId.$season.$episode"];
|
||||||
// $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) {
|
$results = $this->client->get("$imdbId:$season:$episode", $cacheTags);
|
||||||
// $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");
|
|
||||||
$results = json_decode(
|
|
||||||
$response->getBody()->getContents(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
} catch (\Throwable $exception) {
|
|
||||||
if ($exception->getCode() === 429) {
|
|
||||||
$this->logger->warning("> [TorrentioClient] Rate limit exceeded");
|
|
||||||
throw $exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents());
|
|
||||||
// return [];
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (null === $results) {
|
if (null === $results) {
|
||||||
throw new TorrentioRateLimitException();
|
throw new TorrentioRateLimitException();
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Client;
|
|
||||||
|
|
||||||
use App\Values\TorrentioDebridProviderChoices;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Torrentio\Framework\Form;
|
|
||||||
|
|
||||||
use Aimeos\Map;
|
|
||||||
use App\User\Database\ProviderList;
|
|
||||||
use App\Values\TorrentioDebridProviderChoices;
|
|
||||||
use App\Values\TorrentioExcludeQualityChoices;
|
|
||||||
use App\Values\TorrentioLanguageChoices;
|
|
||||||
use App\Values\TorrentioProviderChoices;
|
|
||||||
use App\Values\TorrentioSortChoices;
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|
||||||
|
|
||||||
class TorrentioPreferencesForm extends AbstractType
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
private readonly UrlGeneratorInterface $urlGenerator,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
|
||||||
{
|
|
||||||
$this->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',
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\User\Action\Command;
|
|
||||||
|
|
||||||
use App\Torrentio\Client\TorrentioUrl;
|
|
||||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
|
||||||
|
|
||||||
/** @implements CommandInterface<SaveUserMediaPreferencesCommand> */
|
|
||||||
class SaveUserTorrentioPreferencesCommand implements CommandInterface
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public TorrentioUrl $torrentioUrl,
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\User\Action\Handler;
|
|
||||||
|
|
||||||
use App\User\Action\Command\SaveUserMediaPreferencesCommand;
|
|
||||||
use App\User\Action\Result\SaveUserDownloadPreferencesResult;
|
|
||||||
use App\User\Action\Result\SaveUserMediaPreferencesResult;
|
|
||||||
use App\User\Framework\Entity\User;
|
|
||||||
use App\User\Framework\Entity\UserPreference;
|
|
||||||
use App\User\Framework\Repository\PreferencesRepository;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use OneToMany\RichBundle\Contract\CommandInterface as C;
|
|
||||||
use OneToMany\RichBundle\Contract\HandlerInterface;
|
|
||||||
use OneToMany\RichBundle\Contract\ResultInterface as R;
|
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
|
||||||
|
|
||||||
/** @implements HandlerInterface<SaveUserMediaPreferencesCommand> */
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,31 +5,20 @@ namespace App\User\Database;
|
|||||||
class ProviderList
|
class ProviderList
|
||||||
{
|
{
|
||||||
public static $providers = [
|
public static $providers = [
|
||||||
'YTS',
|
|
||||||
'EZTV',
|
|
||||||
'RARBG',
|
|
||||||
'1337x',
|
'1337x',
|
||||||
'ThePirateBay',
|
'Comando',
|
||||||
'KickassTorrents',
|
'EZTV',
|
||||||
'TorrentGalaxy',
|
'ilCorSaRoNeRo',
|
||||||
'MagnetDL',
|
'MagnetDL',
|
||||||
'HorribleSubs',
|
'MejorTorrent',
|
||||||
'NyaaSi',
|
'RARBG',
|
||||||
'TokyoTosho',
|
'Rutor',
|
||||||
'AniDex',
|
'Rutracker',
|
||||||
'🇷🇺 Rutor',
|
'ThePirateBay',
|
||||||
'🇷🇺 Rutracker',
|
'Torrent9',
|
||||||
'🇵🇹 Comando',
|
'TorrentGalaxy',
|
||||||
'🇵🇹 BluDV',
|
|
||||||
'🇫🇷 Torrent9',
|
|
||||||
'🇮🇹 ilCorSaRoNeRo',
|
|
||||||
'🇪🇸 MejorTorrent',
|
|
||||||
'🇪🇸 Wolfmax4k',
|
|
||||||
'🇲🇽 Cinecalidad',
|
|
||||||
'🇵🇱 BestTorrents'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
public static function getProviders()
|
public static function getProviders()
|
||||||
{
|
{
|
||||||
return self::$providers;
|
return self::$providers;
|
||||||
|
|||||||
@@ -5,14 +5,10 @@ declare(strict_types=1);
|
|||||||
namespace App\User\Framework\Controller\Web;
|
namespace App\User\Framework\Controller\Web;
|
||||||
|
|
||||||
use App\Base\Service\Broadcaster;
|
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\SaveUserMediaPreferencesCommand;
|
||||||
use App\User\Action\Command\SaveUserTorrentioPreferencesCommand;
|
|
||||||
use App\User\Action\Handler\SaveUserCalendarPreferencesHandler;
|
use App\User\Action\Handler\SaveUserCalendarPreferencesHandler;
|
||||||
use App\User\Action\Handler\SaveUserDownloadPreferencesHandler;
|
use App\User\Action\Handler\SaveUserDownloadPreferencesHandler;
|
||||||
use App\User\Action\Handler\SaveUserMediaPreferencesHandler;
|
use App\User\Action\Handler\SaveUserMediaPreferencesHandler;
|
||||||
use App\User\Action\Handler\SaveUserTorrentioPreferencesHandler;
|
|
||||||
use App\User\Action\Input\SaveUserCalendarPreferencesInput;
|
use App\User\Action\Input\SaveUserCalendarPreferencesInput;
|
||||||
use App\User\Action\Input\SaveUserDownloadPreferencesInput;
|
use App\User\Action\Input\SaveUserDownloadPreferencesInput;
|
||||||
use App\User\Action\Input\SaveUserMediaPreferencesInput;
|
use App\User\Action\Input\SaveUserMediaPreferencesInput;
|
||||||
@@ -42,9 +38,6 @@ class PreferencesController extends AbstractController
|
|||||||
$calendarPreferences = $this->getUser()->getCalendarPreferences();
|
$calendarPreferences = $this->getUser()->getCalendarPreferences();
|
||||||
$formData = (array) UserPreferencesFactory::createFromUser($this->getUser());
|
$formData = (array) UserPreferencesFactory::createFromUser($this->getUser());
|
||||||
$form = $this->createForm(UserMediaPreferencesForm::class, $formData);
|
$form = $this->createForm(UserMediaPreferencesForm::class, $formData);
|
||||||
$torrentioForm = $this->createForm(TorrentioPreferencesForm::class, TorrentioUrl::fromString(
|
|
||||||
$this->getUser()->getUserPreference('torrentio_url')->getPreferenceValue()
|
|
||||||
));
|
|
||||||
|
|
||||||
return $this->render(
|
return $this->render(
|
||||||
'user/preferences.html.twig',
|
'user/preferences.html.twig',
|
||||||
@@ -52,7 +45,6 @@ class PreferencesController extends AbstractController
|
|||||||
'downloadPreferences' => $downloadPreferences,
|
'downloadPreferences' => $downloadPreferences,
|
||||||
'calendarPreferences' => $calendarPreferences,
|
'calendarPreferences' => $calendarPreferences,
|
||||||
'preferences_form' => $form,
|
'preferences_form' => $form,
|
||||||
'torrentio_form' => $torrentioForm,
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -139,26 +131,4 @@ 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,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace App\User\Framework\Entity;
|
|||||||
use Aimeos\Map;
|
use Aimeos\Map;
|
||||||
use App\Download\Framework\Entity\Download;
|
use App\Download\Framework\Entity\Download;
|
||||||
use App\Monitor\Framework\Entity\Monitor;
|
use App\Monitor\Framework\Entity\Monitor;
|
||||||
use App\Torrentio\Client\TorrentioUrl;
|
|
||||||
use App\User\Framework\Repository\UserRepository;
|
use App\User\Framework\Repository\UserRepository;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
@@ -343,11 +342,4 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
return $this->hasUserPreference('enable_ical_up_ep') &&
|
return $this->hasUserPreference('enable_ical_up_ep') &&
|
||||||
(bool) $this->getUserPreference('enable_ical_up_ep')->getPreferenceValue() === true;
|
(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class UserPreference
|
|||||||
#[ORM\JoinColumn(nullable: false)]
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
private ?Preference $preference = null;
|
private ?Preference $preference = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 1024, nullable: true)]
|
#[ORM\Column(length: 255, nullable: true)]
|
||||||
private ?string $preference_value = null;
|
private ?string $preference_value = null;
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Values;
|
|
||||||
|
|
||||||
class TorrentioDebridProviderChoices
|
|
||||||
{
|
|
||||||
public static array $providers = [
|
|
||||||
'realdebrid' => '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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Values;
|
|
||||||
|
|
||||||
class TorrentioExcludeQualityChoices
|
|
||||||
{
|
|
||||||
public static array $choices = [
|
|
||||||
'brremux' => '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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Values;
|
|
||||||
|
|
||||||
class TorrentioLanguageChoices
|
|
||||||
{
|
|
||||||
public static array $languages = [
|
|
||||||
'japanese' => '🇯🇵 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Values;
|
|
||||||
|
|
||||||
class TorrentioProviderChoices
|
|
||||||
{
|
|
||||||
public static array $choices = [
|
|
||||||
'yts' => '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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Values;
|
|
||||||
|
|
||||||
class TorrentioSortChoices
|
|
||||||
{
|
|
||||||
public static array $choices = [
|
|
||||||
'quality' => '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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<button class="submit-button {{ class|default('flex flex-row gap-2 items-center') }}">
|
<button class="submit-button flex flex-row gap-2 items-center">
|
||||||
{% if show_icon|default %}
|
{% if show_icon|default %}
|
||||||
<twig:ux:icon name="zondicons:checkmark" width=".8rem" class="text-green-500" />
|
<twig:ux:icon name="zondicons:checkmark" width=".8rem" class="text-green-500" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -57,30 +57,4 @@
|
|||||||
</form>
|
</form>
|
||||||
</twig:Card>
|
</twig:Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 flex flex-col md:flex-row gap-2">
|
|
||||||
<twig:Card title="Torrentio Preferences" class="w-full">
|
|
||||||
<p class="text-gray-50 mb-4">Configure your Torrentio client.</p>
|
|
||||||
{{ form_start(torrentio_form, {
|
|
||||||
action: path('app.torrentio-preferences.save')
|
|
||||||
}) }}
|
|
||||||
<div class="flex flex-col md:flex-row gap-2">
|
|
||||||
<div class="self-end mb-4">
|
|
||||||
{{ form_row(torrentio_form.providers) }}
|
|
||||||
{{ form_row(torrentio_form.sorting) }}
|
|
||||||
{{ form_row(torrentio_form.language) }}
|
|
||||||
{{ form_row(torrentio_form.qualityfilter) }}
|
|
||||||
{{ form_row(torrentio_form.limit) }}
|
|
||||||
{{ form_row(torrentio_form.sizefilter) }}
|
|
||||||
{{ form_row(torrentio_form.debridProvider) }}
|
|
||||||
{{ form_row(torrentio_form.debridToken) }}
|
|
||||||
{{ form_widget(torrentio_form._token) }}
|
|
||||||
<div class="w-[5rem]">
|
|
||||||
<twig:SubmitButton show_icon text="Save"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ form_end(preferences_form) }}
|
|
||||||
</twig:Card>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user