cornsnake.util_proc

Running processes and opening Windows Explorer at a specified directory.

Documentation

  1"""
  2Running processes and opening Windows Explorer at a specified directory.
  3
  4[Documentation](http://docs.mrseanryan.cornsnake.s3-website-eu-west-1.amazonaws.com/cornsnake/util_proc.html)
  5"""
  6
  7import os
  8import subprocess
  9
 10from . import config
 11from . import util_log
 12from . import util_os
 13
 14logger = util_log.getLogger(__name__)
 15
 16
 17def _proc_print(message: str) -> None:
 18    """
 19    Logs the message using the logger and prints it if config.IS_VERBOSE is True.
 20
 21    Args:
 22    message (str): The message to log and possibly print.
 23    """
 24    logger.info(message)
 25    if config.IS_VERBOSE:
 26        print(message)
 27
 28
 29def _proc_print_debug(message: str) -> None:
 30    """
 31    Logs the message at debug level using the logger and prints it if config.IS_VERBOSE is True.
 32
 33    Args:
 34    message (str): The message to log and possibly print.
 35    """
 36    logger.debug(message)
 37    if config.IS_VERBOSE:
 38        print(message)
 39
 40
 41def is_process_running(process_name: str) -> bool:
 42    """
 43    Checks if the given process (identified by program filename) is running.
 44
 45    Args:
 46    process_name (str): The filename of the process. For example 'notepad.exe'.
 47    """
 48    if util_os.is_windows():
 49        progs = str(subprocess.check_output("tasklist"))
 50        return process_name in progs
 51    else:
 52        try:
 53            progs = str(subprocess.check_output(["pgrep", process_name]))
 54            return process_name in progs
 55        except subprocess.CalledProcessError:
 56            return False
 57
 58
 59def run_process_and_get_output(
 60    path_to_proc: str,
 61    arguments: list[str],
 62    working_directory: str,
 63    output_errors: bool = True,
 64    raise_if_str_error: bool = False,
 65) -> str:
 66    """
 67    Executes a process with specified arguments and working directory, capturing the output.
 68
 69    Args:
 70    path_to_proc (str): The path to the process to execute.
 71    arguments (list): List of arguments for the process.
 72    working_directory (str): The working directory for the process.
 73    output_errors (bool): Flag to print out errors. Default is True (but only if config.IS_VERBOSITY).
 74    raise_if_str_error (bool): Flag to raise an exception if stderr was a non-empty string (useful for programs that return 0 exit code, even though they populated stderr). Default is False.
 75
 76    Returns:
 77    str: The standard output of the process.
 78
 79    Raises:
 80    RuntimeError: If the process returns a non-zero exit code.
 81    """
 82    _proc_print_debug(
 83        f"EXECUTING: '{path_to_proc} {arguments}' - at {working_directory}"
 84    )
 85
 86    pipes = subprocess.Popen(
 87        [path_to_proc] + arguments,
 88        stdout=subprocess.PIPE,
 89        stderr=subprocess.PIPE,
 90        cwd=working_directory,
 91    )
 92    std_out, std_err = pipes.communicate()
 93
 94    std_out_str = ""
 95    if isinstance(std_out, str):
 96        std_out_str = std_out
 97    else:
 98        std_out_str = std_out.decode()
 99
100    std_err_str = ""
101    if isinstance(std_err, str):
102        std_err_str = std_err
103    else:
104        std_err_str = std_err.decode()
105
106    if pipes.returncode != 0:
107        # an error happened!
108        err_msg = f"{std_err_str.strip()}. Code: {pipes.returncode}"
109        if output_errors:
110            print(err_msg)
111        else:
112            logger.debug(err_msg)
113        raise RuntimeError(err_msg, pipes.returncode)
114    elif len(std_err_str):
115        # return code is 0 (no error), but we may want to
116        # do something with the info on std_err
117        if output_errors:
118            print(std_err_str)
119        else:
120            logger.debug(std_err_str)
121        if raise_if_str_error:
122            err_msg = f"{std_err_str.strip()}. Code: {pipes.returncode}"
123            raise RuntimeError(err_msg, pipes.returncode)
124
125    _proc_print_debug(f" >>> {std_out_str}")
126
127    return std_out_str
128
129
130def open_windows_explorer_at(path_to_dir: str) -> None:
131    """
132    Opens Windows Explorer or Mac Finder at the specified directory if the OS is Windows.
133
134    Args:
135    path_to_dir (str): The path to the directory to open in Windows Explorer.
136    """
137    if util_os.is_windows():
138        _proc_print(f"Opening Explorer at {path_to_dir}")
139        os.startfile(path_to_dir)
140        return
141    if util_os.is_mac():
142        _proc_print(f"Opening Finder at {path_to_dir}")
143        os.system(f"open {path_to_dir}")
144        return
145    else:
146        _proc_print(f"NOT opening {path_to_dir} - not Windows OS and not Mac")
logger = <Logger cornsnake.util_proc (DEBUG)>
def is_process_running(process_name: str) -> bool:
42def is_process_running(process_name: str) -> bool:
43    """
44    Checks if the given process (identified by program filename) is running.
45
46    Args:
47    process_name (str): The filename of the process. For example 'notepad.exe'.
48    """
49    if util_os.is_windows():
50        progs = str(subprocess.check_output("tasklist"))
51        return process_name in progs
52    else:
53        try:
54            progs = str(subprocess.check_output(["pgrep", process_name]))
55            return process_name in progs
56        except subprocess.CalledProcessError:
57            return False

