Added autocomplete for common options and argument values.
This commit is contained in:
21
FAQ.md
21
FAQ.md
@@ -202,17 +202,26 @@ $ docker exec -ti watchstate console servers:edit --key options.client.timeout -
|
||||
|
||||
### Q: Can I search my server remote libraries?
|
||||
|
||||
Yes, Run the following command
|
||||
Yes, you can search your backend media servers. You can use `--search '[searchTerm]'`
|
||||
or `--search-id [backend_media_id]`. For example, to search for specific title keyword run the following command:
|
||||
|
||||
```bash
|
||||
$ docker exec -ti console server servers:remote --search '[searchTerm]' -- [SERVER_NAME]
|
||||
$ docker exec -ti console server servers:remote --search 'Gundam' -- [SERVER_NAME]
|
||||
```
|
||||
|
||||
Flags:
|
||||
or if you want to get a specific item metadata run the following command:
|
||||
|
||||
* (required) `--search` Search query. For example, `GUNDAM`.
|
||||
* (optional) `--search-limit` To limit returned results. Defaults to `25`.
|
||||
* (optional) `--search-output` Set output style, it can be `yaml` or `json`. Defaults to `json`.
|
||||
```bash
|
||||
$ docker exec -ti console server servers:remote --search-id 2514 -- [SERVER_NAME]
|
||||
```
|
||||
|
||||
### Optional flags related to `--search` and `--search-id`
|
||||
|
||||
Those flags can be combined with the search parameter
|
||||
|
||||
* `--search-raw` Return unfiltered response.
|
||||
* `--search-limit` To limit returned results. Defaults to `25`.
|
||||
* `--search-output` Set output style, it can be `yaml` or `json`. Defaults to `json`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
19
config/servers.spec.php
Normal file
19
config/servers.spec.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name',
|
||||
'type',
|
||||
'url',
|
||||
'token',
|
||||
'uuid',
|
||||
'user',
|
||||
'import.enabled',
|
||||
'import.lastSync',
|
||||
'export.enabled',
|
||||
'export.lastSync',
|
||||
'webhook.import',
|
||||
'webhook.push',
|
||||
'webhook.match.user',
|
||||
'webhook.match.uuid',
|
||||
'webhook.token',
|
||||
];
|
||||
@@ -5,9 +5,12 @@ declare(strict_types=1);
|
||||
namespace App;
|
||||
|
||||
use App\Libs\Config;
|
||||
use DirectoryIterator;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Command\Command as BaseCommand;
|
||||
use Symfony\Component\Console\Command\LockableTrait;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Xhgui\Profiler\Profiler;
|
||||
@@ -130,4 +133,39 @@ class Command extends BaseCommand
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
if ($input->mustSuggestOptionValuesFor('config')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (new DirectoryIterator(getcwd()) as $name) {
|
||||
if (!$name->isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($currentValue) || str_starts_with($name->getFilename(), $currentValue)) {
|
||||
$suggest[] = $name->getFilename();
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('servers-filter') || $input->mustSuggestArgumentValuesFor('server')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (array_keys(Config::get('servers', [])) as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Commands\Database;
|
||||
|
||||
use App\Command;
|
||||
use App\Libs\Config;
|
||||
use App\Libs\Container;
|
||||
use App\Libs\Entity\StateInterface as iFace;
|
||||
use App\Libs\Guid;
|
||||
@@ -12,6 +13,8 @@ use App\Libs\Storage\StorageInterface;
|
||||
use Exception;
|
||||
use PDO;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Helper\TableSeparator;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@@ -313,4 +316,51 @@ final class ListCommand extends Command
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
parent::complete($input, $suggestions);
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('via') || $input->mustSuggestOptionValuesFor('metadata-as')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (array_keys(Config::get('servers', [])) as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('type')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach ([iFace::TYPE_MOVIE, iFace::TYPE_EPISODE] as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('output')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (['json', 'yaml', 'table'] as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace App\Commands\Servers;
|
||||
|
||||
use App\Command;
|
||||
use App\Libs\Config;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
@@ -23,14 +25,8 @@ final class EditCommand extends Command
|
||||
->addOption('key', 'k', InputOption::VALUE_REQUIRED, 'Key to update.')
|
||||
->addOption('set', 's', InputOption::VALUE_REQUIRED, 'Value to set.')
|
||||
->addOption('delete', 'd', InputOption::VALUE_NONE, 'Delete value.')
|
||||
->addOption(
|
||||
'regenerate-api-key',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Re-generate backend webhook token. *Not used. will be removed*'
|
||||
)
|
||||
->addOption('regenerate-webhook-token', 'g', InputOption::VALUE_NONE, 'Re-generate backend webhook token.')
|
||||
->addArgument('name', InputArgument::REQUIRED, 'Server name');
|
||||
->addArgument('server', InputArgument::REQUIRED, 'Backend name');
|
||||
}
|
||||
|
||||
protected function runCommand(InputInterface $input, OutputInterface $output, null|array $rerun = null): int
|
||||
@@ -55,7 +51,7 @@ final class EditCommand extends Command
|
||||
$servers = (array)Config::get('servers', []);
|
||||
}
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
$name = $input->getArgument('server');
|
||||
|
||||
if (!isValidName($name)) {
|
||||
$output->writeln(
|
||||
@@ -72,7 +68,7 @@ final class EditCommand extends Command
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
if ($input->getOption('regenerate-api-key') || $input->getOption('regenerate-webhook-token')) {
|
||||
if ($input->getOption('regenerate-webhook-token')) {
|
||||
try {
|
||||
$apiToken = bin2hex(random_bytes(Config::get('webhook.tokenLength')));
|
||||
|
||||
@@ -156,4 +152,22 @@ final class EditCommand extends Command
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
parent::complete($input, $suggestions);
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('key')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (require __DIR__ . '/../../../config/servers.spec.php' as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ final class ManageCommand extends Command
|
||||
->setDescription('Manage Server settings.')
|
||||
->addOption('add', 'a', InputOption::VALUE_NONE, 'Add Server')
|
||||
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
|
||||
->addArgument('name', InputArgument::REQUIRED, 'Server name');
|
||||
->addArgument('server', InputArgument::REQUIRED, 'Server name');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ final class ManageCommand extends Command
|
||||
}
|
||||
|
||||
$add = $input->getOption('add');
|
||||
$name = $input->getArgument('name');
|
||||
$name = $input->getArgument('server');
|
||||
|
||||
if (!isValidName($name)) {
|
||||
$output->writeln(
|
||||
@@ -549,5 +549,4 @@ final class ManageCommand extends Command
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@ final class RemoteCommand extends Command
|
||||
->addOption('list-users', null, InputOption::VALUE_NONE, 'List Server users.')
|
||||
->addOption('list-users-with-tokens', null, InputOption::VALUE_NONE, 'Show users list with tokens.')
|
||||
->addOption('use-token', null, InputOption::VALUE_REQUIRED, 'Override server config token.')
|
||||
->addOption('search', null, InputOption::VALUE_REQUIRED, 'Search query')
|
||||
->addOption('search-id', null, InputOption::VALUE_REQUIRED, 'Get metadata related to given id')
|
||||
->addOption('search', null, InputOption::VALUE_REQUIRED, 'Search query.')
|
||||
->addOption('search-id', null, InputOption::VALUE_REQUIRED, 'Get metadata related to given id.')
|
||||
->addOption('search-raw', null, InputOption::VALUE_NONE, 'Return Unfiltered results.')
|
||||
->addOption('search-limit', null, InputOption::VALUE_REQUIRED, 'Search limit', 25)
|
||||
->addOption('search-output', null, InputOption::VALUE_REQUIRED, 'Search output style [json,yaml]', 'json')
|
||||
->addOption('search-limit', null, InputOption::VALUE_REQUIRED, 'Search limit.', 25)
|
||||
->addOption('search-output', null, InputOption::VALUE_REQUIRED, 'Search output style [json,yaml].', 'json')
|
||||
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
|
||||
->addArgument('name', InputArgument::REQUIRED, 'Server name');
|
||||
->addArgument('server', InputArgument::REQUIRED, 'Server name');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ final class RemoteCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
$name = $input->getArgument('server');
|
||||
$ref = "servers.{$name}";
|
||||
|
||||
if (null === Config::get("{$ref}.type", null)) {
|
||||
@@ -213,6 +213,8 @@ final class RemoteCommand extends Command
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
parent::complete($input, $suggestions);
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('search-output')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
@@ -226,19 +228,5 @@ final class RemoteCommand extends Command
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
|
||||
if ($input->mustSuggestArgumentValuesFor('name')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (array_keys(Config::get('servers', [])) as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace App\Commands\Servers;
|
||||
|
||||
use App\Command;
|
||||
use App\Libs\Config;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
@@ -176,4 +178,23 @@ final class UnifyCommand extends Command
|
||||
$output->writeln(sprintf('<info>%s global webhook API key is: %s</info>', ucfirst($type), $apiToken));
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
parent::complete($input, $suggestions);
|
||||
|
||||
if ($input->mustSuggestArgumentValuesFor('type')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (array_keys(Config::get('supported', [])) as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ use App\Command;
|
||||
use App\Libs\Config;
|
||||
use Exception;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Helper\TableSeparator;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -33,7 +35,7 @@ final class ViewCommand extends Command
|
||||
->addArgument(
|
||||
'filter',
|
||||
InputArgument::OPTIONAL,
|
||||
'Can be any key from config, use dot notion to access sub keys, for example "webhook.token"'
|
||||
'Can be any key from servers.yaml, use dot notion to access sub keys, for example "webhook.token"'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -102,4 +104,23 @@ final class ViewCommand extends Command
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
parent::complete($input, $suggestions);
|
||||
|
||||
if ($input->mustSuggestArgumentValuesFor('filter')) {
|
||||
$currentValue = $input->getCompletionValue();
|
||||
|
||||
$suggest = [];
|
||||
|
||||
foreach (require __DIR__ . '/../../../config/servers.spec.php' as $name) {
|
||||
if (empty($currentValue) || str_starts_with($name, $currentValue)) {
|
||||
$suggest[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$suggestions->suggestValues($suggest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ final class MakeCommand extends Command
|
||||
{
|
||||
$this->setName('storage:make')
|
||||
->setDescription('Create storage backend migration.')
|
||||
->addArgument('name', InputArgument::REQUIRED, 'Migration name.');
|
||||
->addArgument('filename', InputArgument::REQUIRED, 'Migration name.');
|
||||
}
|
||||
|
||||
protected function runCommand(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$file = $this->storage->makeMigration($input->getArgument('name'));
|
||||
$file = $this->storage->makeMigration($input->getArgument('filename'));
|
||||
|
||||
$output->writeln(sprintf('<info>Created new migration at \'%s\'.</info>', $file));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user