139 lines
5.0 KiB
Python
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) |