refactor(autostart): abstract backend implementation for autostart
This commit is contained in:
15
rewind/autostart/autostart_backend.py
Normal file
15
rewind/autostart/autostart_backend.py
Normal file
@@ -0,0 +1,15 @@
|
||||
class AutostartBackend:
|
||||
def __init__(self, program_path: str):
|
||||
self.program_path = program_path
|
||||
|
||||
def enable_autostart(self):
|
||||
raise NotImplementedError("enable_autostart not implemented for this platform")
|
||||
|
||||
def disable_autostart(self):
|
||||
raise NotImplementedError("disable_autostart not implemented for this platform")
|
||||
|
||||
def start_daemon(self):
|
||||
raise NotImplementedError("start_daemon not implemented for this platform")
|
||||
|
||||
def stop_daemon(self):
|
||||
raise NotImplementedError("stop_daemon not implemented for this platform")
|
||||
@@ -1,75 +1,80 @@
|
||||
import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
from rewind.autostart.autostart_backend import AutostartBackend
|
||||
|
||||
def _run(cmd: list[str]):
|
||||
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{result.stderr}")
|
||||
return result
|
||||
class LinuxBackend(AutostartBackend):
|
||||
def __init__(self, program_path: str):
|
||||
super().__init__(program_path)
|
||||
|
||||
def _create_systemd_service(program_path: str):
|
||||
systemd_dir = Path.home() / ".config/systemd/user"
|
||||
systemd_dir.mkdir(parents=True, exist_ok=True)
|
||||
def _run(self, cmd: list[str]):
|
||||
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{result.stderr}")
|
||||
return result
|
||||
|
||||
obs_service = systemd_dir / "obs.service"
|
||||
daemon_service = systemd_dir / "rewind-daemon.service"
|
||||
def _create_systemd_service(self):
|
||||
systemd_dir = Path.home() / ".config/systemd/user"
|
||||
systemd_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
obs_service.write_text("""[Unit]
|
||||
Description=OBS Studio
|
||||
After=graphical-session.target
|
||||
Wants=graphical-session.target
|
||||
obs_service = systemd_dir / "obs.service"
|
||||
daemon_service = systemd_dir / "rewind-daemon.service"
|
||||
|
||||
[Service]
|
||||
# Ensure OBS sentinel files are cleaned up before starting the daemon
|
||||
ExecStartPre=-/usr/bin/rm -rf %h/.config/obs-studio/.sentinel
|
||||
ExecStart=obs --minimize-to-tray
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
obs_service.write_text("""[Unit]
|
||||
Description=OBS Studio
|
||||
After=graphical-session.target
|
||||
Wants=graphical-session.target
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
""")
|
||||
[Service]
|
||||
# Ensure OBS sentinel files are cleaned up before starting the daemon
|
||||
ExecStartPre=-/usr/bin/rm -rf %h/.config/obs-studio/.sentinel
|
||||
ExecStart=obs --minimize-to-tray
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
|
||||
daemon_service.write_text(f"""[Unit]
|
||||
Description=Rewind Daemon
|
||||
After=obs.service
|
||||
Requires=obs.service
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
""")
|
||||
|
||||
[Service]
|
||||
ExecStart={program_path}
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
daemon_service.write_text(f"""[Unit]
|
||||
Description=Rewind Daemon
|
||||
After=obs.service
|
||||
Requires=obs.service
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
""")
|
||||
[Service]
|
||||
ExecStart={self.program_path}
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
def enable_autostart_linux(program_path: str):
|
||||
_create_systemd_service(program_path)
|
||||
_run(["systemctl", "--user", "daemon-reload"])
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
""")
|
||||
|
||||
_run(["systemctl", "--user", "enable", "obs.service"])
|
||||
_run(["systemctl", "--user", "enable", "rewind-daemon.service"])
|
||||
def enable_autostart(self):
|
||||
self._create_systemd_service()
|
||||
self._run(["systemctl", "--user", "daemon-reload"])
|
||||
|
||||
print("Installed OBS + rewind-daemon via systemd")
|
||||
self._run(["systemctl", "--user", "enable", "obs.service"])
|
||||
self._run(["systemctl", "--user", "enable", "rewind-daemon.service"])
|
||||
|
||||
def disable_autostart_linux(program_path: str):
|
||||
_create_systemd_service(program_path)
|
||||
_run(["systemctl", "--user", "disable", "rewind-daemon.service"])
|
||||
_run(["systemctl", "--user", "disable", "obs.service"])
|
||||
print("Installed OBS + rewind-daemon via systemd")
|
||||
|
||||
systemd_dir = Path.home() / ".config/systemd/user"
|
||||
(systemd_dir / "rewind-daemon.service").unlink(missing_ok=True)
|
||||
(systemd_dir / "obs.service").unlink(missing_ok=True)
|
||||
_run(["systemctl", "--user", "daemon-reload"])
|
||||
def disable_autostart(self):
|
||||
self._create_systemd_service()
|
||||
self._run(["systemctl", "--user", "disable", "rewind-daemon.service"])
|
||||
self._run(["systemctl", "--user", "disable", "obs.service"])
|
||||
|
||||
def start_daemon_linux(program_path: str):
|
||||
_create_systemd_service(program_path)
|
||||
_run(["systemctl", "--user", "start", "rewind-daemon.service"])
|
||||
systemd_dir = Path.home() / ".config/systemd/user"
|
||||
(systemd_dir / "rewind-daemon.service").unlink(missing_ok=True)
|
||||
(systemd_dir / "obs.service").unlink(missing_ok=True)
|
||||
self._run(["systemctl", "--user", "daemon-reload"])
|
||||
|
||||
def stop_daemon_linux(program_path: str):
|
||||
_create_systemd_service(program_path)
|
||||
_run(["systemctl", "--user", "stop", "rewind-daemon.service"])
|
||||
_run(["systemctl", "--user", "stop", "obs.service"])
|
||||
def start_daemon(self):
|
||||
self._create_systemd_service()
|
||||
self._run(["systemctl", "--user", "start", "rewind-daemon.service"])
|
||||
|
||||
def stop_daemon(self):
|
||||
self._create_systemd_service()
|
||||
self._run(["systemctl", "--user", "stop", "rewind-daemon.service"])
|
||||
self._run(["systemctl", "--user", "stop", "obs.service"])
|
||||
@@ -2,7 +2,7 @@
|
||||
import platform
|
||||
import shutil
|
||||
|
||||
import rewind.autostart.linux as linux_autostart
|
||||
from rewind.autostart.linux import LinuxBackend
|
||||
|
||||
APP_NAME = "rewind-daemon"
|
||||
|
||||
@@ -12,38 +12,26 @@ def _find_executable():
|
||||
raise RuntimeError(f"{APP_NAME} not found in PATH")
|
||||
return path
|
||||
|
||||
def enable_autostart():
|
||||
def _get_backend():
|
||||
system = platform.system()
|
||||
program_path = _find_executable()
|
||||
|
||||
if system == "Linux":
|
||||
linux_autostart.enable_autostart_linux(program_path)
|
||||
return LinuxBackend(program_path)
|
||||
else:
|
||||
raise RuntimeError(f"Autostart on OS {system} not compatible or not implemented")
|
||||
|
||||
def enable_autostart():
|
||||
backend = _get_backend()
|
||||
backend.enable_autostart()
|
||||
|
||||
def disable_autostart():
|
||||
system = platform.system()
|
||||
program_path = _find_executable()
|
||||
|
||||
if system == "Linux":
|
||||
linux_autostart.disable_autostart_linux(program_path)
|
||||
else:
|
||||
raise RuntimeError(f"Autostart on OS {system} not compatible or not implemented")
|
||||
backend = _get_backend()
|
||||
backend.disable_autostart()
|
||||
|
||||
def start_daemon():
|
||||
system = platform.system()
|
||||
program_path = _find_executable()
|
||||
|
||||
if system == "Linux":
|
||||
linux_autostart.start_daemon_linux(program_path)
|
||||
else:
|
||||
raise RuntimeError(f"Autostart on OS {system} not compatible or not implemented")
|
||||
backend = _get_backend()
|
||||
backend.start_daemon()
|
||||
|
||||
def stop_daemon():
|
||||
system = platform.system()
|
||||
program_path = _find_executable()
|
||||
|
||||
if system == "Linux":
|
||||
linux_autostart.stop_daemon_linux(program_path)
|
||||
else:
|
||||
raise RuntimeError(f"Autostart on OS {system} not compatible or not implemented")
|
||||
backend = _get_backend()
|
||||
backend.stop_daemon()
|
||||
@@ -16,7 +16,6 @@ from rewind.state import add_file_to_state, create_state_file_if_needed, cleanup
|
||||
running = True
|
||||
LOG_FILE = get_state_dir() / "daemon.log"
|
||||
INTERVAL = 10
|
||||
SENTINEL_FILE = os.path.expanduser("~/.config/obs-studio/.sentinel")
|
||||
OBS_MAX_RETRIES = 5
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
Reference in New Issue
Block a user