feat: add SSH login information and dotfiles status check to hello.py; include OpenSSH server tasks in Ansible configuration
Some checks failed
Nix Format Check / check-format (push) Failing after 39s
Some checks failed
Nix Format Check / check-format (push) Failing after 39s
This commit is contained in:
@@ -2,11 +2,129 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
# Import helper functions
|
||||
sys.path.append(os.path.join(os.path.expanduser("~/.dotfiles"), "bin"))
|
||||
from helpers.functions import printfe, logo, _rainbow_color
|
||||
|
||||
def get_last_ssh_login():
|
||||
"""Get information about the last SSH login"""
|
||||
try:
|
||||
# Using lastlog to get the last login information
|
||||
result = subprocess.run(['lastlog2', '-u', os.environ.get("USER", "")],
|
||||
capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
lines = result.stdout.strip().split('\n')
|
||||
if len(lines) >= 2: # Header line + data line
|
||||
# Parse the last login line for SSH connections
|
||||
parts = lines[1].split()
|
||||
if len(parts) >= 7 and 'ssh' in ' '.join(parts).lower():
|
||||
time_str = ' '.join(parts[3:6])
|
||||
ip = parts[-1]
|
||||
return f"Last SSH login: {time_str} from {ip}"
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def check_dotfiles_status():
|
||||
"""Check if the dotfiles repository is dirty"""
|
||||
dotfiles_path = os.environ.get("DOTFILES_PATH", os.path.expanduser("~/.dotfiles"))
|
||||
try:
|
||||
if not os.path.isdir(os.path.join(dotfiles_path, ".git")):
|
||||
return None
|
||||
|
||||
# Check for git status details
|
||||
status = {
|
||||
'is_dirty': False,
|
||||
'untracked': 0,
|
||||
'modified': 0,
|
||||
'staged': 0,
|
||||
'commit_hash': '',
|
||||
'unpushed': 0
|
||||
}
|
||||
|
||||
# Get status of files
|
||||
result = subprocess.run(['git', 'status', '--porcelain'],
|
||||
cwd=dotfiles_path,
|
||||
capture_output=True, text=True)
|
||||
|
||||
if result.stdout.strip():
|
||||
status['is_dirty'] = True
|
||||
for line in result.stdout.splitlines():
|
||||
if line.startswith('??'):
|
||||
status['untracked'] += 1
|
||||
if line.startswith(' M') or line.startswith('MM'):
|
||||
status['modified'] += 1
|
||||
if line.startswith('M ') or line.startswith('A '):
|
||||
status['staged'] += 1
|
||||
|
||||
# Get current commit hash
|
||||
result = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'],
|
||||
cwd=dotfiles_path,
|
||||
capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
status['commit_hash'] = result.stdout.strip()
|
||||
|
||||
# Count unpushed commits
|
||||
# Fix: Remove capture_output and set stdout explicitly
|
||||
result = subprocess.run(['git', 'log', '--oneline', '@{u}..'],
|
||||
cwd=dotfiles_path,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
text=True)
|
||||
if result.returncode == 0:
|
||||
status['unpushed'] = len(result.stdout.splitlines())
|
||||
|
||||
return status
|
||||
except Exception as e:
|
||||
print(f"Error checking dotfiles status: {str(e)}")
|
||||
return None
|
||||
|
||||
def get_condensed_status():
|
||||
"""Generate a condensed status line for trash and git status"""
|
||||
status_parts = []
|
||||
|
||||
# Define ANSI color codes
|
||||
RED = "\033[31m"
|
||||
YELLOW = "\033[33m"
|
||||
GREEN = "\033[32m"
|
||||
BLUE = "\033[34m"
|
||||
RESET = "\033[0m"
|
||||
|
||||
# Check trash status
|
||||
trash_path = os.path.expanduser("~/.local/share/Trash/files")
|
||||
try:
|
||||
if os.path.exists(trash_path):
|
||||
items = os.listdir(trash_path)
|
||||
count = len(items)
|
||||
if count > 0:
|
||||
status_parts.append(f"[!] {count} file(s) in trash")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Check dotfiles status
|
||||
dotfiles_status = check_dotfiles_status()
|
||||
if dotfiles_status is not None:
|
||||
if dotfiles_status['is_dirty']:
|
||||
status_parts.append(f"{YELLOW}dotfiles is dirty{RESET}")
|
||||
status_parts.append(f"{RED}[{dotfiles_status['untracked']}] untracked{RESET}")
|
||||
status_parts.append(f"{YELLOW}[{dotfiles_status['modified']}] modified{RESET}")
|
||||
status_parts.append(f"{GREEN}[{dotfiles_status['staged']}] staged{RESET}")
|
||||
|
||||
if dotfiles_status['commit_hash']:
|
||||
status_parts.append(f"[{BLUE}{dotfiles_status['commit_hash']}{RESET}]")
|
||||
|
||||
if dotfiles_status['unpushed'] > 0:
|
||||
status_parts.append(f"[!] You have {dotfiles_status['unpushed']} commit(s) to push")
|
||||
else:
|
||||
status_parts.append("Unable to check dotfiles status")
|
||||
|
||||
if status_parts:
|
||||
return " - ".join(status_parts)
|
||||
return None
|
||||
|
||||
def welcome():
|
||||
"""Display welcome message with hostname and username"""
|
||||
print()
|
||||
@@ -20,6 +138,16 @@ def welcome():
|
||||
print("\033[36m] as [", end="")
|
||||
print(_rainbow_color(username), end="")
|
||||
print("\033[36m]\033[0m")
|
||||
|
||||
# Display last SSH login info if available
|
||||
ssh_login = get_last_ssh_login()
|
||||
if ssh_login:
|
||||
print(f"\033[33m{ssh_login}\033[0m")
|
||||
|
||||
# Display condensed status line
|
||||
condensed_status = get_condensed_status()
|
||||
if condensed_status:
|
||||
print(f"\033[33m{condensed_status}\033[0m")
|
||||
|
||||
def main():
|
||||
logo(continue_after=True)
|
||||
|
Reference in New Issue
Block a user