Files
KDE-Display-Profiles/src/profile_manager.py
T
2026-01-23 18:50:07 -07:00

139 lines
5.0 KiB
Python

import os
import json
import subprocess
from datetime import datetime
from pathlib import Path
import uuid
class ProfileManager:
def __init__(self):
self.config_dir = Path.home() / ".local/share/plasma-display-profiles"
self.config_dir.mkdir(parents=True, exist_ok=True)
self.metadata_file = self.config_dir / "profiles.json"
self.script_path = self.find_script()
# Initialize metadata file if it doesn't exist
if not self.metadata_file.exists():
self.save_metadata([])
def find_script(self):
"""Find the bash script for display management"""
# Check common locations
possible_paths = [
Path(__file__).parent.parent / "scripts/display-script.sh",
Path.home() / "bin/display-script.sh",
Path("/usr/local/bin/display-script.sh"),
]
for path in possible_paths:
if path.exists():
return path
# For now, return None - we'll handle this gracefully
return None
def load_metadata(self):
"""Load profile metadata from JSON file"""
try:
with open(self.metadata_file, 'r') as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return []
def save_metadata(self, profiles):
"""Save profile metadata to JSON file"""
with open(self.metadata_file, 'w') as f:
json.dump(profiles, f, indent=2)
def list_profiles(self):
"""Return list of all profiles"""
return self.load_metadata()
def save_profile(self, name):
"""Save current display configuration as a new profile"""
profiles = self.load_metadata()
# Generate unique ID
profile_id = str(uuid.uuid4())
timestamp = datetime.now().isoformat()
# Create profile entry
profile = {
'id': profile_id,
'name': name,
'created': timestamp,
'modified': timestamp,
'script_file': f"{profile_id}.sh",
'shortcut': None
}
# TODO: Call bash script to save display configuration
# For now, create a placeholder script file
script_file = self.config_dir / profile['script_file']
script_file.write_text(f"#!/bin/bash\n# Display profile: {name}\n# Created: {timestamp}\n")
script_file.chmod(0o755)
# If script exists, call it
if self.script_path and self.script_path.exists():
try:
subprocess.run([str(self.script_path), 'save', str(script_file)],
check=True, capture_output=True)
except subprocess.CalledProcessError as e:
raise Exception(f"Script execution failed: {e.stderr.decode()}")
profiles.append(profile)
self.save_metadata(profiles)
def load_profile(self, profile_id):
"""Load a display profile"""
profiles = self.load_metadata()
profile = next((p for p in profiles if p['id'] == profile_id), None)
if not profile:
raise Exception(f"Profile not found: {profile_id}")
script_file = self.config_dir / profile['script_file']
if not script_file.exists():
raise Exception(f"Profile script not found: {script_file}")
# Execute the profile script
try:
if self.script_path and self.script_path.exists():
subprocess.run([str(self.script_path), 'load', str(script_file)],
check=True, capture_output=True)
else:
# Fallback: execute script directly
subprocess.run([str(script_file)], check=True, capture_output=True)
except subprocess.CalledProcessError as e:
raise Exception(f"Failed to load profile: {e.stderr.decode()}")
def delete_profile(self, profile_id):
"""Delete a profile"""
profiles = self.load_metadata()
profile = next((p for p in profiles if p['id'] == profile_id), None)
if not profile:
raise Exception(f"Profile not found: {profile_id}")
# Remove script file
script_file = self.config_dir / profile['script_file']
if script_file.exists():
script_file.unlink()
# Remove from metadata
profiles = [p for p in profiles if p['id'] != profile_id]
self.save_metadata(profiles)
def rename_profile(self, profile_id, new_name):
"""Rename a profile"""
profiles = self.load_metadata()
profile = next((p for p in profiles if p['id'] == profile_id), None)
if not profile:
raise Exception(f"Profile not found: {profile_id}")
profile['name'] = new_name
profile['modified'] = datetime.now().isoformat()
self.save_metadata(profiles)