# -*- coding: utf-8 -*- """Console script to control the bot_z daemon""" import errno import os import time import typing as T import click import lockfile from bot_z.zdaemon import daemon_process, Fifo @click.group() @click.option("-d", "--debug", is_flag=True, default=False, help="Enable debug mode.") @click.option( "-f", "--fifo", type=click.Path(), default="/tmp/bot_z.cmd", help="Path to the control fifo.", ) @click.option( "-w", "--workdir", type=click.Path(exists=True, readable=True, writable=True, resolve_path=True), default="/tmp/", help="The working dir where to launch the daemon and where the lockfile is put.", ) @click.pass_context def cli(ctx: click.Context, debug: bool, fifo: str, workdir: str) -> None: """ Group cli. """ ctx.ensure_object(dict) ctx.obj["debug"] = debug ctx.obj["fifo"] = fifo ctx.obj["workdir"] = workdir @cli.command("start") @click.option( "-t", "--timeout", type=click.INT, default=20, help="Browser requests timeout." ) @click.option( "-m", "--umask", type=click.INT, default=0o002, help="The umask of the control fifo.", ) @click.option( "-n", "--name", type=click.STRING, default="default_instance", help="The daemon instance name.", ) @click.option( "-p", "--proxy", type=click.STRING, default=None, help="An optional string for the proxy with the form 'address:port'.", ) @click.option( "--foreground", is_flag=True, default=False, help="Keep the process in foreground (do not daemonize).", ) @click.argument("baseuri", type=click.STRING) @click.pass_context def start_command( ctx: click.Context, baseuri: str, name: str, umask: int, timeout: int, proxy: T.Optional[str] = None, foreground: bool = False, ) -> None: """ Invokes daemon_process for the first time. """ lf = lockfile.FileLock(os.path.join(ctx.obj["workdir"], "bot_z.lock")) proxy_tuple = None if proxy: proxy_tuple = tuple(proxy.split(":")) daemon_process( fifo_path=ctx.obj["fifo"], working_dir=ctx.obj["workdir"], umask=umask, pidfile=lf, base_uri=baseuri, name=name, timeout=timeout, proxy=proxy_tuple, headless=not ctx.obj["debug"], debug=ctx.obj["debug"], foreground=foreground, ) @cli.command("stop") @click.pass_context def stop_command(ctx: click.Context): """ Writes on the fifo. Invokes the stop. """ with open(ctx.obj["fifo"], "w") as fifo: fifo.write("stop") fifo.flush() @cli.command("reload") @click.pass_context def reload_command(ctx: click.Context): """ Writes on the fifo. Invokes the reload. """ with open(ctx.obj["fifo"], "w") as fifo: fifo.write("reload") fifo.flush() @cli.command("status") @click.pass_context def status_command(ctx: click.Context): """ Writes on the fifo. Queries the status. """ rfifo_path = os.path.join(ctx.obj["workdir"], "rfifo-{}".format(id(ctx))) try: os.mkfifo(rfifo_path) except OSError as err: if err.errno != errno.EEXIST: raise with Fifo(ctx.obj["fifo"], "w") as fifo: fifo.write("status|{}".format(rfifo_path)) done = False while not done: try: with open(rfifo_path, "r") as rfifo: resp = rfifo.read() done = True except FileNotFoundError as e: print(e) pass print(resp) if __name__ == "__main__": cli()