BotZ/bot_z/cli.py

159 lines
3.5 KiB
Python

# -*- 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()