Skip to content

Commit

Permalink
added an option to copy or move appimage
Browse files Browse the repository at this point in the history
  • Loading branch information
mijorus committed May 29, 2023
1 parent e91a651 commit 84422de
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 81 deletions.
3 changes: 3 additions & 0 deletions data/it.mijorus.gearlever.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<schema id="it.mijorus.gearlever" path="/it/mijorus/gearlever/">
<key name="appimages-default-folder" type="s">
<default>"~/AppImages"</default>
</key>
<key name="move-appimage-on-integration" type="b">
<default>true</default>
</key>
</schema>
</schemalist>
49 changes: 43 additions & 6 deletions src/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,55 @@ def __init__(self, **kwargs) :
page1 = Adw.PreferencesPage()

# general group
general_preference_group = Adw.PreferencesGroup(name=_( 'General'))
general_preference_group = Adw.PreferencesGroup(name=_('General'))


# default_localtion
self.default_localtion_row = Adw.ActionRow(
# default_location
self.default_location_row = Adw.ActionRow(
title=_('AppImage location'),
subtitle=self.settings.get_string('appimages-default-folder')
)

pick_default_localtion_btn = Gtk.Button(icon_name='gearlever-file-manager-symbolic', valign=Gtk.Align.CENTER)
pick_default_localtion_btn.connect('clicked', self.on_default_localtion_btn_clicked)
self.default_localtion_row.add_suffix(pick_default_localtion_btn)
general_preference_group.add(self.default_localtion_row)
self.default_location_row.add_suffix(pick_default_localtion_btn)
general_preference_group.add(self.default_location_row)

# move appimage on integration
move_appimages_group = Adw.PreferencesGroup(name=_('File management'), title=_('File management'))
move_appimages_row = Adw.ActionRow(
title=_('Move AppImages into the destination folder'),
subtitle=(_('Default behaviour'))
)

copy_appimages_row = Adw.ActionRow(
title=_('Clone AppImages into the destination folder'),
subtitle=(_('This option keeps the original file but doubles the disk usage'))
)


self.move_to_destination_check = Gtk.CheckButton(
valign=Gtk.Align.CENTER,
active=self.settings.get_boolean('move-appimage-on-integration')
)

self.copy_to_destination_check = Gtk.CheckButton(
valign=Gtk.Align.CENTER,
group=self.move_to_destination_check,
active=(not self.settings.get_boolean('move-appimage-on-integration'))
)

move_appimages_row.add_prefix(self.move_to_destination_check)
copy_appimages_row.add_prefix(self.copy_to_destination_check)

move_appimages_group.add(move_appimages_row)
move_appimages_group.add(copy_appimages_row)

self.move_to_destination_check.connect('toggled', self.on_move_appimages_setting_changed)
self.copy_to_destination_check.connect('toggled', self.on_move_appimages_setting_changed)

page1.add(general_preference_group)
page1.add(move_appimages_group)
self.add(page1)

def on_select_default_location_response(self, dialog, result):
Expand All @@ -57,4 +91,7 @@ def on_default_localtion_btn_clicked(self, widget):
parent=self,
cancellable=None,
callback=self.on_select_default_location_response
)
)

def on_move_appimages_setting_changed(self, widget):
self.settings.set_boolean('move-appimage-on-integration', self.move_to_destination_check.get_active())
159 changes: 84 additions & 75 deletions src/providers/AppImageProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,92 +222,101 @@ def install_file(self, el: AppImageListElement):

dest_appimage_file = Gio.File.new_for_path(appimages_destination_path + '/' + safe_app_name + '.appimage')

if gio_copy(extracted_appimage.appimage_file, dest_appimage_file):
log(f'file copied to {appimages_destination_path}')
if not gio_copy(extracted_appimage.appimage_file, dest_appimage_file):
raise InternalError('Error while moving appimage file to the destination folder')

os.chmod(dest_appimage_file.get_path(), 0o755)
el.file_path = dest_appimage_file.get_path()
log(f'file copied to {appimages_destination_path}')

# copy the icon file
icon_file = None
dest_appimage_icon_file = None
os.chmod(dest_appimage_file.get_path(), 0o755)
el.file_path = dest_appimage_file.get_path()

# copy the icon file
icon_file = None
dest_appimage_icon_file = None
if extracted_appimage.desktop_entry:
icon_file = extracted_appimage.icon_file

if icon_file and os.path.exists(icon_file.get_path()):
if not os.path.exists(f'{appimages_destination_path}/.icons'):
os.mkdir(f'{appimages_destination_path}/.icons')

dest_appimage_icon_file = Gio.File.new_for_path(f'{appimages_destination_path}/.icons/{safe_app_name}')
gio_copy(icon_file, dest_appimage_icon_file)

# Move .desktop file to its default location
dest_destop_file_path = f'{GLib.get_user_data_dir()}/applications/{safe_app_name}.desktop'
dest_destop_file_path = dest_destop_file_path.replace(' ', '_')

