def execute_auto(*args, **kwargs): """Execute a program, in foreground if on CLI, else in background.""" if CHECK.is_cli_frontend: p = Env.execute(*args, **kwargs) p.wait() else: p = Env.execute_disconnected(*args, **kwargs) return p
def execute_pipes(*args, **kwargs): """Execute a program without any file handles or signals or ... attached.""" return Env.execute(*args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, **kwargs)
def execute_disconnected(*args, **kwargs): """Execute a program without any file handles or signals or ... attached.""" return Env.execute(*args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, start_new_session=True, **kwargs)
def _get_exe_path(s, full_path, glob): p = pathlib.Path(s) parts = p.parts if len(parts) > 1: yield from _get_exe_path_ext(p, full_path, glob) else: for c in Env.get("PATH", _paths): f = c / s yield from _get_exe_path_ext(f, full_path, glob)
def loop(): typ, adr = socket_info() with socket.socket(typ, socket.SOCK_STREAM) as sock: sock.bind(adr) Env.log(f"ht3.daemon: Listening on {adr}") sock.settimeout(0.5) sock.listen(0) while True: try: conn, addr = sock.accept() except socket.timeout: if _evt.is_set(): return else: try: handle_socket(conn, addr) except Exception: pass
def which(exe): p = pathlib.Path(exe) parts = p.parts if len(parts) > 1: if p.exists(): return p return None for c in Env.get("PATH", _paths): p = c / exe if p.exists(): return p return None
def load_history(): """Load the history from file, enforce Limit.""" global HISTORY limit = Env.get("HISTORY_LIMIT", 1000) with get_history_file().open("rt") as f: if limit is not None: HISTORY = [line.strip() for line in collections.deque(f, limit)] else: HISTORY = [line.strip() for line in f] if limit is not None: with get_history_file().open("wt") as f: for line in HISTORY: f.write(line + "\n")
def procio(*args, input=None, timeout=None, **kwargs): """Get ouput from a program.""" p = Env.execute(*args, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, **kwargs) out, err = p.communicate(input=input, timeout=timeout) if p.returncode != 0: raise ProcIOException("Non-zero return code", p.returncode, out, err, args) return out
def socket_info(): """Parse Address from DAEMON_ADDRESS as ipv4, ipv6 or socket * IPv4 Format must be like 127.0.0.1:4267 * IPv6 Format must be like [::1]:4267 * On Windows it must be one of the above * For a unix socket, it must be a path """ adr = Env.get("DAEMON_ADDRESS", None) if adr is None: if hasattr(socket, "AF_UNIX"): adr = os.path.expanduser("~/.config/ht3/socket") typ = socket.AF_UNIX else: adr = ("::1", 4267) typ = socket.AF_INET6 else: m = RE_INET6.match(adr) if m: typ = socket.AF_INET6 adr = tuple(m.groups()) else: m = RE_INET.match(adr) if m: typ = socket.AF_INET adr = tuple(m.groups()) else: if hasattr(socket, "AF_UNIX"): typ = socket.AF_UNIX adr = os.path.expanduser(adr) else: raise ValueError( "Misformed Address, should look like " "'127.0.0.1:4267' or '[::1]:4267'", adr, ) if typ is getattr(socket, "AF_UNIX", object()): if os.path.exists(adr): os.remove(adr) return typ, adr
def get_history_file(): p = Env.get("HISTORY", HISTORY_FILE_DEFAULT) p = pathlib.Path(p).expanduser() if not p.parent.exists(): p.parent.mkdir(parents=True) return p
import ht3 from ht3 import args from ht3.check import CHECK from ht3.command import * from ht3.complete import * from ht3.env import Env from ht3.lib import * from ht3.utils.dialog import * from ht3.utils.fake_input import * from ht3.utils.helpers import * from ht3.utils.process import * if CHECK.os.windows: from ht3.utils.windows import * args.Python = args.Param(complete=lambda s: Env.complete_py(s), doc="PythonCode") args.Path = args.Param(convert=pathlib.Path, complete=lambda s: Env.complete_path(s), doc="Path") args.Executable = args.Param(complete=lambda s: Env.complete_executable(s), doc="Executable") args.Command = args.Param(complete=lambda s: Env.complete_commands(s), doc="Command") args.CommandWithArgs = args.Param( complete=lambda s: Env.complete_command_with_args(s), doc="CommandWithArgs") Env.update((k, v) for k, v in globals().items() if k[0] != "_")