Checks if the given process (identified by program filename) is running.

Args: process_name (str): The filename of the process. For example 'notepad.exe'.

def run_process_and_get_output( path_to_proc: str, arguments: list[str], working_directory: str, output_errors: bool = True, raise_if_str_error: bool = False) -> str:
 60def run_process_and_get_output(
 61    path_to_proc: str,
 62    arguments: list[str],
 63    working_directory: str,
 64    output_errors: bool = True,
 65    raise_if_str_error: bool = False,
 66) -> str:
 67    """
 68    Executes a process with specified arguments and working directory, capturing the output.
 69
 70    Args:
 71    path_to_proc (str): The path to the process to execute.
 72    arguments (list): List of arguments for the process.
 73    working_directory (str): The working directory for the process.
 74    output_errors (bool): Flag to print out errors. Default is True (but only if config.IS_VERBOSITY).
 75    raise_if_str_error (bool): Flag to raise an exception if stderr was a non-empty string (useful for programs that return 0 exit code, even though they populated stderr). Default is False.
 76
 77    Returns:
 78    str: The standard output of the process.
 79
 80    Raises:
 81    RuntimeError: If the process returns a non-zero exit code.
 82    """
 83    _proc_print_debug(
 84        f"EXECUTING: '{path_to_proc} {arguments}' - at {working_directory}"
 85    )
 86
 87    pipes = subprocess.Popen(
 88        [path_to_proc] + arguments,
 89        stdout=subprocess.PIPE,
 90        stderr=subprocess.PIPE,
 91        cwd=working_directory,
 92    )
 93    std_out, std_err = pipes.communicate()
 94
 95    std_out_str = ""
 96    if isinstance(std_out, str):
 97        std_out_str = std_out
 98    else:
 99        std_out_str = std_out.decode()
100
101    std_err_str = ""
102    if isinstance(std_err, str):
103        std_err_str = std_err
104    else:
105        std_err_str = std_err.decode()
106
107    if pipes.returncode != 0:
108        # an error happened!
109        err_msg = f"{std_err_str.strip()}. Code: {pipes.returncode}"
110        if output_errors:
111            print(err_msg)
112        else:
113            logger.debug(err_msg)
114        raise RuntimeError(err_msg, pipes.returncode)
115    elif len(std_err_str):
116        # return code is 0 (no error), but we may want to
117        # do something with the info on std_err
118        if output_errors:
119            print(std_err_str)
120        else:
121            logger.debug(std_err_str)
122        if raise_if_str_error:
123            err_msg = f"{std_err_str.strip()}. Code: {pipes.returncode}"
124            raise RuntimeError(err_msg, pipes.returncode)
125
126    _proc_print_debug(f" >>> {std_out_str}")
127
128    return std_out_str

Executes a process with specified arguments and working directory, capturing the output.

Args: path_to_proc (str): The path to the process to execute. arguments (list): List of arguments for the process. working_directory (str): The working directory for the process. output_errors (bool): Flag to print out errors. Default is True (but only if config.IS_VERBOSITY). raise_if_str_error (bool): Flag to raise an exception if stderr was a non-empty string (useful for programs that return 0 exit code, even though they populated stderr). Default is False.

Returns: str: The standard output of the process.

Raises: RuntimeError: If the process returns a non-zero exit code.

def open_windows_explorer_at(path_to_dir: str) -> None:
131def open_windows_explorer_at(path_to_dir: str) -> None:
132    """
133    Opens Windows Explorer or Mac Finder at the specified directory if the OS is Windows.
134
135    Args:
136    path_to_dir (str): The path to the directory to open in Windows Explorer.
137    """
138    if util_os.is_windows():
139        _proc_print(f"Opening Explorer at {path_to_dir}")
140        os.startfile(path_to_dir)
141        return
142    if util_os.is_mac():
143        _proc_print(f"Opening Finder at {path_to_dir}")
144        os.system(f"open {path_to_dir}")
145        return
146    else:
147        _proc_print(f"NOT opening {path_to_dir} - not Windows OS and not Mac")

Opens Windows Explorer or Mac Finder at the specified directory if the OS is Windows.

Args: path_to_dir (str): The path to the directory to open in Windows Explorer.