Files
Modus/modules/launcher/plugins/caffeine.py
T

127 lines
4.4 KiB
Python

"""
Caffeine plugin for the launcher.
Prevents system from going idle for a specified duration.
"""
import subprocess
import os
from typing import List
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf, GLib
from ..plugin_base import PluginBase
from ..result import Result
from fabric.widgets.label import Label
import utils.icons as icons
class CaffeinePlugin(PluginBase):
"""
Plugin for preventing system idle using the inhibit script.
"""
def __init__(self):
super().__init__()
self.display_name = "Caffeine"
self.description = "Prevent system from going idle"
self.inhibit_script = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), "utils", "inhibit.py")
# Predefined durations
self.durations = {
"30m": "30 minutes",
"1h": "1 hour",
"2h": "2 hours",
"4h": "4 hours",
"8h": "8 hours",
"indefinite": "Indefinitely",
"off": "Off"
}
def initialize(self):
"""Initialize the caffeine plugin."""
self.set_triggers(["caffeine", "caffeine "])
def cleanup(self):
"""Cleanup the caffeine plugin."""
pass
def _create_inhibit_action(self, duration: str):
"""Create an inhibit action that properly captures the duration."""
def action():
try:
# Run the script in the background without waiting
subprocess.Popen(
["python3", self.inhibit_script, duration],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True # Run in a new session to prevent hanging
)
except Exception as e:
print(f"Error starting inhibit script: {e}")
return action
def _is_valid_duration(self, query: str) -> bool:
"""Check if the query is a valid duration format."""
if query in self.durations:
return True
if query.isdigit():
return True
if query.endswith(('h', 'm', 's')) and query[:-1].replace('.', '').isdigit():
return True
return False
def _get_default_action(self, query: str):
"""Get the default action for a direct duration input."""
if self._is_valid_duration(query):
return self._create_inhibit_action(query)
return None
def query(self, query_string: str) -> List[Result]:
"""Search caffeine durations based on query."""
if not query_string.strip():
return []
query = query_string.lower().strip()
results = []
# Handle direct search entry (e.g., "caffeine 30m" or just "30m")
if query.startswith("caffeine "):
query = query[9:].strip() # Remove "caffeine " prefix
elif query in self.durations or (query.endswith(('h', 'm', 's')) and query[:-1].replace('.', '').isdigit()):
# If query is a valid duration without prefix, use it directly
pass
else:
return []
# Add custom duration option
if query.isdigit() or (query.endswith(('h', 'm', 's')) and query[:-1].replace('.', '').isdigit()):
result = Result(
title=f"Custom: {query}",
subtitle="Set custom duration",
icon_markup=icons.coffee,
action=self._create_inhibit_action(query),
relevance=1.0,
plugin_name=self.display_name,
data={"duration": query}
)
results.append(result)
# Add predefined durations
for duration, description in self.durations.items():
if query in duration or query in description.lower():
result = Result(
title=description,
subtitle=f"Prevent idle for {description.lower()}",
icon_markup=icons.coffee,
action=self._create_inhibit_action(duration),
relevance=0.9 if query == duration else 0.7,
plugin_name=self.display_name,
data={"duration": duration}
)
results.append(result)
# Set default action for direct duration input
if results:
results[0].default_action = self._get_default_action(query)
return results