feat: improve AppImage discovery and extraction handling
This commit is contained in:
@@ -1,28 +1,108 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import yaml
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
|
||||||
# Apps directory
|
# Config path
|
||||||
apps_dir = Path.home() / "Apps"
|
config_dir = Path.home() / ".config" / "appimager"
|
||||||
|
config_file = config_dir / "config.yaml"
|
||||||
|
|
||||||
# Create the Apps directory if doesn't exists
|
# Default config
|
||||||
def ensure_apps_dir():
|
default_config = {"apps_dir": str(Path.home() / "Apps")}
|
||||||
if not apps_dir.exists():
|
|
||||||
apps_dir.mkdir(parents=True)
|
|
||||||
print(f"Created {apps_dir} directory.")
|
|
||||||
else:
|
|
||||||
print(f"{apps_dir} directory exists.")
|
|
||||||
|
|
||||||
# List AppImage files in the directory
|
# Create config directory and file if not exists
|
||||||
def list_appimage_files():
|
if not config_dir.exists():
|
||||||
appimage_files = [file.name for file in apps_dir.iterdir() if file.is_file() and file.suffix == ".AppImage"]
|
config_dir.mkdir(parents=True)
|
||||||
if appimage_files:
|
print(f"Created {config_dir} directory.")
|
||||||
print("AppImage files found:")
|
|
||||||
for app in appimage_files:
|
|
||||||
print(f" - {app}")
|
|
||||||
else:
|
|
||||||
print("No AppImage files found in ~/Apps directory.")
|
|
||||||
|
|
||||||
# Ensure the Apps directory exists
|
if not config_file.exists():
|
||||||
ensure_apps_dir()
|
with config_file.open("w") as file:
|
||||||
|
yaml.dump(default_config, file)
|
||||||
|
print(f"Created default config file at {config_file}.")
|
||||||
|
|
||||||
# List AppImage files
|
# Load config
|
||||||
list_appimage_files()
|
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