feat: improve AppImage discovery and extraction handling
This commit is contained in:
@@ -1,28 +1,108 @@
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
# Apps directory
|
||||
apps_dir = Path.home() / "Apps"
|
||||
# Config path
|
||||
config_dir = Path.home() / ".config" / "appimager"
|
||||
config_file = config_dir / "config.yaml"
|
||||
|
||||
# Create the Apps directory if doesn't exists
|
||||
def ensure_apps_dir():
|
||||
if not apps_dir.exists():
|
||||
apps_dir.mkdir(parents=True)
|
||||
print(f"Created {apps_dir} directory.")
|
||||
else:
|
||||
print(f"{apps_dir} directory exists.")
|
||||
# Default config
|
||||
default_config = {"apps_dir": str(Path.home() / "Apps")}
|
||||
|
||||
# List AppImage files in the directory
|
||||
def list_appimage_files():
|
||||
appimage_files = [file.name for file in apps_dir.iterdir() if file.is_file() and file.suffix == ".AppImage"]
|
||||
if appimage_files:
|
||||
print("AppImage files found:")
|
||||
for app in appimage_files:
|
||||
print(f" - {app}")
|
||||
else:
|
||||
print("No AppImage files found in ~/Apps directory.")
|
||||
# Create config directory and file if not exists
|
||||
if not config_dir.exists():
|
||||
config_dir.mkdir(parents=True)
|
||||
print(f"Created {config_dir} directory.")
|
||||
|
||||
# Ensure the Apps directory exists
|
||||
ensure_apps_dir()
|
||||
if not config_file.exists():
|
||||
with config_file.open("w") as file:
|
||||
yaml.dump(default_config, file)
|
||||
print(f"Created default config file at {config_file}.")
|
||||
|
||||
# List AppImage files
|
||||
list_appimage_files()
|
||||
# Load config
|
||||
with config_file.open("r") as file:
|
||||
config = yaml.safe_load(file)
|
||||
print(f"Loaded config: {config}")
|
||||
|
||||
# Get apps_dir from config
|
||||
apps_dir = Path(config.get("apps_dir", str(Path.home() / "Apps")))
|
||||
|
||||
# Create Apps directory if not exists
|
||||
if not apps_dir.exists():
|
||||
apps_dir.mkdir(parents=True)
|
||||
print(f"Created {apps_dir} directory.")
|
||||
else:
|
||||
print(f"{apps_dir} directory exists.")
|
||||
|
||||
# Path to the directory where .desktop files will be stored
|
||||
desktop_files_dir = Path.home() / ".local" / "share" / "applications"
|
||||
if not desktop_files_dir.exists():
|
||||
desktop_files_dir.mkdir(parents=True)
|
||||
print(f"Created {desktop_files_dir} directory.")
|
||||
|
||||
# Extract icon from AppImage
|
||||
def extract_icon(appimage_path):
|
||||
app_name = appimage_path.stem
|
||||
extract_dir = Path.home() / f".appimagetool_{app_name}"
|
||||
|
||||
# Extract AppImage content
|
||||
try:
|
||||
subprocess.run([str(appimage_path), "--appimage-extract"], check=True, stdout=subprocess.DEVNULL)
|
||||
extracted_dir = Path(".") / "squashfs-root"
|
||||
icon_path = None
|
||||
|
||||
# Search for an icon file in common directories
|
||||
for icon_dir in ["usr/share/icons", "usr/share/pixmaps"]:
|
||||
icon_candidates = list(extracted_dir.glob(f"{icon_dir}/**/*.png")) + list(extracted_dir.glob(f"{icon_dir}/**/*.svg"))
|
||||
if icon_candidates:
|
||||
icon_path = icon_candidates[0] # Use the first found icon
|
||||
break
|
||||
|
||||
if icon_path:
|
||||
# Copy icon to .local/share/icons
|
||||
target_icon_path = Path.home() / ".local" / "share" / "icons" / f"{app_name}{icon_path.suffix}"
|
||||
shutil.copy(icon_path, target_icon_path)
|
||||
print(f"Extracted icon for {app_name}: {target_icon_path}")
|
||||
return target_icon_path
|
||||
else:
|
||||
print(f"No icon found for {app_name}. Using default icon.")
|
||||
return "utilities-terminal" # Default icon
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error extracting AppImage: {e}")
|
||||
return "utilities-terminal" # Default icon
|
||||
finally:
|
||||
# Clean up extracted files
|
||||
if extracted_dir.exists():
|
||||
shutil.rmtree(extracted_dir)
|
||||
|
||||
# Function to create a .desktop file
|
||||
def create_desktop_file(appimage_path):
|
||||
# Ensure the AppImage fie is executable
|
||||
if not os.access(appimage_path, os.X_OK):
|
||||
os.chmod(appimage_path, 0o755)
|
||||
print(f"Set executable permission for: {appimage_path}.")
|
||||
app_name = appimage_path.stem # App name derived from filename
|
||||
desktop_file_content = f"""[Desktop Entry]
|
||||
Name={app_name}
|
||||
Exec={appimage_path}
|
||||
Icon=utilities-terminal
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
Terminal=false
|
||||
"""
|
||||
desktop_file_path = desktop_files_dir / f"{app_name}.desktop"
|
||||
with desktop_file_path.open("w") as desktop_file:
|
||||
desktop_file.write(desktop_file_content)
|
||||
os.chmod(desktop_file_path, 0o755) # Make the .desktop file executable
|
||||
print(f"Created .desktop file: {desktop_file_path}")
|
||||
|
||||
# List AppImage files in the Apps directory and create .desktop files
|
||||
appimage_files = [file for file in apps_dir.iterdir() if file.is_file() and file.suffix == ".AppImage"]
|
||||
if appimage_files:
|
||||
print("Creating .desktop files for AppImage files:")
|
||||
for app in appimage_files:
|
||||
create_desktop_file(app)
|
||||
else:
|
||||
print("No AppImage files found in ~/Apps directory.")
|
||||
|
||||
Reference in New Issue
Block a user