dotfiles/bin/helpers/functions.py
2025-03-10 19:35:55 +01:00

124 lines
4.3 KiB
Python

#!/usr/bin/env python3
import os
import sys
import subprocess
import math
import random
try:
import pyfiglet
except ImportError:
pyfiglet = None
# Color codes for terminal output
COLORS = {
"black": "\033[0;30m",
"red": "\033[0;31m",
"green": "\033[0;32m",
"yellow": "\033[0;33m",
"blue": "\033[0;34m",
"purple": "\033[0;35m",
"cyan": "\033[0;36m",
"white": "\033[0;37m",
"reset": "\033[0m"
}
def printfe(color, message):
"""Print a formatted message with the specified color"""
color_code = COLORS.get(color.lower(), COLORS["reset"])
print(f"{color_code}{message}{COLORS['reset']}")
def println(message, color=None):
"""Print a line with optional color"""
if color:
printfe(color, message)
else:
print(message)
def _rainbow_color(text, freq=0.1, offset=0):
"""Apply rainbow colors to text similar to lolcat"""
colored_text = ""
for i, char in enumerate(text):
if char.strip(): # Only color non-whitespace characters
# Calculate RGB values using sine waves with phase shifts
r = int(127 * math.sin(freq * i + offset + 0) + 128)
g = int(127 * math.sin(freq * i + offset + 2 * math.pi / 3) + 128)
b = int(127 * math.sin(freq * i + offset + 4 * math.pi / 3) + 128)
# Apply the RGB color to the character
colored_text += f"\033[38;2;{r};{g};{b}m{char}\033[0m"
else:
colored_text += char
return colored_text
def logo(continue_after=False):
"""Display the dotfiles logo"""
try:
# Try to read logo file first for backward compatibility
if pyfiglet:
# Generate ASCII art with pyfiglet and rainbow colors
ascii_art = pyfiglet.figlet_format("Menno's Dotfiles", font='slant')
print("\n") # Add some space before the logo
# Use a random offset to vary the rainbow start position
random_offset = random.random() * 2 * math.pi
line_offset = 0
for line in ascii_art.splitlines():
# Add a little variation to each line
print(_rainbow_color(line, offset=random_offset + line_offset))
line_offset += 0.1
else:
# Fallback if pyfiglet is not available
printfe("yellow", "\n *** Menno's Dotfiles ***\n")
printfe("cyan", " Note: Install pyfiglet for better logo display")
printfe("cyan", " (pip install pyfiglet)\n")
if not continue_after:
sys.exit(0)
except Exception as e:
printfe("red", f"Error displaying logo: {e}")
def run_command(command, shell=False):
"""Run a shell command and return the result"""
try:
result = subprocess.run(command, shell=shell, check=True, text=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return True, result.stdout.strip()
except subprocess.CalledProcessError as e:
return False, e.stderr.strip()
def ensure_dependencies():
"""Check and install required dependencies for the dotfiles system"""
required_packages = [
'pyfiglet', # For ASCII art generation
]
missing_packages = []
for package in required_packages:
try:
__import__(package)
except ImportError:
missing_packages.append(package)
if missing_packages:
printfe("yellow", f"Missing dependencies: {', '.join(missing_packages)}")
install = input("Would you like to install them now? (y/n): ").lower()
if install == 'y' or install == 'yes':
printfe("cyan", "Installing missing dependencies...")
for package in missing_packages:
printfe("blue", f"Installing {package}...")
success, output = run_command(['pip', 'install', '--user', package, '--break-system-packages'])
if success:
printfe("green", f"Successfully installed {package}")
else:
printfe("red", f"Failed to install {package}: {output}")
printfe("green", "All dependencies have been processed")
return True
else:
printfe("yellow", "Skipping dependency installation")
return False
return True