diff --git a/archivebox/cli/__init__.py b/archivebox/cli/__init__.py index c3cdc742..3527d63c 100644 --- a/archivebox/cli/__init__.py +++ b/archivebox/cli/__init__.py @@ -87,15 +87,18 @@ class ArchiveBoxGroup(click.Group): @click.group(cls=ArchiveBoxGroup, invoke_without_command=True) @click.option('--help', '-h', is_flag=True, help='Show help') -@click.version_option(version=VERSION, package_name='archivebox', message='%(version)s') +@click.version_option(VERSION, '-v', '--version', package_name='archivebox', message='%(version)s') @click.pass_context def cli(ctx, help=False): """ArchiveBox: The self-hosted internet archive""" + # if --help is passed or no subcommand is given, show custom help message if help or ctx.invoked_subcommand is None: ctx.invoke(ctx.command.get_command(ctx, 'help')) - if ctx.invoked_subcommand in ArchiveBoxGroup.archive_commands: + # if the subcommand is in the archive_commands dict and is not 'manage', + # then we need to set up the django environment and check that we're in a valid data folder + if ctx.invoked_subcommand in ArchiveBoxGroup.archive_commands and ctx.invoked_subcommand != 'manage': # print('SETUP DJANGO AND CHECK DATA FOLDER') from archivebox.config.django import setup_django from archivebox.misc.checks import check_data_folder diff --git a/archivebox/cli/archivebox_manage.py b/archivebox/cli/archivebox_manage.py index 63ff354b..0d367042 100644 --- a/archivebox/cli/archivebox_manage.py +++ b/archivebox/cli/archivebox_manage.py @@ -1,44 +1,33 @@ #!/usr/bin/env python3 __package__ = 'archivebox.cli' -__command__ = 'archivebox manage' -import sys -from pathlib import Path -from typing import Optional, List, IO - -from archivebox.misc.util import docstring -from archivebox.config import DATA_DIR +import rich_click as click +from archivebox.misc.util import docstring, enforce_types - -# @enforce_types -def manage(args: Optional[List[str]]=None, out_dir: Path=DATA_DIR) -> None: +@enforce_types +def manage(args: list[str] | None=None) -> None: """Run an ArchiveBox Django management command""" - check_data_folder() - from django.core.management import execute_from_command_line + from archivebox.config.common import SHELL_CONFIG + from archivebox.misc.logging import stderr - if (args and "createsuperuser" in args) and (IN_DOCKER and not SHELL_CONFIG.IS_TTY): + if (args and "createsuperuser" in args) and (SHELL_CONFIG.IN_DOCKER and not SHELL_CONFIG.IS_TTY): stderr('[!] Warning: you need to pass -it to use interactive commands in docker', color='lightyellow') stderr(' docker run -it archivebox manage {}'.format(' '.join(args or ['...'])), color='lightyellow') stderr('') - - # import ipdb; ipdb.set_trace() + from django.core.management import execute_from_command_line execute_from_command_line(['manage.py', *(args or ['help'])]) - - - +@click.command(add_help_option=False, context_settings=dict(ignore_unknown_options=True)) +@click.argument('args', nargs=-1) @docstring(manage.__doc__) -def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional[str]=None) -> None: - manage( - args=args, - out_dir=Path(pwd) if pwd else DATA_DIR, - ) +def main(args: list[str] | None=None) -> None: + manage(args=args) if __name__ == '__main__': - main(args=sys.argv[1:], stdin=sys.stdin) + main() diff --git a/archivebox/cli/archivebox_shell.py b/archivebox/cli/archivebox_shell.py index a7d90a51..d51e8aba 100644 --- a/archivebox/cli/archivebox_shell.py +++ b/archivebox/cli/archivebox_shell.py @@ -1,46 +1,27 @@ #!/usr/bin/env python3 __package__ = 'archivebox.cli' -__command__ = 'archivebox shell' -import sys -import argparse -from pathlib import Path -from typing import Optional, List, IO +from typing import Iterable + +import rich_click as click from archivebox.misc.util import docstring -from archivebox.config import DATA_DIR -from archivebox.misc.logging_util import SmartFormatter, reject_stdin - -#@enforce_types -def shell(out_dir: Path=DATA_DIR) -> None: +def shell(args: Iterable[str]=()) -> None: """Enter an interactive ArchiveBox Django shell""" - check_data_folder() - from django.core.management import call_command - call_command("shell_plus") - - + call_command("shell_plus", *args) +@click.command(add_help_option=False, context_settings=dict(ignore_unknown_options=True)) +@click.argument('args', nargs=-1) @docstring(shell.__doc__) -def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional[str]=None) -> None: - parser = argparse.ArgumentParser( - prog=__command__, - description=shell.__doc__, - add_help=True, - formatter_class=SmartFormatter, - ) - parser.parse_args(args or ()) - reject_stdin(__command__, stdin) - - shell( - out_dir=Path(pwd) if pwd else DATA_DIR, - ) - +def main(args: Iterable[str]=()) -> None: + shell(args=args) + if __name__ == '__main__': - main(args=sys.argv[1:], stdin=sys.stdin) + main() diff --git a/archivebox/core/settings.py b/archivebox/core/settings.py index 9e2ce6c5..8b95ed8e 100644 --- a/archivebox/core/settings.py +++ b/archivebox/core/settings.py @@ -223,39 +223,38 @@ MIGRATION_MODULES = {'signal_webhooks': None} # as much as I'd love this to be a UUID or ULID field, it's not supported yet as of Django 5.0 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +HUEY = { + "huey_class": "huey.SqliteHuey", + "filename": CONSTANTS.QUEUE_DATABASE_FILENAME, + "name": "commands", + "results": True, + "store_none": True, + "immediate": False, + "utc": True, + "consumer": { + "workers": 1, + "worker_type": "thread", + "initial_delay": 0.1, # Smallest polling interval, same as -d. + "backoff": 1.15, # Exponential backoff using this rate, -b. + "max_delay": 10.0, # Max possible polling interval, -m. + "scheduler_interval": 1, # Check schedule every second, -s. + "periodic": True, # Enable crontab feature. + "check_worker_health": True, # Enable worker health checks. + "health_check_interval": 1, # Check worker health every second. + }, +} -if not IS_GETTING_VERSION_OR_HELP: # dont create queue.sqlite3 file if we're just running to get --version or --help - HUEY = { - "huey_class": "huey.SqliteHuey", - "filename": CONSTANTS.QUEUE_DATABASE_FILENAME, - "name": "commands", - "results": True, - "store_none": True, - "immediate": False, - "utc": True, - "consumer": { - "workers": 1, - "worker_type": "thread", - "initial_delay": 0.1, # Smallest polling interval, same as -d. - "backoff": 1.15, # Exponential backoff using this rate, -b. - "max_delay": 10.0, # Max possible polling interval, -m. - "scheduler_interval": 1, # Check schedule every second, -s. - "periodic": True, # Enable crontab feature. - "check_worker_health": True, # Enable worker health checks. - "health_check_interval": 1, # Check worker health every second. - }, - } +# https://huey.readthedocs.io/en/latest/contrib.html#setting-things-up +# https://github.com/gaiacoop/django-huey +DJANGO_HUEY = { + "default": "commands", + "queues": { + HUEY["name"]: HUEY.copy(), + # more registered here at plugin import-time by BaseQueue.register() + **abx.as_dict(abx.pm.hook.get_DJANGO_HUEY_QUEUES(QUEUE_DATABASE_NAME=CONSTANTS.QUEUE_DATABASE_FILENAME)), + }, +} - # https://huey.readthedocs.io/en/latest/contrib.html#setting-things-up - # https://github.com/gaiacoop/django-huey - DJANGO_HUEY = { - "default": "commands", - "queues": { - HUEY["name"]: HUEY.copy(), - # more registered here at plugin import-time by BaseQueue.register() - **abx.as_dict(abx.pm.hook.get_DJANGO_HUEY_QUEUES(QUEUE_DATABASE_NAME=CONSTANTS.QUEUE_DATABASE_FILENAME)), - }, - } class HueyDBRouter: """