| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #!/usr/bin/env python3
- __package__ = 'archivebox.cli'
- import sys
- import rich_click as click
- from rich import print
- from benedict import benedict
- from archivebox.misc.util import docstring, enforce_types
- from archivebox.misc.toml_util import CustomTOMLEncoder
- @enforce_types
- def config(*keys,
- get: bool=False,
- set: bool=False,
- search: bool=False,
- reset: bool=False,
- **kwargs) -> None:
- """Get and set your ArchiveBox project configuration values"""
- import archivebox
- from archivebox.misc.checks import check_data_folder
- from archivebox.misc.logging_util import printable_config
- from archivebox.config.collection import load_all_config, write_config_file, get_real_name
- check_data_folder()
- FLAT_CONFIG = archivebox.pm.hook.get_FLAT_CONFIG()
- CONFIGS = archivebox.pm.hook.get_CONFIGS()
-
- config_options: list[str] = list(kwargs.pop('key=value', []) or keys or [f'{key}={val}' for key, val in kwargs.items()])
- no_args = not (get or set or reset or config_options)
- matching_config = {}
- if search:
- if config_options:
- config_options = [get_real_name(key) for key in config_options]
- matching_config = {key: FLAT_CONFIG[key] for key in config_options if key in FLAT_CONFIG}
- for config_section in CONFIGS.values():
- aliases = getattr(config_section, 'aliases', {})
-
- for search_key in config_options:
- # search all aliases in the section
- for alias_key, key in aliases.items():
- if search_key.lower() in alias_key.lower():
- matching_config[key] = dict(config_section)[key]
-
- # search all keys and values in the section
- for existing_key, value in dict(config_section).items():
- if search_key.lower() in existing_key.lower() or search_key.lower() in str(value).lower():
- matching_config[existing_key] = value
-
- print(printable_config(matching_config))
- raise SystemExit(not matching_config)
- elif get or no_args:
- if config_options:
- config_options = [get_real_name(key) for key in config_options]
- matching_config = {key: FLAT_CONFIG[key] for key in config_options if key in FLAT_CONFIG}
- failed_config = [key for key in config_options if key not in FLAT_CONFIG]
- if failed_config:
- print('\n[red][X] These options failed to get[/red]')
- print(' {}'.format('\n '.join(config_options)))
- raise SystemExit(1)
- else:
- matching_config = FLAT_CONFIG
-
- for config_section in CONFIGS.values():
- if hasattr(config_section, 'toml_section_header'):
- print(f'[grey53]\\[{config_section.toml_section_header}][/grey53]')
- else:
- print('[grey53]\\[CONSTANTS] # (read-only)[/grey53]')
-
- kv_in_section = {key: val for key, val in dict(config_section).items() if key in matching_config}
- print(benedict(kv_in_section).to_toml(encoder=CustomTOMLEncoder()).strip().replace('\n\n', '\n'))
- print('[grey53]################################################################[/grey53]')
-
-
- raise SystemExit(not matching_config)
- elif set:
- new_config = {}
- failed_options = []
- for line in config_options:
- if line.startswith('#') or not line.strip():
- continue
- if '=' not in line:
- print('[red][X] Config KEY=VALUE must have an = sign in it[/red]')
- print(f' {line}')
- raise SystemExit(2)
- raw_key, val = line.split('=', 1)
- raw_key = raw_key.upper().strip()
- key = get_real_name(raw_key)
- if key != raw_key:
- print(f'[yellow][i] Note: The config option {raw_key} has been renamed to {key}, please use the new name going forwards.[/yellow]')
- if key in FLAT_CONFIG:
- new_config[key] = val.strip()
- else:
- failed_options.append(line)
- if new_config:
- before = FLAT_CONFIG
- matching_config = write_config_file(new_config)
- after = {**load_all_config(), **archivebox.pm.hook.get_FLAT_CONFIG()}
- print(printable_config(matching_config))
- side_effect_changes = {}
- for key, val in after.items():
- if key in FLAT_CONFIG and (str(before[key]) != str(after[key])) and (key not in matching_config):
- side_effect_changes[key] = after[key]
- if side_effect_changes:
- print(file=sys.stderr)
- print('[yellow][i] Note: This change also affected these other options that depended on it:[/yellow]', file=sys.stderr)
- print(' {}'.format(printable_config(side_effect_changes, prefix=' ')), file=sys.stderr)
- if failed_options:
- print()
- print('[red][X] These options failed to set (check for typos):[/red]')
- print(' {}'.format('\n '.join(failed_options)))
- raise SystemExit(1)
- elif reset:
- print('[red][X] This command is not implemented yet.[/red]')
- print(' Please manually remove the relevant lines from your config file:')
- raise SystemExit(2)
- else:
- print('[red][X] You must pass either --get or --set, or no arguments to get the whole config.[/red]')
- print(' archivebox config')
- print(' archivebox config --get SOME_KEY')
- print(' archivebox config --set SOME_KEY=SOME_VALUE')
- raise SystemExit(2)
- @click.command()
- @click.option('--search', is_flag=True, help='Search config KEYs, VALUEs, and ALIASES for the given term')
- @click.option('--get', is_flag=True, help='Get the value for the given config KEYs')
- @click.option('--set', is_flag=True, help='Set the given KEY=VALUE config values')
- @click.option('--reset', is_flag=True, help='Reset the given KEY config values to their defaults')
- @click.argument('KEY=VALUE', nargs=-1, type=str)
- @docstring(config.__doc__)
- def main(**kwargs) -> None:
- config(**kwargs)
- if __name__ == '__main__':
- main()
|