with open(extracted_appimage.desktop_file.get_path(), 'r') as dskt_file:
desktop_file_content = dskt_file.read()

# replace executable path
desktop_file_content = re.sub(
r'^Exec=.*$',
f"Exec={dest_appimage_file.get_path()}",
desktop_file_content,
flags=re.MULTILINE
)

# replace icon path
desktop_file_content = re.sub(
r'^Icon=.*$',
f"Icon={dest_appimage_icon_file.get_path() if dest_appimage_icon_file else 'applications-other'}",
desktop_file_content,
flags=re.MULTILINE
)

# generate a new app name
final_app_name = extracted_appimage.appimage_file.get_basename()
if extracted_appimage.desktop_entry:
icon_file = extracted_appimage.icon_file

if icon_file and os.path.exists(icon_file.get_path()):
if not os.path.exists(f'{appimages_destination_path}/.icons'):
os.mkdir(f'{appimages_destination_path}/.icons')

dest_appimage_icon_file = Gio.File.new_for_path(f'{appimages_destination_path}/.icons/{safe_app_name}')
gio_copy(icon_file, dest_appimage_icon_file)

# Move .desktop file to its default location
dest_destop_file_path = f'{GLib.get_user_data_dir()}/applications/{safe_app_name}.desktop'
dest_destop_file_path = dest_destop_file_path.replace(' ', '_')

with open(extracted_appimage.desktop_file.get_path(), 'r') as dskt_file:
desktop_file_content = dskt_file.read()

# replace executable path
desktop_file_content = re.sub(
r'^Exec=.*$',
f"Exec={dest_appimage_file.get_path()}",
desktop_file_content,
flags=re.MULTILINE
)

# replace icon path
desktop_file_content = re.sub(
r'^Icon=.*$',
f"Icon={dest_appimage_icon_file.get_path() if dest_appimage_icon_file else 'applications-other'}",
desktop_file_content,
flags=re.MULTILINE
)

# generate a new app name
final_app_name = extracted_appimage.appimage_file.get_basename()
if extracted_appimage.desktop_entry:
final_app_name = f"{extracted_appimage.desktop_entry.getName()}"

version = extracted_appimage.desktop_entry.get('X-AppImage-Version')

if not version:
version = extracted_appimage.md5[0:6]
desktop_file_content += f'\nX-AppImage-Version={version}'

if el.update_logic is AppImageUpdateLogic.KEEP:
final_app_name += f' ({version})'

desktop_file_content = re.sub(
r'^Name\[(.*?)\]=.*$',
'',
desktop_file_content,
flags=re.MULTILINE
)

final_app_name = final_app_name.strip()
desktop_file_content = re.sub(
r'^Name=.*$',
f"Name={final_app_name}",
desktop_file_content,
flags=re.MULTILINE
)

# finally, write the new .desktop file
with open(dest_destop_file_path, 'w+') as desktop_file_python_dest:
desktop_file_python_dest.write(desktop_file_content)

if os.path.exists(dest_destop_file_path):
el.desktop_entry = DesktopEntry.DesktopEntry(filename=dest_destop_file_path)
el.installed_status = InstalledStatus.INSTALLED
final_app_name = f"{extracted_appimage.desktop_entry.getName()}"

version = extracted_appimage.desktop_entry.get('X-AppImage-Version')

if not version:
version = extracted_appimage.md5[0:6]
desktop_file_content += f'\nX-AppImage-Version={version}'

if el.update_logic is AppImageUpdateLogic.KEEP:
final_app_name += f' ({version})'

desktop_file_content = re.sub(
r'^Name\[(.*?)\]=.*$',
'',
desktop_file_content,
flags=re.MULTILINE
)

final_app_name = final_app_name.strip()
desktop_file_content = re.sub(
r'^Name=.*$',
f"Name={final_app_name}",
desktop_file_content,
flags=re.MULTILINE
)

# finally, write the new .desktop file
with open(dest_destop_file_path, 'w+') as desktop_file_python_dest:
desktop_file_python_dest.write(desktop_file_content)

if os.path.exists(dest_destop_file_path):
el.desktop_entry = DesktopEntry.DesktopEntry(filename=dest_destop_file_path)
el.installed_status = InstalledStatus.INSTALLED

except Exception as e:
logging.error('Appimage installation error: ' + str(e))
raise e

try:
self.extraction_folder_cleanup()
except Exception as g:
logging.error('Appimage cleanup error: ' + str(g))
raise g

if get_gsettings().get_boolean('move-appimage-on-integration'):
logging.debug('Deleting original appimage file from: ' + extracted_appimage.appimage_file.get_path())
if not extracted_appimage.appimage_file.delete(None):
raise InternalError('Cannot delete original file')

terminal.sh(['update-desktop-database', '-q'])

Expand Down

0 comments on commit 84422de

Please sign in to comment.