diff --git a/src/Commands/Servers/ManageCommand.php b/src/Commands/Servers/ManageCommand.php
index 24c9ad5c..9e87bd22 100644
--- a/src/Commands/Servers/ManageCommand.php
+++ b/src/Commands/Servers/ManageCommand.php
@@ -6,6 +6,7 @@ namespace App\Commands\Servers;
use App\Command;
use App\Libs\Config;
+use App\Libs\Options;
use Exception;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
@@ -95,7 +96,11 @@ final class ManageCommand extends Command
if (true === $add && null !== ag($servers, "{$name}.type", null)) {
$output->writeln(
- sprintf('ERROR: Backend name \'%s\' already exists in \'%s\'.', $name, $config)
+ sprintf(
+ 'ERROR: Backend name \'%s\' already exists in \'%s\' omit the --add flag if you want to edit the config.',
+ $name,
+ $config
+ )
);
return self::FAILURE;
}
@@ -103,7 +108,7 @@ final class ManageCommand extends Command
$u = $rerun ?? ag($servers, $name, []);
// -- $name.type
- (function () use ($input, $output, &$u) {
+ (function () use ($input, $output, &$u, $name) {
$list = array_keys(Config::get('supported', []));
$chosen = ag($u, 'type');
@@ -112,7 +117,8 @@ final class ManageCommand extends Command
$question = new ChoiceQuestion(
sprintf(
- 'Select backend type. %s',
+ 'Select %s type. %s',
+ $name,
null !== $chosen ? "[Default: {$chosen}]" : ''
),
$list,
@@ -132,14 +138,13 @@ final class ManageCommand extends Command
$output->writeln('');
// -- $name.url
- (function () use ($input, $output, &$u) {
+ (function () use ($input, $output, &$u, $name) {
$helper = $this->getHelper('question');
$chosen = ag($u, 'url');
$question = new Question(
sprintf(
- 'Please enter %s URL. %s' . PHP_EOL . '> ',
- ucfirst(ag($u, 'type')),
-
+ 'Enter %s URL. %s' . PHP_EOL . '> ',
+ $name,
null !== $chosen ? "[Default: {$chosen}]" : '',
),
$chosen
@@ -158,13 +163,13 @@ final class ManageCommand extends Command
$output->writeln('');
// -- $name.token
- (function () use ($input, $output, &$u) {
+ (function () use ($input, $output, &$u, $name) {
$helper = $this->getHelper('question');
$chosen = ag($u, 'token');
$question = new Question(
sprintf(
- 'Please enter %s API token. %s' . PHP_EOL . '> ',
- ucfirst(ag($u, 'type')),
+ 'Enter %s API token. %s' . PHP_EOL . '> ',
+ $name,
null !== $chosen ? "[Default: {$chosen}]" : '',
),
$chosen
@@ -215,8 +220,8 @@ final class ManageCommand extends Command
$helper = $this->getHelper('question');
$question = new Question(
sprintf(
- 'Please enter %s unique identifier. %s' . PHP_EOL . '> ',
- ucfirst(ag($u, 'type')),
+ 'Enter %s backend unique identifier. %s' . PHP_EOL . '> ',
+ $name,
null !== $chosen ? "[Default: {$chosen}]" : '',
),
$chosen
@@ -243,32 +248,8 @@ final class ManageCommand extends Command
})();
$output->writeln('');
- // -- if the backend is plex we may need to skip user validation
- $chooseUser = (function () use ($input, $output, &$u) {
- $chosen = ag($u, 'type');
-
- if ('plex' !== $chosen || null !== ag($u, 'user')) {
- return true;
- }
-
- $helper = $this->getHelper('question');
- $text =
- <<[Y|N]
- it's important to know otherwise their watch history might end up in your history if you use webhooks
- TEXT;
-
- $question = new ConfirmationQuestion($text . PHP_EOL . '> ', false);
-
- return $helper->ask($input, $output, $question);
- })();
-
// -- $name.user
- (function () use ($input, $output, &$u, $name, $chooseUser) {
- if (false === $chooseUser) {
- return;
- }
-
+ (function () use ($input, $output, &$u, $name) {
$chosen = ag($u, 'user');
try {
@@ -359,10 +340,7 @@ final class ManageCommand extends Command
$chosen = (bool)ag($u, 'import.enabled', true);
$helper = $this->getHelper('question');
- $text =
- <<"Import" from this backend via scheduled task? %s
- TEXT;
+ $text = 'Enable Importing metadata and play state from this backend? %s';
$question = new ConfirmationQuestion(
sprintf(
@@ -382,10 +360,7 @@ final class ManageCommand extends Command
$chosen = (bool)ag($u, 'export.enabled', true);
$helper = $this->getHelper('question');
- $text =
- <<"Export" to this backend via scheduled task? %s
- TEXT;
+ $text = 'Enable Exporting play state to this backend? %s';
$question = new ConfirmationQuestion(
sprintf(
@@ -400,16 +375,28 @@ final class ManageCommand extends Command
})();
$output->writeln('');
- // -- $name.webhook.import
+ // -- $name.options.IMPORT_METADATA_ONLY
(function () use ($input, $output, &$u) {
- $chosen = (bool)ag($u, 'webhook.import', true);
+ if (true === (bool)ag($u, 'import.enabled')) {
+ return;
+ }
+
+ if (false === (bool)ag($u, 'export.enabled')) {
+ return;
+ }
+
+ $chosen = (bool)ag($u, 'options.' . Options::IMPORT_METADATA_ONLY, true);
$helper = $this->getHelper('question');
$text =
<<"Import" via webhooks for this backend? %s
- -----------------
- Do not forget to add the webhook end point to the backend if you enabled this option.
+ Enable Importing metadata ONLY from this backend? %s
+ ------------------
+ To efficiently export to this backend we need relation map and this require
+ us to get metadata from the backend. You have Importing disabled, as such this option
+ allow us to import this backend metadata without altering your play state.
+ ------------------
+ This option is SAFE and WILL NOT change your play state or add new items.
TEXT;
$question = new ConfirmationQuestion(
@@ -421,34 +408,7 @@ final class ManageCommand extends Command
);
$response = $helper->ask($input, $output, $question);
- $u = ag_set($u, 'webhook.import', (bool)$response);
- })();
- $output->writeln('');
-
- // -- $name.webhook.push
- (function () use ($input, $output, &$u) {
- $chosen = (bool)ag($u, 'webhook.push', true);
-
- $helper = $this->getHelper('question');
- $text =
- <<"Push" to this backend on received webhooks events? %s
- -----------------
- The way push works is to queue watched state and then push them to the backend.
- -----------------
- This approach has both strength and limitations, please refer to docs for more info on webhooks.
- TEXT;
-
- $question = new ConfirmationQuestion(
- sprintf(
- $text . PHP_EOL . '> ',
- '[Y|N] [Default: ' . ($chosen ? 'Yes' : 'No') . ']',
- ),
- $chosen
- );
-
- $response = $helper->ask($input, $output, $question);
- $u = ag_set($u, 'webhook.push', (bool)$response);
+ $u = ag_set($u, 'options.' . Options::IMPORT_METADATA_ONLY, (bool)$response);
})();
$output->writeln('');
@@ -459,9 +419,10 @@ final class ManageCommand extends Command
$helper = $this->getHelper('question');
$text =
<<scope this backend webhook events to the specified user? %s
+ Limit backend webhook events to the selected user? %s
------------------
- Helpful for Plex multi user/servers setup.
+ Helpful for Plex multi user/servers setup.
+ Lead sometimes to missed events for jellyfin itemAdd events. You should scope the token at jellyfin level.
TEXT;
$question = new ConfirmationQuestion(
@@ -484,9 +445,9 @@ final class ManageCommand extends Command
$helper = $this->getHelper('question');
$text =
<<scope this backend webhook events to the specified backend unique id? %s
+ Limit backend webhook events to the selected backend unique id? %s
------------------
- Helpful for Plex multi user/servers setup.
+ Helpful for Plex multi user/servers setup.
TEXT;
$question = new ConfirmationQuestion(
@@ -502,26 +463,23 @@ final class ManageCommand extends Command
})();
$output->writeln('');
- // -- $name.webhook.token
- (function () use ($output, &$u, $name) {
- $cond = true === ag($u, 'webhook.import') && null === ag($u, 'webhook.token');
-
- if (true === $cond) {
- try {
- $apiToken = bin2hex(random_bytes(Config::get('webhook.tokenLength')));
-
- $output->writeln(
- sprintf('The API key for \'%s\' webhook endpoint is: %s', $name, $apiToken)
- );
-
- $u = ag_set($u, 'webhook.token', $apiToken);
- } catch (Throwable $e) {
- $output->writeln(sprintf('%s', $e->getMessage()));
- exit(self::FAILURE);
- }
+ if (null === ag($u, 'webhook.token')) {
+ try {
+ $u = ag_set($u, 'webhook.token', bin2hex(random_bytes(Config::get('webhook.tokenLength'))));
+ } catch (Throwable $e) {
+ $output->writeln(
+ sprintf('Generating webhook api token has failed. %s', $e->getMessage())
+ );
+ return self::FAILURE;
}
- })();
- $output->writeln('');
+ }
+
+ // -- sanity check in case user has both import.enabled and options.IMPORT_METADATA_ONLY enabled.
+ if (true === (bool)ag($u, 'import.enabled')) {
+ if (true === ag_exists($u, 'options.' . Options::IMPORT_METADATA_ONLY)) {
+ $u = ag_delete($u, 'options.' . Options::IMPORT_METADATA_ONLY);
+ }
+ }
$output->writeln('-----------');
$output->writeln('');