Removed --import-unwatched flag for import, we import the state regardless of watched/unwatched now.
This commit is contained in:
34
FAQ.md
34
FAQ.md
@@ -194,32 +194,16 @@ Flags:
|
||||
|
||||
---
|
||||
|
||||
### Q: Can Task scheduler import unwatched episodes?
|
||||
|
||||
Yes, Set the environment variable `WS_CRON_IMPORT_UNWATCHED` in your `docker-compose.yaml` and restart your container
|
||||
for changes to take effect.
|
||||
|
||||
---
|
||||
|
||||
### Q: Can this tool work with alternative Plex agents?
|
||||
|
||||
#### Supported Agents GUIDs:
|
||||
|
||||
* plex://(type)/(id)
|
||||
* tvdb://(id)
|
||||
* imdb://(id)
|
||||
* tmdb://(id)
|
||||
* com.plexapp.agents.imdb://(id)?lang=en
|
||||
* com.plexapp.agents.tmdb://(id)?lang=en
|
||||
* com.plexapp.agents.themoviedb://(id)?lang=en
|
||||
* com.plexapp.agents.hama://(db)-(id)
|
||||
* com.plexapp.agents.xbmcnfo://(id)?lang=en
|
||||
|
||||
#### Unsupported Agents:
|
||||
|
||||
* com.plexapp.agents.tvdb://(show-id)/(season)/(episode)?lang=en
|
||||
* com.plexapp.agents.thetvdb://(show-id)/(season)/(episode)?lang=en
|
||||
* com.plexapp.agents.tvmaze://(show-id)/(season)/(episode)?lang=en
|
||||
* com.plexapp.agents.xbmcnfotv://(show-id)/(season)/(episode)?lang=en
|
||||
|
||||
Those agents do not provide Unique ID, and thus will not work with this tool.
|
||||
* plex://(type)/(id) `New Plex Agent`
|
||||
* tvdb://(id) `New Plex Agent`
|
||||
* imdb://(id) `New Plex Agent`
|
||||
* tmdb://(id) `New Plex Agent`
|
||||
* com.plexapp.agents.imdb://(id)?lang=en `(Old plex agents)`
|
||||
* com.plexapp.agents.tmdb://(id)?lang=en `(Old plex agents)`
|
||||
* com.plexapp.agents.themoviedb://(id)?lang=en `(Old plex agents)`
|
||||
* com.plexapp.agents.hama://(db)-(id) `(anime agent parser)`
|
||||
* com.plexapp.agents.xbmcnfo://(id)?lang=en `( xbmc nfo parser agent)`
|
||||
|
||||
31
README.md
31
README.md
@@ -119,8 +119,7 @@ If you don't want to use webhooks and want to rely only on scheduled task for im
|
||||
of `WS_CRON_IMPORT` to `1`. By default, we run the import command every hour. However, you can change the scheduled task
|
||||
timer by adding another variable `WS_CRON_IMPORT_AT` and set its value to valid cron expression. for
|
||||
example, `0 */2 * * *` it will run every two hours instead of 1 hour. beware, this operation is somewhat costly as it's
|
||||
pulls the entire server library. You can also set `WS_CRON_IMPORT_UNWATCHED` to `1` allow the task to pull unwatched
|
||||
items.
|
||||
pulls the entire server library.
|
||||
|
||||
---
|
||||
|
||||
@@ -304,39 +303,39 @@ None that we are aware of.
|
||||
- (bool) `WS_REQUEST_DEBUG` enable debug mode for pre webhook request.
|
||||
- (integer) `WS_WEBHOOK_TOKEN_LENGTH` how many bits for the webhook api key generator.
|
||||
- (bool) `WS_LOGGER_STDERR_ENABLED` enable stderr output logging.
|
||||
- (string) `WS_LOGGER_STDERR_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY,
|
||||
100|200|250|300|400|500|550|600).
|
||||
- (string) `WS_LOGGER_STDERR_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY).
|
||||
- (bool) `WS_LOGGER_FILE_ENABLE` enable file logging.
|
||||
- (string) `WS_LOGGER_FILE_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY,
|
||||
100|200|250|300|400|500|550|600).
|
||||
- (string) `WS_LOGGER_FILE_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY).
|
||||
- (string) `WS_LOGGER_FILE` full path for log file. By default, it's stored at `$(WS_TMP_DIR)/logs/app.log`
|
||||
- (bool) `WS_LOGGER_SYSLOG_ENABLED` enable syslog logger.
|
||||
- (int) `WS_LOGGER_SYSLOG_FACILITY` syslog logging facility
|
||||
- (string) `WS_LOGGER_SYSLOG_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY,
|
||||
100|200|250|300|400|500|550|600).
|
||||
- (string) `WS_LOGGER_SYSLOG_LEVEL` level to log (DEBUG|INFO|NOTICE|WARNING|ERROR|CRITICAL|ALERT|EMERGENCY).
|
||||
- (string) `WS_LOGGER_SYSLOG_NAME` What name should logs be under.
|
||||
- (int) `WS_CRON_IMPORT` enable import scheduled task.
|
||||
- (string) `WS_CRON_IMPORT_AT` cron expression timer.
|
||||
- (bool) `WS_CRON_IMPORT_UNWATCHED` Allow the import task to import unwatched items. Defaults to `false`.
|
||||
- (string) `WS_CRON_IMPORT_DEBUG_LEVEL` set debug level, to see unmatched items set to `-vv`. Defaults to `-v`
|
||||
- (int) `WS_CRON_EXPORT` enable export scheduled task.
|
||||
- (string) `WS_CRON_EXPORT_AT` cron expression timer.
|
||||
- (string) `WS_CRON_EXPORT_DEBUG_LEVEL` set debug level. Defaults to `-v`
|
||||
- (int) `WS_CRON_PUSH` enable push scheduled task.
|
||||
- (string) `WS_CRON_PUSH_AT` cron expression timer.
|
||||
- (string) `WS_CRON_PUSH_DEBUG_LEVEL` set debug level. Defaults to `-v`
|
||||
- (int) `WS_CRON_CACHE` enable caching of GUIDs relations.
|
||||
- (string) `WS_CRON_CACHE_AT` cron expression timer.
|
||||
- (string) `WS_CRON_CACHE_DEBUG_LEVEL` set debug level. Defaults to `-v`
|
||||
- (string) `WS_LOGS_PRUNE_AFTER` Delete logs older than specified time, set to `disable` to disable logs pruning. it
|
||||
follows php [strtotime](https://www.php.net/strtotime) function rules.
|
||||
- (bool) `WS_DEBUG_IMPORT` Whether to log invalid GUID items from server in `${WS_TMP_DIR}/debug`.
|
||||
- (bool) `WS_IMPORT_PROMOTE_GUID_ERROR` By default we log this error to `INFO` if this variable set to true it will
|
||||
promote it to `NOTICE` level.
|
||||
|
||||
# Container specific environment variables
|
||||
|
||||
- (int) `WS_NO_CHOWN` do not change ownership of `/config` inside container.
|
||||
- (int) `WS_DISABLE_HTTP` disable included http server.
|
||||
- (int) `WS_DISABLE_CRON` disable included task scheduler.
|
||||
- (int) `WS_UID` Container user ID
|
||||
- (int) `WS_GID` Container group ID
|
||||
- (int) `WS_NO_CHOWN` do not change ownership needed paths inside container.
|
||||
- (int) `WS_DISABLE_HTTP` disable included HTTP Server.
|
||||
- (int) `WS_DISABLE_CRON` disable included Task Scheduler.
|
||||
- (int) `WS_UID` Container app user ID.
|
||||
- (int) `WS_GID` Container app group ID.
|
||||
|
||||
---
|
||||
|
||||
# FAQ
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ return (function () {
|
||||
Task::RUN_AT => (string)env('WS_CRON_IMPORT_AT', '0 */1 * * *'),
|
||||
Task::COMMAND => '@state:import',
|
||||
Task::ARGS => [
|
||||
'-v' => null,
|
||||
env('WS_CRON_IMPORT_DEBUG_LEVEL', '-v') => null,
|
||||
]
|
||||
],
|
||||
ExportCommand::TASK_NAME => [
|
||||
@@ -172,7 +172,7 @@ return (function () {
|
||||
Task::RUN_AT => (string)env('WS_CRON_EXPORT_AT', '30 */1 * * *'),
|
||||
Task::COMMAND => '@state:export',
|
||||
Task::ARGS => [
|
||||
'-v' => null,
|
||||
env('WS_CRON_EXPORT_DEBUG_LEVEL', '-v') => null,
|
||||
]
|
||||
],
|
||||
PushCommand::TASK_NAME => [
|
||||
@@ -181,7 +181,7 @@ return (function () {
|
||||
Task::RUN_AT => (string)env('WS_CRON_PUSH_AT', '*/10 * * * *'),
|
||||
Task::COMMAND => '@state:push',
|
||||
Task::ARGS => [
|
||||
'-v' => null,
|
||||
env('WS_CRON_PUSH_DEBUG_LEVEL', '-v') => null,
|
||||
]
|
||||
],
|
||||
CacheCommand::TASK_NAME => [
|
||||
@@ -190,13 +190,13 @@ return (function () {
|
||||
Task::RUN_AT => (string)env('WS_CRON_CACHE_AT', '0 */6 * * *'),
|
||||
Task::COMMAND => '@state:cache',
|
||||
Task::ARGS => [
|
||||
'-v' => null,
|
||||
env('WS_CRON_CACHE_DEBUG_LEVEL', '-v') => null,
|
||||
]
|
||||
],
|
||||
PruneCommand::TASK_NAME => [
|
||||
Task::NAME => PruneCommand::TASK_NAME,
|
||||
Task::ENABLED => (bool)env('WS_CRON_PRUNE', true),
|
||||
Task::RUN_AT => (string)env('WS_CRON_CACHE_AT', '0 */12 * * *'),
|
||||
Task::ENABLED => true,
|
||||
Task::RUN_AT => '0 */12 * * *',
|
||||
Task::COMMAND => '@config:prune',
|
||||
Task::ARGS => [
|
||||
'-v' => null,
|
||||
@@ -204,9 +204,5 @@ return (function () {
|
||||
],
|
||||
];
|
||||
|
||||
if (true === (bool)env('WS_CRON_IMPORT_UNWATCHED', false)) {
|
||||
$config['tasks'][ImportCommand::TASK_NAME][Task::ARGS]['--import-unwatched'] = null;
|
||||
}
|
||||
|
||||
return $config;
|
||||
})();
|
||||
|
||||
@@ -12,7 +12,6 @@ use App\Libs\Entity\StateInterface;
|
||||
use App\Libs\Extends\CliLogger;
|
||||
use App\Libs\Mappers\Import\DirectMapper;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
use App\Libs\Servers\ServerInterface;
|
||||
use App\Libs\Storage\PDO\PDOAdapter;
|
||||
use App\Libs\Storage\StorageInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -64,7 +63,7 @@ class ImportCommand extends Command
|
||||
'timeout',
|
||||
null,
|
||||
InputOption::VALUE_REQUIRED,
|
||||
'Set request timeout in seconds'
|
||||
'Set request timeout in seconds for each request.'
|
||||
)
|
||||
->addOption(
|
||||
'servers-filter',
|
||||
@@ -77,7 +76,7 @@ class ImportCommand extends Command
|
||||
'import-unwatched',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Import unwatched state (note: It Will set items to unwatched if the server has newer date on items)'
|
||||
'--DEPRECATED-- will be removed in v1.x. We import the item regardless of watched/unwatched state.'
|
||||
)
|
||||
->addOption('stats-show', null, InputOption::VALUE_NONE, 'Show final status.')
|
||||
->addOption(
|
||||
@@ -87,7 +86,12 @@ class ImportCommand extends Command
|
||||
'Filter final status output e.g. (servername.key)',
|
||||
null
|
||||
)
|
||||
->addOption('mapper-direct', null, InputOption::VALUE_NONE, 'Use less memory hungry mapper.')
|
||||
->addOption(
|
||||
'mapper-direct',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Uses less memory. However, it\'s significantly slower then default mapper.'
|
||||
)
|
||||
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.');
|
||||
}
|
||||
|
||||
@@ -194,10 +198,6 @@ class ImportCommand extends Command
|
||||
|
||||
$opts = ag($server, 'options', []);
|
||||
|
||||
if ($input->getOption('import-unwatched')) {
|
||||
$opts[ServerInterface::OPT_IMPORT_UNWATCHED] = true;
|
||||
}
|
||||
|
||||
if ($input->getOption('proxy')) {
|
||||
$opts['client']['proxy'] = $input->getOption('proxy');
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace App\Libs\Mappers\Import;
|
||||
use App\Libs\Data;
|
||||
use App\Libs\Entity\StateInterface;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
use App\Libs\Servers\ServerInterface;
|
||||
use App\Libs\Storage\StorageInterface;
|
||||
use DateTimeInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -21,11 +20,9 @@ final class DirectMapper implements ImportInterface
|
||||
];
|
||||
|
||||
private int $changed = 0;
|
||||
private string $guidErrorLevel = 'info';
|
||||
|
||||
public function __construct(private LoggerInterface $logger, private StorageInterface $storage)
|
||||
{
|
||||
$this->guidErrorLevel = true === (bool)env('WS_IMPORT_PROMOTE_GUID_ERROR', false) ? 'notice' : 'info';
|
||||
}
|
||||
|
||||
public function setUp(array $opts): ImportInterface
|
||||
@@ -41,7 +38,7 @@ final class DirectMapper implements ImportInterface
|
||||
public function add(string $bucket, string $name, StateInterface $entity, array $opts = []): self
|
||||
{
|
||||
if (!$entity->hasGuids()) {
|
||||
$this->logger->{$this->guidErrorLevel}(sprintf('Ignoring %s. No valid GUIDs.', $name));
|
||||
$this->logger->info(sprintf('Ignoring %s. No valid GUIDs.', $name));
|
||||
Data::increment($bucket, $entity->type . '_failed_no_guid');
|
||||
return $this;
|
||||
}
|
||||
@@ -49,12 +46,6 @@ final class DirectMapper implements ImportInterface
|
||||
$item = $this->get($entity);
|
||||
|
||||
if (null === $entity->id && null === $item) {
|
||||
if (0 === $entity->watched && true !== ($opts[ServerInterface::OPT_IMPORT_UNWATCHED] ?? false)) {
|
||||
$this->logger->debug(sprintf('Ignoring %s. Not watched.', $name));
|
||||
Data::increment($bucket, $entity->type . '_ignored_not_watched');
|
||||
return $this;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->storage->insert($entity);
|
||||
} catch (Throwable $e) {
|
||||
@@ -70,31 +61,6 @@ final class DirectMapper implements ImportInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
// -- Ignore unwatched Item.
|
||||
if (0 === $entity->watched && true !== ($opts[ServerInterface::OPT_IMPORT_UNWATCHED] ?? false)) {
|
||||
// -- check for updated GUIDs.
|
||||
if ($item->apply($entity, guidOnly: true)->isChanged()) {
|
||||
try {
|
||||
$this->changed++;
|
||||
if (!empty($entity->meta)) {
|
||||
$item->meta = $entity->meta;
|
||||
}
|
||||
$this->storage->update($item);
|
||||
$this->operations[$entity->type]['updated']++;
|
||||
$this->logger->debug(sprintf('Updating %s. GUIDs.', $name), $item->diff());
|
||||
return $this;
|
||||
} catch (Throwable $e) {
|
||||
$this->operations[$entity->type]['failed']++;
|
||||
Data::append($bucket, 'storage_error', $e->getMessage());
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->debug(sprintf('Ignoring %s. Not watched.', $name));
|
||||
Data::increment($bucket, $entity->type . '_ignored_not_watched');
|
||||
return $this;
|
||||
}
|
||||
|
||||
// -- Ignore old item.
|
||||
if (null !== ($opts['after'] ?? null) && ($opts['after'] instanceof DateTimeInterface)) {
|
||||
if ($opts['after']->getTimestamp() >= $entity->updated) {
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace App\Libs\Mappers\Import;
|
||||
use App\Libs\Data;
|
||||
use App\Libs\Entity\StateInterface;
|
||||
use App\Libs\Mappers\ImportInterface;
|
||||
use App\Libs\Servers\ServerInterface;
|
||||
use App\Libs\Storage\StorageInterface;
|
||||
use DateTimeInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -33,11 +32,8 @@ final class MemoryMapper implements ImportInterface
|
||||
|
||||
private bool $fullyLoaded = false;
|
||||
|
||||
private string $guidErrorLevel = 'info';
|
||||
|
||||
public function __construct(private LoggerInterface $logger, private StorageInterface $storage)
|
||||
{
|
||||
$this->guidErrorLevel = true === (bool)env('WS_IMPORT_PROMOTE_GUID_ERROR', false) ? 'notice' : 'info';
|
||||
}
|
||||
|
||||
public function setUp(array $opts): ImportInterface
|
||||
@@ -65,18 +61,12 @@ final class MemoryMapper implements ImportInterface
|
||||
public function add(string $bucket, string $name, StateInterface $entity, array $opts = []): self
|
||||
{
|
||||
if (!$entity->hasGuids()) {
|
||||
$this->logger->{$this->guidErrorLevel}(sprintf('Ignoring %s. No valid GUIDs.', $name));
|
||||
$this->logger->info(sprintf('Ignoring %s. No valid GUIDs.', $name));
|
||||
Data::increment($bucket, $entity->type . '_failed_no_guid');
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (false === ($pointer = $this->getPointer($entity))) {
|
||||
if (0 === $entity->watched && true !== ($opts[ServerInterface::OPT_IMPORT_UNWATCHED] ?? false)) {
|
||||
$this->logger->debug(sprintf('Ignoring %s. Not watched.', $name));
|
||||
Data::increment($bucket, $entity->type . '_ignored_not_watched');
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->objects[] = $entity;
|
||||
|
||||
$pointer = array_key_last($this->objects);
|
||||
@@ -89,25 +79,6 @@ final class MemoryMapper implements ImportInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
// -- Ignore unwatched Item.
|
||||
if (0 === $entity->watched && true !== ($opts[ServerInterface::OPT_IMPORT_UNWATCHED] ?? false)) {
|
||||
// -- check for updated GUIDs.
|
||||
if ($this->objects[$pointer]->apply($entity, guidOnly: true)->isChanged()) {
|
||||
$this->changed[$pointer] = $pointer;
|
||||
if (!empty($entity->meta)) {
|
||||
$this->objects[$pointer]->meta = $entity->meta;
|
||||
}
|
||||
Data::increment($bucket, $entity->type . '_updated');
|
||||
$this->addGuids($this->objects[$pointer], $pointer);
|
||||
$this->logger->debug(sprintf('Updating %s. GUIDs.', $name), $this->objects[$pointer]->diff());
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->logger->debug(sprintf('Ignoring %s. Not watched.', $name));
|
||||
Data::increment($bucket, $entity->type . '_ignored_not_watched');
|
||||
return $this;
|
||||
}
|
||||
|
||||
// -- Ignore old item.
|
||||
if (null !== ($opts['after'] ?? null) && ($opts['after'] instanceof DateTimeInterface)) {
|
||||
if ($opts['after']->getTimestamp() >= $entity->updated) {
|
||||
|
||||
@@ -74,14 +74,11 @@ class JellyfinServer implements ServerInterface
|
||||
protected array $cacheData = [];
|
||||
protected string|int|null $uuid = null;
|
||||
|
||||
protected string $guidErrorLevel = 'info';
|
||||
|
||||
public function __construct(
|
||||
protected HttpClientInterface $http,
|
||||
protected LoggerInterface $logger,
|
||||
protected CacheInterface $cache
|
||||
) {
|
||||
$this->guidErrorLevel = true === (bool)env('WS_IMPORT_PROMOTE_GUID_ERROR', false) ? 'notice' : 'info';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1296,7 +1293,7 @@ class JellyfinServer implements ServerInterface
|
||||
|
||||
$guids = (array)($item->ProviderIds ?? []);
|
||||
|
||||
$this->logger->{$this->guidErrorLevel}(
|
||||
$this->logger->info(
|
||||
sprintf(
|
||||
'Ignoring %s. No valid GUIDs. Possibly unmatched item?',
|
||||
$iName
|
||||
@@ -1355,8 +1352,7 @@ class JellyfinServer implements ServerInterface
|
||||
];
|
||||
|
||||
$mapper->add($this->name, $iName, Container::get(StateInterface::class)::fromArray($row), [
|
||||
'after' => $after,
|
||||
self::OPT_IMPORT_UNWATCHED => (bool)($this->options[self::OPT_IMPORT_UNWATCHED] ?? false),
|
||||
'after' => $after
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->error($e->getMessage(), [
|
||||
|
||||
@@ -45,6 +45,15 @@ class PlexServer implements ServerInterface
|
||||
'anidb' => Guid::GUID_ANIDB,
|
||||
];
|
||||
|
||||
protected const DISABLED_GUID_AGENTS = [
|
||||
'local',
|
||||
'com.plexapp.agents.none',
|
||||
'com.plexapp.agents.tvdb',
|
||||
'com.plexapp.agents.thetvdb',
|
||||
'com.plexapp.agents.tvmaze',
|
||||
'com.plexapp.agents.xbmcnfotv',
|
||||
];
|
||||
|
||||
protected const WEBHOOK_ALLOWED_TYPES = [
|
||||
'movie',
|
||||
'episode',
|
||||
@@ -78,14 +87,11 @@ class PlexServer implements ServerInterface
|
||||
protected string|int|null $uuid = null;
|
||||
protected string|int|null $user = null;
|
||||
|
||||
protected string $guidErrorLevel = 'info';
|
||||
|
||||
public function __construct(
|
||||
protected HttpClientInterface $http,
|
||||
protected LoggerInterface $logger,
|
||||
protected CacheInterface $cache
|
||||
) {
|
||||
$this->guidErrorLevel = true === (bool)env('WS_IMPORT_PROMOTE_GUID_ERROR', false) ? 'notice' : 'info';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1336,12 +1342,13 @@ class PlexServer implements ServerInterface
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->{$this->guidErrorLevel}(
|
||||
$this->logger->info(
|
||||
sprintf('Ignoring %s. No valid GUIDs. Possibly unmatched item?', $iName),
|
||||
[
|
||||
'guids' => empty($item->Guid) ? 'None' : $item->Guid,
|
||||
]
|
||||
);
|
||||
|
||||
Data::increment($this->name, $type . '_ignored_no_supported_guid');
|
||||
return;
|
||||
}
|
||||
@@ -1389,7 +1396,6 @@ class PlexServer implements ServerInterface
|
||||
|
||||
$mapper->add($this->name, $iName, Container::get(StateInterface::class)::fromArray($row), [
|
||||
'after' => $after,
|
||||
self::OPT_IMPORT_UNWATCHED => (bool)($this->options[self::OPT_IMPORT_UNWATCHED] ?? false),
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
$this->logger->error($e->getMessage(), [
|
||||
@@ -1513,37 +1519,22 @@ class PlexServer implements ServerInterface
|
||||
* com.plexapp.agents.hama://(db)-(id)
|
||||
* com.plexapp.agents.xbmcnfo://(id)?lang=xn > imdb
|
||||
* @Disabled For:
|
||||
* local://(id)
|
||||
* com.plexapp.agents.none://(gid)?lang=en
|
||||
* com.plexapp.agents.tvdb://(show-id)/(season)/(episode)?lang=en
|
||||
* com.plexapp.agents.thetvdb://(show-id)/(season)/(episode)?lang=en
|
||||
* com.plexapp.agents.tvmaze://(show-id)/(season)/(episode))?lang=en
|
||||
* com.plexapp.agents.xbmcnfotv://(show-id)/(season)/(episode)?lang=xn
|
||||
*/
|
||||
|
||||
$this->logger->debug('Parsing Legacy plex content agent.', ['guid' => $agent]);
|
||||
|
||||
$disabled = [
|
||||
'com.plexapp.agents.tvdb',
|
||||
'com.plexapp.agents.thetvdb',
|
||||
'com.plexapp.agents.tvmaze',
|
||||
'com.plexapp.agents.xbmcnfotv',
|
||||
];
|
||||
|
||||
if (in_array(before($agent, '://'), $disabled)) {
|
||||
$this->logger->{$this->guidErrorLevel}(
|
||||
'Unable to parse GUID as it does not provide episode unique id',
|
||||
['guid' => $agent]
|
||||
);
|
||||
if (true === in_array(before($agent, '://'), self::DISABLED_GUID_AGENTS)) {
|
||||
return $agent;
|
||||
}
|
||||
|
||||
try {
|
||||
if (str_starts_with($agent, 'com.plexapp.agents.none')) {
|
||||
return $agent;
|
||||
}
|
||||
|
||||
$replacer = [
|
||||
'agents.themoviedb' => 'agents.tmdb',
|
||||
'agents.xbmcnfo://' => 'agents.imdb://',
|
||||
'com.plexapp.agents.themoviedb://' => 'com.plexapp.agents.tmdb://',
|
||||
'com.plexapp.agents.xbmcnfo://' => 'com.plexapp.agents.imdb://',
|
||||
];
|
||||
|
||||
$agent = str_replace(array_keys($replacer), array_values($replacer), $agent);
|
||||
@@ -1554,7 +1545,7 @@ class PlexServer implements ServerInterface
|
||||
}
|
||||
}
|
||||
|
||||
$id = afterlast($agent, 'agents.');
|
||||
$id = afterLast($agent, 'agents.');
|
||||
$agentGuid = explode('://', $id);
|
||||
$agent = $agentGuid[0];
|
||||
$guid = explode('/', $agentGuid[1])[0];
|
||||
|
||||
@@ -17,7 +17,6 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
interface ServerInterface
|
||||
{
|
||||
public const OPT_IMPORT_UNWATCHED = 'importUnwatched';
|
||||
public const OPT_EXPORT_IGNORE_DATE = 'exportIgnoreDate';
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user