added support for multiple actions per .desktop file
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import os
|
import os
|
||||||
|
import configparser
|
||||||
|
|
||||||
class App:
|
class App:
|
||||||
def __init__(self, name: str, exec: str, icon: str = "", hidden: bool = False):
|
def __init__(self, name: str, exec: str, icon: str = "", hidden: bool = False):
|
||||||
@@ -27,33 +28,53 @@ def get_desktop_dirs():
|
|||||||
|
|
||||||
return [d for d in dirs if d.exists()]
|
return [d for d in dirs if d.exists()]
|
||||||
|
|
||||||
def parse_desktop_file(file_path: Path) -> App:
|
def parse_desktop_file(file_path: Path) -> list[App]:
|
||||||
app_data = {}
|
apps = []
|
||||||
with file_path.open() as f:
|
config = configparser.ConfigParser(interpolation=None)
|
||||||
for line in f:
|
|
||||||
if line.startswith("["):
|
|
||||||
continue
|
|
||||||
if "=" in line:
|
|
||||||
key, value = line.split("=", 1)
|
|
||||||
app_data[key] = value.strip().strip('"')
|
|
||||||
|
|
||||||
if "Name" in app_data:
|
try:
|
||||||
app_data["Name"] = app_data["Name"].strip().strip('"')
|
config.read(file_path, encoding='utf-8')
|
||||||
if "Icon" in app_data:
|
except Exception:
|
||||||
app_data["Icon"] = app_data["Icon"].strip().strip('"')
|
return []
|
||||||
if "Hidden" in app_data:
|
|
||||||
app_data["Hidden"] = app_data["Hidden"].strip().strip('"')
|
|
||||||
if "NoDisplay" in app_data:
|
|
||||||
app_data["Hidden"] = app_data["NoDisplay"].strip().strip('"')
|
|
||||||
|
|
||||||
app = App(
|
if 'Desktop Entry' not in config:
|
||||||
name=app_data.get("Name", ""),
|
return []
|
||||||
exec=app_data.get("Exec", ""),
|
|
||||||
icon=app_data.get("Icon", ""),
|
main_entry = config['Desktop Entry']
|
||||||
hidden=app_data.get("Hidden", "").lower() == "true"
|
main_name = main_entry.get('Name')
|
||||||
)
|
|
||||||
|
is_hidden = main_entry.get('Hidden', 'false').lower() == 'true' or \
|
||||||
|
main_entry.get('NoDisplay', 'false').lower() == 'true'
|
||||||
|
|
||||||
|
if main_name and not is_hidden:
|
||||||
|
main_exec = main_entry.get('Exec')
|
||||||
|
if main_exec:
|
||||||
|
apps.append(App(
|
||||||
|
name=main_name,
|
||||||
|
exec=main_exec,
|
||||||
|
icon=main_entry.get('Icon', ''),
|
||||||
|
hidden=False
|
||||||
|
))
|
||||||
|
|
||||||
|
if 'Actions' in main_entry:
|
||||||
|
action_ids = [action for action in main_entry['Actions'].split(';') if action]
|
||||||
|
for action_id in action_ids:
|
||||||
|
action_section_name = f'Desktop Action {action_id}'
|
||||||
|
if action_section_name in config:
|
||||||
|
action_section = config[action_section_name]
|
||||||
|
action_name = action_section.get('Name')
|
||||||
|
action_exec = action_section.get('Exec')
|
||||||
|
|
||||||
|
if action_name and action_exec:
|
||||||
|
combined_name = f"{main_name} - {action_name}"
|
||||||
|
apps.append(App(
|
||||||
|
name=combined_name,
|
||||||
|
exec=action_exec,
|
||||||
|
icon=main_entry.get('Icon', ''),
|
||||||
|
hidden=False
|
||||||
|
))
|
||||||
|
return apps
|
||||||
|
|
||||||
return app
|
|
||||||
|
|
||||||
def is_user_dir(path: Path) -> bool:
|
def is_user_dir(path: Path) -> bool:
|
||||||
path_str = str(path)
|
path_str = str(path)
|
||||||
@@ -67,9 +88,9 @@ def list_apps() -> list[App]:
|
|||||||
is_user = is_user_dir(desktop_dir)
|
is_user = is_user_dir(desktop_dir)
|
||||||
|
|
||||||
for file_path in desktop_dir.glob("*.desktop"):
|
for file_path in desktop_dir.glob("*.desktop"):
|
||||||
app = parse_desktop_file(file_path)
|
for app in parse_desktop_file(file_path):
|
||||||
|
|
||||||
if app.hidden or not app.name:
|
if app.hidden or not app.name or not app.exec:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if app.name in apps_dict:
|
if app.name in apps_dict:
|
||||||
@@ -82,9 +103,18 @@ def list_apps() -> list[App]:
|
|||||||
return [app for app, _ in apps_dict.values()]
|
return [app for app, _ in apps_dict.values()]
|
||||||
|
|
||||||
def launch(app: App):
|
def launch(app: App):
|
||||||
os.system(f"{app.exec}")
|
import subprocess
|
||||||
|
import shlex
|
||||||
|
|
||||||
|
cleaned_exec = app.exec.split(' %')[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.Popen(shlex.split(cleaned_exec))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to launch '{app.name}': {e}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
apps = list_apps()
|
apps = list_apps()
|
||||||
for app in apps:
|
for app in sorted(apps, key=lambda a: a.name):
|
||||||
print(app)
|
print(app)
|
||||||
Reference in New Issue
Block a user