Skip to content

Instantly share code, notes, and snippets.

@SWORDIntel
Created May 11, 2025 10:36
Show Gist options
  • Save SWORDIntel/856bf0fb0951129ddd53dcbff0bd6583 to your computer and use it in GitHub Desktop.
Save SWORDIntel/856bf0fb0951129ddd53dcbff0bd6583 to your computer and use it in GitHub Desktop.
Intergrate an appimage interactively w/shortcut creation and perms
#!/usr/bin/env python3
import npyscreen
import os
import stat
import shutil
from pathlib import Path
import subprocess
import logging
from datetime import datetime
# Setup logging
logging.basicConfig(
filename=f'appimage_helper_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
class AppImageHelper:
def __init__(self):
self.home = Path.home()
self.programs_dir = self.home / "Programs"
self.desktop_dir = self.home / "Desktop"
self.local_apps_dir = self.home / ".local/share/applications"
self.local_icons_dir = self.home / ".local/share/icons/hicolor/256x256/apps"
def get_appimages(self):
"""Scan for AppImage files in the Programs directory."""
try:
return list(self.programs_dir.glob("*.AppImage"))
except Exception as e:
logging.error(f"Error scanning for AppImages: {e}")
return []
def extract_icon(self, appimage_path):
"""Extract icon from AppImage."""
try:
# Create temporary directory for extraction
temp_dir = Path("/tmp/appimage_icon_extract")
temp_dir.mkdir(exist_ok=True)
# Extract icon using AppImage's built-in mechanism
cmd = [str(appimage_path), "--appimage-extract", "*.png"]
subprocess.run(cmd, cwd=temp_dir, capture_output=True)
# Find the largest icon file
icons = list(temp_dir.rglob("*.png"))
if icons:
icon = max(icons, key=lambda x: os.path.getsize(x))
return icon
return None
except Exception as e:
logging.error(f"Error extracting icon: {e}")
return None
def create_desktop_entry(self, appimage_path, icon_path=None):
"""Create .desktop file for the AppImage."""
try:
app_name = appimage_path.stem
desktop_entry = f"""[Desktop Entry]
Name={app_name}
Exec={appimage_path}
Type=Application
Categories=Utility;
Terminal=false
"""
if icon_path:
desktop_entry += f"Icon={icon_path}\n"
# Create .desktop file in local applications directory
self.local_apps_dir.mkdir(parents=True, exist_ok=True)
desktop_file = self.local_apps_dir / f"{app_name.lower()}.desktop"
desktop_file.write_text(desktop_entry)
# Create symbolic link on desktop
desktop_shortcut = self.desktop_dir / f"{app_name.lower()}.desktop"
if desktop_shortcut.exists():
desktop_shortcut.unlink()
desktop_shortcut.symlink_to(desktop_file)
# Make desktop file executable
desktop_file.chmod(desktop_file.stat().st_mode | stat.S_IEXEC)
desktop_shortcut.chmod(desktop_shortcut.stat().st_mode | stat.S_IEXEC)
return True
except Exception as e:
logging.error(f"Error creating desktop entry: {e}")
return False
class AppImageSelector(npyscreen.NPSAppManaged):
def onStart(self):
self.helper = AppImageHelper()
self.addForm("MAIN", MainForm, name="AppImage Helper")
class MainForm(npyscreen.ActionForm):
def create(self):
self.appimages = self.parentApp.helper.get_appimages()
# Show instructions
self.add(npyscreen.TitleText, name="Select AppImage to integrate:", editable=False)
# Create selection widget
self.appimage_select = self.add(npyscreen.TitleSelectOne,
name="Available AppImages",
max_height=10,
values=[str(p.name) for p in self.appimages],
scroll_exit=True)
def on_ok(self):
if not self.appimage_select.value:
npyscreen.notify_confirm("Please select an AppImage file.", "Error")
return
selected_index = self.appimage_select.value[0]
appimage_path = self.appimages[selected_index]
# Make AppImage executable
try:
appimage_path.chmod(appimage_path.stat().st_mode | stat.S_IEXEC)
except Exception as e:
logging.error(f"Error making AppImage executable: {e}")
npyscreen.notify_confirm(f"Error making AppImage executable: {e}", "Error")
return
# Extract icon
icon_path = self.parentApp.helper.extract_icon(appimage_path)
if icon_path:
try:
# Copy icon to system location
self.parentApp.helper.local_icons_dir.mkdir(parents=True, exist_ok=True)
icon_dest = self.parentApp.helper.local_icons_dir / f"{appimage_path.stem}.png"
shutil.copy2(icon_path, icon_dest)
icon_path = icon_dest
except Exception as e:
logging.error(f"Error copying icon: {e}")
icon_path = None
# Create desktop entry
if self.parentApp.helper.create_desktop_entry(appimage_path, icon_path):
npyscreen.notify_confirm("AppImage successfully integrated!", "Success")
else:
npyscreen.notify_confirm("Error creating desktop entry.", "Error")
self.parentApp.switchForm(None)
def on_cancel(self):
self.parentApp.switchForm(None)
def main():
try:
app = AppImageSelector()
app.run()
except Exception as e:
logging.error(f"Application error: {e}")
print(f"Error: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment