dashboard sync app

This commit is contained in:
Tim Bendt
2025-12-16 17:13:26 -05:00
parent 73079f743a
commit d7c82a0da0
25 changed files with 4181 additions and 69 deletions

352
src/utils/platform.py Normal file
View File

@@ -0,0 +1,352 @@
"""Cross-platform compatibility utilities."""
import os
import sys
import platform
import subprocess
from pathlib import Path
from typing import Optional, Dict, Any
def get_platform_info() -> Dict[str, str]:
"""Get platform information for compatibility checks."""
return {
"system": platform.system(),
"release": platform.release(),
"version": platform.version(),
"machine": platform.machine(),
"processor": platform.processor(),
"python_version": platform.python_version(),
"python_implementation": platform.python_implementation(),
}
def is_supported_platform() -> bool:
"""Check if the current platform is supported."""
system = platform.system()
python_version = tuple(map(int, platform.python_version().split(".")))
# Check Python version
if python_version < (3, 12):
return False
# Check operating system
supported_systems = ["Darwin", "Linux", "Windows"]
return system in supported_systems
def get_default_config_dir() -> Path:
"""Get platform-specific config directory."""
system = platform.system()
if system == "Darwin": # macOS
return Path.home() / "Library" / "Application Support" / "luk"
elif system == "Linux":
config_dir = os.environ.get("XDG_CONFIG_HOME")
if config_dir:
return Path(config_dir) / "luk"
return Path.home() / ".config" / "luk"
elif system == "Windows":
return Path(os.environ.get("APPDATA", "")) / "luk"
else:
# Fallback to ~/.config
return Path.home() / ".config" / "luk"
def get_default_data_dir() -> Path:
"""Get platform-specific data directory."""
system = platform.system()
if system == "Darwin": # macOS
return Path.home() / "Library" / "Application Support" / "luk"
elif system == "Linux":
data_dir = os.environ.get("XDG_DATA_HOME")
if data_dir:
return Path(data_dir) / "luk"
return Path.home() / ".local" / "share" / "luk"
elif system == "Windows":
return Path(os.environ.get("LOCALAPPDATA", "")) / "luk"
else:
# Fallback to ~/.local/share
return Path.home() / ".local" / "share" / "luk"
def get_default_log_dir() -> Path:
"""Get platform-specific log directory."""
system = platform.system()
if system == "Darwin": # macOS
return Path.home() / "Library" / "Logs" / "luk"
elif system == "Linux":
data_dir = os.environ.get("XDG_DATA_HOME")
if data_dir:
return Path(data_dir) / "luk" / "logs"
return Path.home() / ".local" / "share" / "luk" / "logs"
elif system == "Windows":
return Path(os.environ.get("LOCALAPPDATA", "")) / "luk" / "logs"
else:
# Fallback to ~/.local/share/logs
return Path.home() / ".local" / "share" / "luk" / "logs"
def get_default_maildir_path() -> Path:
"""Get platform-specific default Maildir path."""
system = platform.system()
if system == "Darwin": # macOS
return Path.home() / "Library" / "Mail"
elif system == "Linux":
return Path.home() / "Mail"
elif system == "Windows":
return Path.home() / "Mail"
else:
return Path.home() / "Mail"
def check_dependencies() -> Dict[str, bool]:
"""Check if required system dependencies are available."""
dependencies = {
"python": True, # We're running Python
"pip": False,
"git": False,
"curl": False,
"wget": False,
}
# Check for pip
try:
subprocess.run(["pip", "--version"], capture_output=True, check=True)
dependencies["pip"] = True
except (subprocess.CalledProcessError, FileNotFoundError):
pass
# Check for git
try:
subprocess.run(["git", "--version"], capture_output=True, check=True)
dependencies["git"] = True
except (subprocess.CalledProcessError, FileNotFoundError):
pass
# Check for curl
try:
subprocess.run(["curl", "--version"], capture_output=True, check=True)
dependencies["curl"] = True
except (subprocess.CalledProcessError, FileNotFoundError):
pass
# Check for wget
try:
subprocess.run(["wget", "--version"], capture_output=True, check=True)
dependencies["wget"] = True
except (subprocess.CalledProcessError, FileNotFoundError):
pass
return dependencies
def get_shell_info() -> Dict[str, str]:
"""Get shell information for completion setup."""
shell = os.environ.get("SHELL", "")
shell_name = Path(shell).name if shell else "unknown"
return {
"shell_path": shell,
"shell_name": shell_name,
"config_file": get_shell_config_file(shell_name),
}
def get_shell_config_file(shell_name: str) -> str:
"""Get the config file for a given shell."""
shell_configs = {
"bash": "~/.bashrc",
"zsh": "~/.zshrc",
"fish": "~/.config/fish/config.fish",
"ksh": "~/.kshrc",
"csh": "~/.cshrc",
"tcsh": "~/.tcshrc",
}
return shell_configs.get(shell_name, "~/.profile")
def setup_platform_specific() -> None:
"""Setup platform-specific configurations."""
system = platform.system()
if system == "Darwin":
setup_macos()
elif system == "Linux":
setup_linux()
elif system == "Windows":
setup_windows()
def setup_macos() -> None:
"""Setup macOS-specific configurations."""
# Ensure macOS-specific directories exist
config_dir = get_default_config_dir()
data_dir = get_default_data_dir()
log_dir = get_default_log_dir()
for directory in [config_dir, data_dir, log_dir]:
directory.mkdir(parents=True, exist_ok=True)
def setup_linux() -> None:
"""Setup Linux-specific configurations."""
# Ensure XDG directories exist
config_dir = get_default_config_dir()
data_dir = get_default_data_dir()
log_dir = get_default_log_dir()
for directory in [config_dir, data_dir, log_dir]:
directory.mkdir(parents=True, exist_ok=True)
def setup_windows() -> None:
"""Setup Windows-specific configurations."""
# Ensure Windows-specific directories exist
config_dir = get_default_config_dir()
data_dir = get_default_data_dir()
log_dir = get_default_log_dir()
for directory in [config_dir, data_dir, log_dir]:
directory.mkdir(parents=True, exist_ok=True)
def get_platform_specific_commands() -> Dict[str, str]:
"""Get platform-specific command equivalents."""
system = platform.system()
if system == "Darwin" or system == "Linux":
return {
"open": "open" if system == "Darwin" else "xdg-open",
"copy": "pbcopy" if system == "Darwin" else "xclip -selection clipboard",
"notify": "osascript -e 'display notification \"%s\"'"
if system == "Darwin"
else 'notify-send "%s"',
}
elif system == "Windows":
return {
"open": "start",
"copy": "clip",
"notify": "powershell -Command \"Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('%s')\"",
}
else:
return {}
def check_terminal_compatibility() -> Dict[str, bool]:
"""Check terminal compatibility for TUI features."""
return {
"color_support": sys.stdout.isatty(),
"unicode_support": True, # Most modern terminals support Unicode
"mouse_support": check_mouse_support(),
"textual_support": check_textual_support(),
}
def check_mouse_support() -> bool:
"""Check if terminal supports mouse events."""
# This is a basic check - actual mouse support depends on the terminal
return sys.stdout.isatty()
def check_textual_support() -> bool:
"""Check if Textual TUI framework can run."""
try:
import textual
return True
except ImportError:
return False
def get_platform_recommendations() -> list[str]:
"""Get platform-specific recommendations."""
system = platform.system()
recommendations = []
if system == "Darwin":
recommendations.extend(
[
"Install iTerm2 or Terminal.app for best TUI experience",
"Enable 'Terminal > Preferences > Profiles > Text > Unicode Normalization Form' set to 'None'",
"Consider using Homebrew for package management: brew install python3",
]
)
elif system == "Linux":
recommendations.extend(
[
"Use a modern terminal emulator like GNOME Terminal, Konsole, or Alacritty",
"Ensure UTF-8 locale is set: export LANG=en_US.UTF-8",
"Install system packages: sudo apt-get install python3-pip python3-venv",
]
)
elif system == "Windows":
recommendations.extend(
[
"Use Windows Terminal for best TUI experience",
"Enable UTF-8 support in Windows Terminal settings",
"Consider using WSL2 for better Unix compatibility",
"Install Python from python.org or Microsoft Store",
]
)
return recommendations
def validate_environment() -> Dict[str, Any]:
"""Validate the current environment for compatibility."""
platform_info = get_platform_info()
dependencies = check_dependencies()
terminal_compat = check_terminal_compatibility()
return {
"platform_supported": is_supported_platform(),
"platform_info": platform_info,
"dependencies": dependencies,
"terminal_compatibility": terminal_compat,
"recommendations": get_platform_recommendations(),
"config_dir": str(get_default_config_dir()),
"data_dir": str(get_default_data_dir()),
"log_dir": str(get_default_log_dir()),
}
if __name__ == "__main__":
# Print environment validation
env_info = validate_environment()
print("Platform Compatibility Check")
print("=" * 40)
print(
f"Platform: {env_info['platform_info']['system']} {env_info['platform_info']['release']}"
)
print(
f"Python: {env_info['platform_info']['python_version']} ({env_info['platform_info']['python_implementation']})"
)
print(f"Supported: {'' if env_info['platform_supported'] else ''}")
print()
print("Dependencies:")
for dep, available in env_info["dependencies"].items():
print(f" {dep}: {'' if available else ''}")
print()
print("Terminal Compatibility:")
for feature, supported in env_info["terminal_compatibility"].items():
print(f" {feature}: {'' if supported else ''}")
print()
print("Directories:")
print(f" Config: {env_info['config_dir']}")
print(f" Data: {env_info['data_dir']}")
print(f" Logs: {env_info['log_dir']}")
print()
if env_info["recommendations"]:
print("Recommendations:")
for rec in env_info["recommendations"]:
print(f"{rec}")