Last active
October 26, 2025 11:24
-
-
Save ssokolow/db565fd8a82d6002baada946adb81f68 to your computer and use it in GitHub Desktop.
Revisions
-
ssokolow revised this gist
May 27, 2024 . 1 changed file with 3 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -86,12 +86,13 @@ #: `STRIP_SCRIPT_EXTS`. STRIP_REVERSE_DNS = True #: If not None, strip matching suffixes from the end of the command #: name, removing the need to special-case retrieved command names like #: `scummvm_wrapper`. This will be applied after `STRIP_SCRIPT_EXTS`. #: #: Will be applied after `STRIP_SCRIPT_EXTS` and `STRIP_REVERSE_DNS` STRIP_WRAPPER_SUFFIX = re.compile("[_-](wrapper|launcher)$", re.IGNORECASE) #: Remappings for flatpak packages that use less-than-ideal command names CMD_REMAPPINGS = { -
ssokolow revised this gist
Sep 25, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -96,6 +96,7 @@ #: Remappings for flatpak packages that use less-than-ideal command names CMD_REMAPPINGS = { 'io.github.simple64.simple64': 'simple64', # gui-wrapper.sh 'org.godotengine.Godot3': 'godot3', # Collides with Godot 4 'org.jdownloader.JDownloader': 'jdownloader', # jd-wrapper 'org.ppsspp.PPSSPP': 'ppsspp', # PPSSPPDL 'org.purei.Play': 'play_emu', # Collides with SoX's `play` -
ssokolow revised this gist
Sep 23, 2022 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,6 +20,7 @@ Known shortcomings: * Doesn't recognize file:// URLs and `@@u` wrap them yet. * Doesn't try parsing `--foo=/bar/baz` to find paths that need `--file-forwarding`, so use `--foo /bar/baz` instead. * Still need to look into the best way to query the set of `.desktop` files -
ssokolow revised this gist
Sep 23, 2022 . 1 changed file with 55 additions and 33 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,12 +20,11 @@ Known shortcomings: * Doesn't try parsing `--foo=/bar/baz` to find paths that need `--file-forwarding`, so use `--foo /bar/baz` instead. * Still need to look into the best way to query the set of `.desktop` files installed by Things like OpenRA so I don't need to *manually* amend the `EXTRA_COMMANDS` list in cases involving secondary GUI apps. * Uses the sledgehammer approach of just removing all non-folders from the target directory before generating new launchers to clear out stale entries. (A proper solution would keep track of which ones it created, but that'd @@ -56,7 +55,7 @@ SOFTWARE. """ import re, shlex from distutils.spawn import find_executable import os.path @@ -128,11 +127,15 @@ unset LD_PRELOAD # Make arguments that are existing paths absolute # and wrap them in the appropriate type of --file-forwarding # wrapper tokens. # (Necessary to make forwarding work reliably) declare -a args for arg in "$@"; do if [ -a "$arg" ]; then args+=("{fwd_wrap_start}") args+=("$(readlink -f "$arg")") args+=("@@") else args+=("$arg") fi @@ -142,7 +145,9 @@ exec {flatpak_cmd} """ # Regex to match the argument type in a .desktop file so it can be converted # to the appropriate --file-forwarding marker type arg_placeholder_re = re.compile("%([uUfF])") def get_installed_packages() -> Dict[str, str]: @@ -170,42 +175,43 @@ def get_installed_packages() -> Dict[str, str]: def make_flatpak_cmd(ref: str, extra_args: str = '') -> str: """Construct a ``flatpak run`` command for the given arguments This is used to avoid a needless indirection from calling the existing wrappers just to add things like `--file-forwarding` handling, and is preferred over harvesting the `.desktop` file `Exec` lines to avoid the complications of handling field codes like `%c`. """ return (f'flatpak run {extra_args} --file-forwarding ' f'"{ref}" "${{args[@]}}"') def wants_urls(ref: str) -> bool: """Attempt to parse the corresponding `.desktop` file to determine whether a Flatpak-packaged app expects its `--file-forwarding` arguments as URLs. Default to `False` on failure. Command is not actually used to construct the launcher to avoid the complexities introduced by field codes like `%c`. """ for candidate in FLATPAK_DESKTOP_FILE_PATHS: try: desktop_file = Gio.DesktopAppInfo.new_from_filename( os.path.join(candidate, ref + '.desktop')) if desktop_file: commandline = desktop_file.get_commandline() if commandline: if any(x.lower() == '%u' for x in shlex.split(commandline)): return True except TypeError: pass return False def make_wrapper(flatpak_cmd: str, command: str, bin_dir: str, wants_urls=False, seen: List[str] = None): """Render ``WRAPPER_TEMPLATE`` to a command in the folder ``bin_dir`` and mark it executable. @@ -227,7 +233,8 @@ def make_wrapper(flatpak_cmd: str, command: str, bin_dir: str, existing = find_executable(command) with open(out_path, 'w') as fobj: fobj.write(WRAPPER_TEMPLATE.format( flatpak_cmd=flatpak_cmd, fwd_wrap_start="@@u" if wants_urls else "@@")) os.chmod(out_path, os.stat(out_path).st_mode | 0o755) if seen is not None: seen.append(out_path) @@ -288,15 +295,30 @@ def main(): print(f"Generating wrapper for {ref}...") command = prepare_cmd_name(command, ref) takes_urls = wants_urls(ref) make_wrapper(make_flatpak_cmd(ref), command, BIN_DIR, wants_urls=takes_urls, seen=added) if ref in EXTRA_CMDS: for cmd in EXTRA_CMDS[ref]: make_wrapper(make_flatpak_cmd(ref, f"--command={cmd}"), cmd, BIN_DIR, wants_urls=takes_urls, seen=added) exec_path = os.environ.get('PATH', '').split(os.pathsep) try: bin_dir_idx = exec_path.index(BIN_DIR) masked = [] for idx, val in enumerate(exec_path): if idx > bin_dir_idx and not val.startswith('/home'): masked.append(val) if masked: print(f"WARNING: {BIN_DIR} has a higher precendence than these" f" paths in your PATH. This may present a security risk by" f" allowing flatpaks to override trusted system commands:" "\n\t" + '\n\t'.join(masked)) except ValueError: print(f"WARNING: Could not find {BIN_DIR} in PATH. You will need to " "add it before you can use the generated launchers.") -
ssokolow revised this gist
Sep 10, 2022 . 1 changed file with 59 additions and 14 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -23,8 +23,9 @@ * Still need to look into the best way to query the set of `.desktop` files installed by Things like OpenRA so I don't need to *manually* amend the `EXTRA_COMMANDS` list in cases involving secondary GUI apps. * Need a way to override things like the `--player-operation-mode=pseudo-gui --` that's harvested from MPV's `.desktop` file and breaks stdout/stderr output. * Uses the sledgehammer approach of just removing all non-folders from the target directory before generating new launchers to clear out stale entries. (A proper solution would keep track of which ones it created, but that'd @@ -71,19 +72,33 @@ #: Add this to the end of your $PATH BIN_DIR = os.path.expanduser("~/.local/bin/flatpak") #: If True, lowercase retrieved command names like `Fritzing` and `SweetHome3D` #: before using them as launcher names to make commands easier to type. FORCE_LOWERCASE_CMDS = True #: Strip the specified extensions from the extracted command name, #: removing the need to special-case retrieved command names like `86Box.sh` STRIP_SCRIPT_EXTS = ['.sh', '.js', '.py', '.pl', '.rb'] #: If True and the command's name matches the reverse DNS "ref", take only the #: final component as the command name, removing the need to special-case #: command names like `com.github.tchx84.Flatseal`. Will be applied after #: `STRIP_SCRIPT_EXTS`. STRIP_REVERSE_DNS = True #: If not None, strip `_wrapper` or `-wrapper` from the end of the command #: name, removing the need to special-case retrieved command names like #: `scummvm_wrapper`. This will be applied after `STRIP_SCRIPT_EXTS`. #: #: Will be applied after `STRIP_SCRIPT_EXTS` and `STRIP_REVERSE_DNS` STRIP_WRAPPER_SUFFIX = re.compile("[_-]wrapper$", re.IGNORECASE) #: Remappings for flatpak packages that use less-than-ideal command names CMD_REMAPPINGS = { 'io.github.simple64.simple64': 'simple64', # gui-wrapper.sh 'org.jdownloader.JDownloader': 'jdownloader', # jd-wrapper 'org.ppsspp.PPSSPP': 'ppsspp', # PPSSPPDL 'org.purei.Play': 'play_emu', # Collides with SoX's `play` } #: Secondary commands to expose @@ -227,6 +242,36 @@ def make_wrapper(flatpak_cmd: str, command: str, bin_dir: str, print(msg + f' The Flatpak wrapper will mask access to it.') def prepare_cmd_name(command: str, ref: str) -> str: """Apply configured transformations to derive the best command name""" # Strip things like `86Box.sh` down to `86Box` cmd_base, ext = os.path.splitext(command) if ext.lower() in STRIP_SCRIPT_EXTS: command = cmd_base # Strip things like `com.github.tchx84.Flatseal` down to `Flatseal` # # TODO: If the last component is `Launcher` or `Wrapper`, then take the # next component and join them with a dash. This hasn't proved necessary # yet but, if `org.solarus_games.solarus.Launcher` hadn't used # `solarus-launcher` as its command name, it could have been. if STRIP_REVERSE_DNS and command.lower() == ref.lower(): command = command.rsplit('.')[-1] # Force things like `SweetHome3D` to `sweethome3d` for easier typing if FORCE_LOWERCASE_CMDS: command = command.lower() # Remove `_wrapper` or `-wrapper` from names like `scummvm_wrapper` if STRIP_WRAPPER_SUFFIX: command = STRIP_WRAPPER_SUFFIX.sub('', command) # Allow manually overriding all previous transformations command = CMD_REMAPPINGS.get(ref, command) return command def main(): """setuptools-compatible entry point""" # Ensure BIN_DIR exists and remove any stale launch scripts @@ -242,7 +287,7 @@ def main(): for (ref, command) in get_installed_packages().items(): print(f"Generating wrapper for {ref}...") command = prepare_cmd_name(command, ref) make_wrapper(get_flatpak_cmd(ref), command, BIN_DIR, seen=added) if ref in EXTRA_CMDS: -
ssokolow revised this gist
Sep 10, 2022 . No changes.There are no files selected for viewing
-
ssokolow revised this gist
Sep 10, 2022 . 1 changed file with 5 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -23,6 +23,8 @@ * Still need to look into the best way to query the set of `.desktop` files installed by Things like OpenRA so I don't need to *manually* amend the `EXTRA_COMMANDS` list in cases involving secondary GUI apps. * Need a way to override things like the `--player-operation-mode=pseudo-gui --` that's harvested from MPV's `.desktop` file and breaks stdout/stderr output. * Uses the sledgehammer approach of just removing all non-folders from the target directory before generating new launchers to clear out stale entries. (A proper solution would keep track of which ones it created, but that'd @@ -70,6 +72,8 @@ BIN_DIR = os.path.expanduser("~/.local/bin/flatpak") #: Remappings for flatpak packages that use less-than-ideal command names #: #: TODO: Most of these could be replaced with a "force lowercase" boolean CMD_REMAPPINGS = { 'com.github.tchx84.Flatseal': 'flatseal', 'com.sweethome3d.Sweethome3d': 'sweethome3d', @@ -92,8 +96,6 @@ #: Paths to check for .desktop files, since ``Gio.DesktopAppInfo.new`` doesn't FLATPAK_DESKTOP_FILE_PATHS = ( '/var/lib/flatpak/exports/share/applications', os.path.expanduser('~/.local/share/flatpak/exports/share/applications') ) @@ -199,6 +201,7 @@ def make_wrapper(flatpak_cmd: str, command: str, bin_dir: str, Also warn if we're masking existing commands. """ command = os.path.basename(command) out_path = os.path.join(bin_dir, command) if seen is not None and out_path in seen: print(f'ERROR: Wrapper name "{out_path}" was already claimed and ' -
ssokolow revised this gist
Sep 4, 2022 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -20,6 +20,9 @@ Known shortcomings: * Still need to look into the best way to query the set of `.desktop` files installed by Things like OpenRA so I don't need to *manually* amend the `EXTRA_COMMANDS` list in cases involving secondary GUI apps. * Uses the sledgehammer approach of just removing all non-folders from the target directory before generating new launchers to clear out stale entries. (A proper solution would keep track of which ones it created, but that'd @@ -71,6 +74,7 @@ 'com.github.tchx84.Flatseal': 'flatseal', 'com.sweethome3d.Sweethome3d': 'sweethome3d', 'io.github.simple64.simple64': 'simple64', 'net._86box._86Box': '86box', 'net.cebix.basilisk': 'basilikii', 'org.fritzing.Fritzing': 'fritzing', 'org.jdownloader.JDownloader': 'jdownloader', @@ -81,6 +85,7 @@ #: Secondary commands to expose EXTRA_CMDS = { "com.github.AmatCoder.mednaffe": ['mednafen'], 'net.openra.OpenRA': ['openra-cnc', 'openra-d2k'], "org.atheme.audacious": ['audtool'], } -
ssokolow revised this gist
Sep 4, 2022 . 1 changed file with 8 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -68,12 +68,14 @@ #: Remappings for flatpak packages that use less-than-ideal command names CMD_REMAPPINGS = { 'com.github.tchx84.Flatseal': 'flatseal', 'com.sweethome3d.Sweethome3d': 'sweethome3d', 'io.github.simple64.simple64': 'simple64', 'net.cebix.basilisk': 'basilikii', 'org.fritzing.Fritzing': 'fritzing', 'org.jdownloader.JDownloader': 'jdownloader', 'org.ppsspp.PPSSPP': 'ppsspp', 'org.scummvm.ScummVM': 'scummvm', } #: Secondary commands to expose @@ -232,7 +234,7 @@ def main(): for (ref, command) in get_installed_packages().items(): print(f"Generating wrapper for {ref}...") command = CMD_REMAPPINGS.get(ref, command) make_wrapper(get_flatpak_cmd(ref), command, BIN_DIR, seen=added) if ref in EXTRA_CMDS: -
ssokolow revised this gist
Sep 4, 2022 . No changes.There are no files selected for viewing
-
ssokolow revised this gist
Sep 4, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -104,7 +104,7 @@ unset LD_PRELOAD # Make arguments that are existing paths absolute # (Necessary to make forwarding work reliably) declare -a args for arg in "$@"; do if [ -a "$arg" ]; then -
ssokolow revised this gist
Sep 4, 2022 . 2 changed files with 250 additions and 78 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,250 @@ #!/usr/bin/env python3 """Flatpak CLI Shortcut Generator A simple no-argument tool that generates launchers with traditional non-flatpak command names for your installed Flatpak applications in ~/.local/bin/flatpak. Does full collision detection and warns you if you forgot to add its output directory to your PATH. Also overrules the command-line specified in the ``.desktop`` file if the Flatpak maintainer didn't include support for command-line arguments. Also includes some built-in mappings to compensate for the less desirable launcher/wrapper names some Flatpak packages use. Dependencies: - Python 3.8+ - PyGobject (eg. python3-gi) - Glib and Gio 2.0 with GIR bindings (eg. gir1.2-glib-2.0) - Flatpak 1.0 GIR binding (eg. gir1.2-flatpak-1.0) Known shortcomings: * Uses the sledgehammer approach of just removing all non-folders from the target directory before generating new launchers to clear out stale entries. (A proper solution would keep track of which ones it created, but that'd require me to go back and implement detection of all prior versions which don't have a specific marker.) * Doesn't solve the problem of flatpaks still not installing manpages MIT License Copyright (c) 2021-2022 Stephan Sokolow (deitarion/SSokolow) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import re from distutils.spawn import find_executable import os.path from typing import Dict, List import gi # type: ignore gi.require_version('Flatpak', '1.0') gi.require_version('Gio', '2.0') gi.require_version('GLib', '2.0') from gi.repository import Flatpak, Gio, GLib # type: ignore #: Add this to the end of your $PATH BIN_DIR = os.path.expanduser("~/.local/bin/flatpak") #: Remappings for flatpak packages that use less-than-ideal command names CMD_REMAPPINGS = { 'BasiliskII': 'basilikii', 'com.github.tchx84.Flatseal': 'flatseal', 'Fritzing': 'fritzing', 'scummvm_wrapper': 'scummvm', 'PPSSPPSDL': 'ppsspp', 'SweetHome3D': 'sweethome3d', } #: Secondary commands to expose EXTRA_CMDS = { "com.github.AmatCoder.mednaffe": ['mednafen'], "org.atheme.audacious": ['audtool'], } #: Paths to check for .desktop files, since ``Gio.DesktopAppInfo.new`` doesn't FLATPAK_DESKTOP_FILE_PATHS = ( '/var/lib/flatpak/exports/share/applications', # TODO: Confirm this is correct for --user os.path.expanduser('~/.local/share/flatpak/exports/share/applications') ) #: The template for generating wrapper scripts. #: (Uses Python's ``.format``, so escape { and } as {{ and }} #: #: Uses bash for the wrapper script because I need to iterate an array #: and conditionally rewrite arguments and the Python interpreter is an #: order of magnitude slower to start. WRAPPER_TEMPLATE = """#!/bin/bash # AUTOGENERATED FILE! DO NOT EDIT! # Unset LD_PRELOAD to silence errors about gtk-nocsd being # missing from the Flatpak runtime unset LD_PRELOAD # Make arguments that are existing paths absolute # (Necessary to make "assume file:// URLs are OK" forwarding work reliably) declare -a args for arg in "$@"; do if [ -a "$arg" ]; then args+=("$(readlink -f "$arg")") else args+=("$arg") fi done # Use file forwarding to make paths Just Work™ exec {flatpak_cmd} """ arg_placeholder_re = re.compile("%[uUfF]") def get_installed_packages() -> Dict[str, str]: """Retrieve a dict mapping package names to command names for installed flatpaks""" results = {} for installation in ( Flatpak.Installation.new_system(), Flatpak.Installation.new_user()): refs = installation.list_installed_refs_by_kind( Flatpak.RefKind.APP, None) for ref in refs: meta = ref.load_metadata().get_data().decode('utf8') keyfile = GLib.KeyFile.new() keyfile.load_from_data(meta, len(meta), GLib.KeyFileFlags.NONE) command = keyfile.get_string('Application', 'command').strip() if command: results[ref.get_name()] = command return results def make_flatpak_cmd(ref: str, extra_args: str = '') -> str: """Construct a ``flatpak run`` command for the given arguments This is used for secondary commands and for the fallback for the primary command""" return (f'flatpak run {extra_args} --file-forwarding "{ref}" @@u ' f'"${{args[@]}}" @@') def get_flatpak_cmd(ref: str) -> str: """Extract or construct the best possible command to launch ``ref`` (This tries to extract it from the ``.desktop`` file and then falls back to ``make_flatpak_cmd`` if it fails or the extracted command line doesn't include ``--file-forwarding`` to ensure that upstream can't prevent us from feeding command-line arguments... ScummVM as of this writing, for example.) """ desktop_file = None for candidate in FLATPAK_DESKTOP_FILE_PATHS: try: desktop_file = Gio.DesktopAppInfo.new_from_filename( os.path.join(candidate, ref + '.desktop')) break except TypeError: pass # If we found a .desktop file AND it uses --file-forwarding if desktop_file: command = desktop_file.get_commandline() if '--file-forwarding' in command: return arg_placeholder_re.sub('"${args[@]}"', command) # ...otherwise, fall back to the generated command line that's been working # well for me for months. return make_flatpak_cmd(ref) def make_wrapper(flatpak_cmd: str, command: str, bin_dir: str, seen: List[str] = None): """Render ``WRAPPER_TEMPLATE`` to a command in the folder ``bin_dir`` and mark it executable. If provided, ``extra_args`` will be inserted into the portion of the ``flatpak run`` command before ``run``. If ``seen`` is not ``None``, use it to detect and reject naming collisions. Also warn if we're masking existing commands. """ out_path = os.path.join(bin_dir, command) if seen is not None and out_path in seen: print(f'ERROR: Wrapper name "{out_path}" was already claimed and ' f'could not be mapped to "{flatpak_cmd}". Please add a ' f' CMD_REMAPPINGS entry.') return existing = find_executable(command) with open(out_path, 'w') as fobj: fobj.write(WRAPPER_TEMPLATE.format( flatpak_cmd=flatpak_cmd)) os.chmod(out_path, os.stat(out_path).st_mode | 0o755) if seen is not None: seen.append(out_path) if existing: msg = (f'WARNING: Command "{command}" already exists in your PATH at ' f'"{existing}".') winner = find_executable(command) if winner == existing: print(msg + f' The Flatpak wrapper will be inaccessible.') else: print(msg + f' The Flatpak wrapper will mask access to it.') def main(): """setuptools-compatible entry point""" # Ensure BIN_DIR exists and remove any stale launch scripts if not os.path.exists(BIN_DIR): os.makedirs(BIN_DIR) for name in os.listdir(BIN_DIR): path = os.path.join(BIN_DIR, name) if os.path.isfile(path): os.remove(path) print(f"Getting list of installed application/non-runtime packages...") added = [] for (ref, command) in get_installed_packages().items(): print(f"Generating wrapper for {ref}...") command = CMD_REMAPPINGS.get(command, command) make_wrapper(get_flatpak_cmd(ref), command, BIN_DIR, seen=added) if ref in EXTRA_CMDS: for cmd in EXTRA_CMDS[ref]: make_wrapper(make_flatpak_cmd(ref, f"--command={cmd}"), cmd, BIN_DIR, added) # Check if BIN_DIR is in the PATH so people don't need to read this source if BIN_DIR not in os.environ.get('PATH', '').split(os.pathsep): print(f"WARNING: Could not find {BIN_DIR} in PATH. You will need to " "add it before you can use the generated launchers.") if __name__ == '__main__': main() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,78 +0,0 @@ -
ssokolow revised this gist
Sep 3, 2022 . 1 changed file with 24 additions and 8 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -41,22 +41,38 @@ CMD_REMAPPINGS=( [SweetHome3D]='sweethome3d' ) declare -A EXTRA_CMDS EXTRA_CMDS=( ["com.github.AmatCoder.mednaffe"]='mednafen' ["org.atheme.audacious"]='audtool' ) # Remove any stale launch scripts rm -f "$BIN_DIR"/* mkdir -p "$BIN_DIR" make_wrapper() { # Use bash for the wrapper script because I need to iterate an array # and conditionally rewrite arguments and the Python interpreter is an # order of magnitude slower to start. # # shellcheck disable=SC2016 printf '#!/bin/bash\n# AUTOGENERATED FILE! DO NOT EDIT!\n\n# Unset LD_PRELOAD to silence errors about gtk-nocsd being missing from the Flatpak runtime\nunset LD_PRELOAD\n\n# Make arguments that are existing paths absolute\n# (Necessary to make "assume file:// URLs are OK" forwarding work reliably)\ndeclare -a args\nfor arg in "$@"; do\n if [ -a "$arg" ]; then\n args+=("$(readlink -f "$arg")")\n else\n args+=("$arg")\n fi\ndone\n\n# Use file forwarding to make paths Just Work™\nexec flatpak run '"$3"' --file-forwarding "%s" @@u "${args[@]}" @@' "$1" >"$2" chmod +x "$2" } for X in $(flatpak list --columns=ref); do echo "Querying $X..." app_command="$(flatpak info -m "$X" | grep command= | cut -d= -f2)" if [ -n "$app_command" ]; then cmd_path="$BIN_DIR"/"${CMD_REMAPPINGS["${app_command}"]:-$app_command}" make_wrapper "$X" "$cmd_path" # Strip any `/x86_64/stable` and check for a match if [ -n "${EXTRA_CMDS["${X%%/*}"]}" ]; then cmd="${EXTRA_CMDS["${X%%/*}"]}" cmd_path="$BIN_DIR"/ make_wrapper "$X" "$BIN_DIR/$cmd" "--command=$cmd" fi fi done -
ssokolow revised this gist
Sep 3, 2022 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,8 +4,6 @@ # # License: MIT # # Known shortcomings in this quick and dirty PoC: # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts -
ssokolow revised this gist
Sep 3, 2022 . 1 changed file with 35 additions and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,44 +1,64 @@ #!/bin/bash # Flatpak CLI Shortcut Proof of Concept # Copyright 2021-2022 Stephan Sokolow (deitarion/SSokolow) # # License: MIT # # Features: # # Known shortcomings in this quick and dirty PoC: # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered instead of just applying "last processed wins" behaviour.) # * In order to support non-local URL arguments to Flatpak'd browsers, use of # --file-forwarding assumes all installed programs will accept file:// URLs. # (A proper solution would parse the .desktop files to identify what kinds of # arguments the commands want, but I have yet to run into something I want to # invoke from the command-line which *doesn't* accept file:// URLs... I'm # guessing things like GTK's GIO and Qt's I/O classes just accept file:// # URLs as a valid form of "local path".) # * Just uses `grep command= | cut -d= -f2` to "parse" the INI-style output # of `flatpak info -m` # (A proper implementation needs to make sure it's from the right section of # the file to ensure there's no risk of multiple lines matching.) # * Uses the sledgehammer approach of just removing all non-folders from the # target directory before generating new launchers to clear out stale entries. # (A proper solution would keep track of which ones it created and would also # look for more performant alternatives to spawning a `flatpak info -m` for # each application, which limits performance to about 13 applications per # second.) # * Doesn't solve the problem of flatpaks still not installing manpages # Add this to the end of your $PATH BIN_DIR=~/.local/bin/flatpak # Remappings for flatpak packages that use less-than-ideal command names declare -A CMD_REMAPPINGS CMD_REMAPPINGS=( [BasiliskII]='basilikii' ["com.github.tchx84.Flatseal"]='flatseal' [Fritzing]='fritzing' [scummvm_wrapper]='scummvm' [PPSSPPSDL]='ppsspp' [SweetHome3D]='sweethome3d' ) # Remove any stale launch scripts rm -f "$BIN_DIR"/* mkdir -p "$BIN_DIR" for X in $(flatpak list --columns=ref); do echo "Querying $X..." app_command="$(flatpak info -m "$X" | grep command= | cut -d= -f2)" if [ -n "$app_command" ]; then cmd_path="$BIN_DIR"/"${CMD_REMAPPINGS["${app_command}"]:-$app_command}" # Use bash for the wrapper script because I need to iterate an array # and conditionally rewrite arguments and the Python interpreter is an # order of magnitude slower to start. # # shellcheck disable=SC2016 printf '#!/bin/bash\n# AUTOGENERATED FILE! DO NOT EDIT!\n\n# Unset LD_PRELOAD to silence errors about gtk-nocsd being missing from the Flatpak runtime\nunset LD_PRELOAD\n\n# Make arguments that are existing paths absolute\n# (Necessary to make "assume file:// URLs are OK" forwarding work reliably)\ndeclare -a args\nfor arg in "$@"; do\n if [ -a "$arg" ]; then\n args+=("$(readlink -f "$arg")")\n else\n args+=("$arg")\n fi\ndone\n\n# Use file forwarding to make paths Just Work™\nexec flatpak run --file-forwarding "%s" @@u "${args[@]}" @@' "$X" >"$cmd_path" chmod +x "$cmd_path" fi done -
ssokolow revised this gist
Mar 19, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -37,7 +37,7 @@ for X in $(flatpak list --columns=ref); do if [ -n "$app_command" ]; then # Unset LD_PRELOAD to silence gtk-nocsd errors and support file # forwarding so you can tighten your sandbox and still open local files printf '#!/bin/sh\nunset LD_PRELOAD\nexec flatpak run --file-forwarding "%s" @@u "$@" @@' "$X" >"$cmd_path" chmod +x "$cmd_path" fi -
ssokolow revised this gist
Oct 9, 2021 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,8 @@ # Known shortcomings in this quick and dirty PoC: # * In order to support non-local URL arguments to Flatpak'd browsers, use of # --file-forwarding assumes all installed programs will accept file:// URLs. # (A proper solution would parse the .desktop files to identify what kinds of # arguments the commands want.) # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered.) -
ssokolow revised this gist
Oct 9, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ # # Known shortcomings in this quick and dirty PoC: # * In order to support non-local URL arguments to Flatpak'd browsers, use of # --file-forwarding assumes all installed programs will accept file:// URLs. # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered.) -
ssokolow revised this gist
Oct 8, 2021 . 1 changed file with 2 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,10 +6,7 @@ # # Known shortcomings in this quick and dirty PoC: # * In order to support non-local URL arguments to Flatpak'd browsers, use of # --file-forwarding assumes all installed programs will accept # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered.) @@ -39,7 +36,7 @@ for X in $(flatpak list --columns=ref); do if [ -n "$app_command" ]; then # Unset LD_PRELOAD to silence gtk-nocsd errors and support file # forwarding so you can sandbox browsers and still open local files printf '#!/bin/sh\nunset LD_PRELOAD\nexec flatpak run --file-forwarding "%s" @@u "$@" @@' "$X" >"$cmd_path" chmod +x "$cmd_path" fi done -
ssokolow revised this gist
Oct 8, 2021 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,11 @@ # License: MIT # # Known shortcomings in this quick and dirty PoC: # * In order to support non-local URL arguments to Flatpak'd browsers, use of # --file-forwarding assumes all installed programs will be OK with local # paths getting translated to file:// URLs by Flatpak. # (Proper solution is to parse the corresponding `.desktop` files to # determine whether the applications expect URLs or paths.) # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered.) -
ssokolow revised this gist
Oct 8, 2021 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,6 +18,7 @@ # * No means of overriding Flatseal's decision to use # "com.github.tchx84.Flatseal" as its internal binary name rather than # "flatseal" # * Doesn't solve the problem of flatpaks still not installing manpages # Add this to the end of your $PATH BIN_DIR=~/.local/bin/flatpak @@ -31,7 +32,9 @@ for X in $(flatpak list --columns=ref); do cmd_path="$BIN_DIR"/"$app_command" if [ -n "$app_command" ]; then # Unset LD_PRELOAD to silence gtk-nocsd errors and support file # forwarding so you can sandbox browsers and still open local files printf '#!/bin/sh\nunset LD_PRELOAD\nexec flatpak run --file-forwarding "%s" @@ "$@" @@' "$X" >"$cmd_path" chmod +x "$cmd_path" fi done -
ssokolow created this gist
Apr 29, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ #!/bin/sh # Flatpak CLI Shortcut Proof of Concept # Copyright 2021 Stephan Sokolow (deitarion/SSokolow) # # License: MIT # # Known shortcomings in this quick and dirty PoC: # * Assumes command name collisions will never happen # (A proper implementation would need to prompt the user to resolve conflicts # if encountered.) # * Just uses `grep command= | cut -d= -f2` to "parse" the INI-style output # of `flatpak info -m` # (A proper implementation needs to make sure it's from the right section of # the file to ensure there's no risk of multiple lines matching.) # * Uses the sledgehammer approach of just removing all non-folders from the # target directory before generating new launchers to clear out stale entries. # (A proper solution would keep track of which ones it created) # * No means of overriding Flatseal's decision to use # "com.github.tchx84.Flatseal" as its internal binary name rather than # "flatseal" # Add this to the end of your $PATH BIN_DIR=~/.local/bin/flatpak # Remove any stale launch scripts rm -f "$BIN_DIR"/* mkdir -p "$BIN_DIR" for X in $(flatpak list --columns=ref); do app_command="$(flatpak info -m "$X" | grep command= | cut -d= -f2)" cmd_path="$BIN_DIR"/"$app_command" if [ -n "$app_command" ]; then printf '#!/bin/sh\nexec flatpak run "%s" "$@"' "$X" >"$cmd_path" chmod +x "$cmd_path" fi done