184 lines
5.6 KiB
Python
Executable File
184 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Check if all script dependencies are available.
|
|
Does not go into venvs, dependencies need to be installed globally.
|
|
Prints a list of which commands can be run and which can't.
|
|
Basic binaries such as gnu coreutils are expected and not checked for.
|
|
"""
|
|
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import configparser
|
|
from pathlib import Path
|
|
from typing import Dict, List, Tuple
|
|
import importlib
|
|
|
|
CHECK = "✅"
|
|
CROSS = "❌"
|
|
|
|
def check_command(cmd: str) -> Tuple[bool, str|None]:
|
|
if shutil.which(cmd) is not None:
|
|
return (True, None)
|
|
else:
|
|
return (False, f"Command '{cmd}' not found")
|
|
|
|
def check_env_var(var: str) -> Tuple[bool, str|None]:
|
|
if var in os.environ:
|
|
return (True, None)
|
|
else:
|
|
return (False, f"Environment variable '{var}' not set")
|
|
|
|
def check_python_lib(lib: str) -> Tuple[bool, str|None]:
|
|
try:
|
|
importlib.import_module(lib)
|
|
return (True, None)
|
|
except ImportError:
|
|
return (False, f"Python library '{lib}' not found")
|
|
|
|
def check_stats_commands() -> List[Tuple[bool, str]]:
|
|
"""
|
|
Checks if all the commands that are configured for the stats daemon
|
|
can be executed.
|
|
"""
|
|
results = []
|
|
config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
|
|
config_path = Path(config_home) / "stats/config.ini"
|
|
|
|
if not config_path.exists():
|
|
return [(False, f"Stats config not found at {config_path}")]
|
|
|
|
config = configparser.ConfigParser(interpolation=None)
|
|
config.read(config_path)
|
|
|
|
for section in config.sections():
|
|
if section.startswith('stat.'):
|
|
cmd = config[section]['command']
|
|
try:
|
|
subprocess.run(cmd, shell=True, capture_output=True, check=True)
|
|
results.append((True, None))
|
|
except subprocess.CalledProcessError:
|
|
results.append((False, f"Command '{cmd}' failed to run"))
|
|
|
|
return results
|
|
|
|
def check_scripts() -> Dict[str, List[Tuple[bool, str|None]]]:
|
|
"""Run all checks for each script."""
|
|
checks = {
|
|
"check": [
|
|
check_command("python3"),
|
|
check_command("git"),
|
|
check_command("sudo"),
|
|
check_command("man"),
|
|
],
|
|
"e-ink": [
|
|
check_command("python3"),
|
|
check_python_lib("PIL"),
|
|
],
|
|
"indeel": [
|
|
check_command("file"),
|
|
check_command("magick"),
|
|
check_command("dctfilename"),
|
|
check_command("webpmux"),
|
|
check_command("gifski"),
|
|
],
|
|
"mover": [],
|
|
"pushover": [
|
|
check_env_var("PUSHOVER_APP_TOKEN"),
|
|
check_env_var("PUSHOVER_USER_TOKEN"),
|
|
check_command("curl"),
|
|
check_python_lib("requests"),
|
|
],
|
|
"stats": [
|
|
check_command("python3"),
|
|
check_command("sensors"),
|
|
check_command("jq"),
|
|
check_command("top"),
|
|
check_command("free"),
|
|
check_command("df"),
|
|
check_python_lib("configparser"),
|
|
check_python_lib("http"),
|
|
*check_stats_commands(),
|
|
],
|
|
"stats-collector": [
|
|
check_command("python3"),
|
|
check_python_lib("sqlalchemy"),
|
|
check_python_lib("requests"),
|
|
],
|
|
"syncwall": [
|
|
check_command("wget"),
|
|
check_command("wal"),
|
|
],
|
|
"tclean": [
|
|
check_command("python3"),
|
|
check_command("transmission-remote"),
|
|
check_python_lib("argparse"),
|
|
check_python_lib("datetime"),
|
|
],
|
|
"vc": [
|
|
check_command("ffmpeg"),
|
|
check_command("yt-dlp"),
|
|
check_python_lib("argparse"),
|
|
],
|
|
"vcmp": [
|
|
check_command("ffmpeg"),
|
|
check_command("ffprobe"),
|
|
check_command("nice"),
|
|
check_python_lib("pathlib"),
|
|
check_python_lib("argparse"),
|
|
check_python_lib("logging"),
|
|
check_python_lib("tempfile"),
|
|
],
|
|
}
|
|
return checks
|
|
|
|
def check_git_updates() -> Tuple[bool, str|None]:
|
|
try:
|
|
script_dir = Path(__file__).parent.parent
|
|
if not (script_dir / '.git').exists():
|
|
return (False, "Not a git repository")
|
|
original_dir = os.getcwd()
|
|
os.chdir(script_dir)
|
|
|
|
try:
|
|
# git fetch
|
|
subprocess.run(['git', 'fetch'], check=True, capture_output=True)
|
|
|
|
# git status
|
|
result = subprocess.run(['git', 'status'], check=True, capture_output=True, text=True)
|
|
|
|
if "Your branch is up to date" in result.stdout:
|
|
return (True, None)
|
|
else:
|
|
return (False, result.stdout)
|
|
finally:
|
|
os.chdir(original_dir)
|
|
except subprocess.CalledProcessError as e:
|
|
return (False, f"Git command failed: {e}")
|
|
except Exception as e:
|
|
return (False, f"Error checking git status: {e}")
|
|
|
|
def main():
|
|
# First check git status
|
|
git_status, git_message = check_git_updates()
|
|
status = CHECK if git_status else CROSS
|
|
print(f"{status} Repository status")
|
|
if git_message:
|
|
print(f"\t{status} {git_message}")
|
|
print() # Empty line for separation
|
|
|
|
results = check_scripts()
|
|
|
|
for script, checks in results.items():
|
|
all_passed = all(result[0] for result in checks) if checks else True
|
|
status = CHECK if all_passed else CROSS
|
|
print(f"{status} {script}")
|
|
|
|
for passed, message in checks:
|
|
status = CHECK if passed else CROSS
|
|
if message:
|
|
print(f"\t{status} {message}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|