archivebox_server.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #!/usr/bin/env python3
  2. __package__ = 'archivebox.cli'
  3. __command__ = 'archivebox server'
  4. import sys
  5. import argparse
  6. from pathlib import Path
  7. from typing import Optional, List, IO
  8. from archivebox.misc.util import docstring
  9. from archivebox.config import DATA_DIR
  10. from archivebox.config.common import SERVER_CONFIG
  11. from archivebox.misc.logging_util import SmartFormatter, reject_stdin
  12. # @enforce_types
  13. def server(runserver_args: Optional[List[str]]=None,
  14. reload: bool=False,
  15. debug: bool=False,
  16. init: bool=False,
  17. quick_init: bool=False,
  18. createsuperuser: bool=False,
  19. daemonize: bool=False,
  20. out_dir: Path=DATA_DIR) -> None:
  21. """Run the ArchiveBox HTTP server"""
  22. from rich import print
  23. runserver_args = runserver_args or []
  24. if init:
  25. run_subcommand('init', stdin=None, pwd=out_dir)
  26. print()
  27. elif quick_init:
  28. run_subcommand('init', subcommand_args=['--quick'], stdin=None, pwd=out_dir)
  29. print()
  30. if createsuperuser:
  31. run_subcommand('manage', subcommand_args=['createsuperuser'], pwd=out_dir)
  32. print()
  33. check_data_folder()
  34. from django.core.management import call_command
  35. from django.contrib.auth.models import User
  36. if not User.objects.filter(is_superuser=True).exclude(username='system').exists():
  37. print()
  38. # print('[yellow][!] No admin accounts exist, you must create one to be able to log in to the Admin UI![/yellow]')
  39. print('[violet]Hint:[/violet] To create an [bold]admin username & password[/bold] for the [deep_sky_blue3][underline][link=http://{host}:{port}/admin]Admin UI[/link][/underline][/deep_sky_blue3], run:')
  40. print(' [green]archivebox manage createsuperuser[/green]')
  41. print()
  42. host = '127.0.0.1'
  43. port = '8000'
  44. try:
  45. host_and_port = [arg for arg in runserver_args if arg.replace('.', '').replace(':', '').isdigit()][0]
  46. if ':' in host_and_port:
  47. host, port = host_and_port.split(':')
  48. else:
  49. if '.' in host_and_port:
  50. host = host_and_port
  51. else:
  52. port = host_and_port
  53. except IndexError:
  54. pass
  55. print('[green][+] Starting ArchiveBox webserver...[/green]')
  56. print(f' [blink][green]>[/green][/blink] Starting ArchiveBox webserver on [deep_sky_blue4][link=http://{host}:{port}]http://{host}:{port}[/link][/deep_sky_blue4]')
  57. print(f' [green]>[/green] Log in to ArchiveBox Admin UI on [deep_sky_blue3][link=http://{host}:{port}/admin]http://{host}:{port}/admin[/link][/deep_sky_blue3]')
  58. print(' > Writing ArchiveBox error log to ./logs/errors.log')
  59. if SHELL_CONFIG.DEBUG:
  60. if not reload:
  61. runserver_args.append('--noreload') # '--insecure'
  62. call_command("runserver", *runserver_args)
  63. else:
  64. from workers.supervisord_util import start_server_workers
  65. print()
  66. start_server_workers(host=host, port=port, daemonize=False)
  67. print("\n[i][green][🟩] ArchiveBox server shut down gracefully.[/green][/i]")
  68. @docstring(server.__doc__)
  69. def main(args: Optional[List[str]]=None, stdin: Optional[IO]=None, pwd: Optional[str]=None) -> None:
  70. parser = argparse.ArgumentParser(
  71. prog=__command__,
  72. description=server.__doc__,
  73. add_help=True,
  74. formatter_class=SmartFormatter,
  75. )
  76. parser.add_argument(
  77. 'runserver_args',
  78. nargs='*',
  79. type=str,
  80. default=[SERVER_CONFIG.BIND_ADDR],
  81. help='Arguments to pass to Django runserver'
  82. )
  83. parser.add_argument(
  84. '--reload',
  85. action='store_true',
  86. help='Enable auto-reloading when code or templates change',
  87. )
  88. parser.add_argument(
  89. '--debug',
  90. action='store_true',
  91. help='Enable DEBUG=True mode with more verbose errors',
  92. )
  93. parser.add_argument(
  94. '--nothreading',
  95. action='store_true',
  96. help='Force runserver to run in single-threaded mode',
  97. )
  98. parser.add_argument(
  99. '--init',
  100. action='store_true',
  101. help='Run a full archivebox init/upgrade before starting the server',
  102. )
  103. parser.add_argument(
  104. '--quick-init', '-i',
  105. action='store_true',
  106. help='Run quick archivebox init/upgrade before starting the server',
  107. )
  108. parser.add_argument(
  109. '--createsuperuser',
  110. action='store_true',
  111. help='Run archivebox manage createsuperuser before starting the server',
  112. )
  113. parser.add_argument(
  114. '--daemonize',
  115. action='store_true',
  116. help='Run the server in the background as a daemon',
  117. )
  118. command = parser.parse_args(args or ())
  119. reject_stdin(__command__, stdin)
  120. server(
  121. runserver_args=command.runserver_args + (['--nothreading'] if command.nothreading else []),
  122. reload=command.reload,
  123. debug=command.debug,
  124. init=command.init,
  125. quick_init=command.quick_init,
  126. createsuperuser=command.createsuperuser,
  127. daemonize=command.daemonize,
  128. out_dir=Path(pwd) if pwd else DATA_DIR,
  129. )
  130. if __name__ == '__main__':
  131. main(args=sys.argv[1:], stdin=sys.stdin)