diff --git a/ee/maintained-apps/inputs/homebrew/ua-connect.json b/ee/maintained-apps/inputs/homebrew/ua-connect.json new file mode 100644 index 00000000000..e3872c71caa --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/ua-connect.json @@ -0,0 +1,10 @@ +{ + "name": "UA Connect", + "unique_identifier": "com.uaudio.ua-connect", + "token": "ua-connect", + "installer_format": "dmg", + "slug": "ua-connect/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/ukelele.json b/ee/maintained-apps/inputs/homebrew/ukelele.json new file mode 100644 index 00000000000..ea3632a6fb3 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/ukelele.json @@ -0,0 +1,10 @@ +{ + "name": "Ukelele", + "unique_identifier": "org.sil.ukelele", + "token": "ukelele", + "installer_format": "dmg", + "slug": "ukelele/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/ultimaker-cura.json b/ee/maintained-apps/inputs/homebrew/ultimaker-cura.json new file mode 100644 index 00000000000..8e922b95e78 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/ultimaker-cura.json @@ -0,0 +1,10 @@ +{ + "name": "UltiMaker Cura", + "unique_identifier": "nl.ultimaker.cura.dmg", + "token": "ultimaker-cura", + "installer_format": "dmg", + "slug": "ultimaker-cura/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/unclutter.json b/ee/maintained-apps/inputs/homebrew/unclutter.json new file mode 100644 index 00000000000..68ca53e036c --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/unclutter.json @@ -0,0 +1,10 @@ +{ + "name": "Unclutter", + "unique_identifier": "com.softwareambience.Unclutter", + "token": "unclutter", + "installer_format": "zip", + "slug": "unclutter/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/unicodechecker.json b/ee/maintained-apps/inputs/homebrew/unicodechecker.json new file mode 100644 index 00000000000..4041d69af11 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/unicodechecker.json @@ -0,0 +1,10 @@ +{ + "name": "UnicodeChecker", + "unique_identifier": "net.earthlingsoft.UnicodeChecker", + "token": "unicodechecker", + "installer_format": "zip", + "slug": "unicodechecker/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/unity-hub.json b/ee/maintained-apps/inputs/homebrew/unity-hub.json new file mode 100644 index 00000000000..86c78f82ffe --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/unity-hub.json @@ -0,0 +1,10 @@ +{ + "name": "Unity Hub", + "unique_identifier": "com.unity3d.unityhub", + "token": "unity-hub", + "installer_format": "dmg", + "slug": "unity-hub/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/updf.json b/ee/maintained-apps/inputs/homebrew/updf.json new file mode 100644 index 00000000000..b8ce8d3ed19 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/updf.json @@ -0,0 +1,10 @@ +{ + "name": "UPDF", + "unique_identifier": "com.superace.updf.mac", + "token": "updf", + "installer_format": "dmg", + "slug": "updf/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/upscayl.json b/ee/maintained-apps/inputs/homebrew/upscayl.json new file mode 100644 index 00000000000..6041227f7c8 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/upscayl.json @@ -0,0 +1,10 @@ +{ + "name": "Upscayl", + "unique_identifier": "org.upscayl.Upscayl", + "token": "upscayl", + "installer_format": "dmg", + "slug": "upscayl/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/usage-app.json b/ee/maintained-apps/inputs/homebrew/usage-app.json new file mode 100644 index 00000000000..c1b42b5d1e9 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/usage-app.json @@ -0,0 +1,10 @@ +{ + "name": "Usage", + "unique_identifier": "com.mediaatelier.Usage", + "token": "usage-app", + "installer_format": "dmg", + "slug": "usage-app/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index fa29a9c2a39..4f04f6dd603 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -3270,6 +3270,69 @@ "unique_identifier": "Twingate", "description": "Twingate is a zero trust network access platform." }, + { + "name": "UA Connect", + "slug": "ua-connect/darwin", + "platform": "darwin", + "unique_identifier": "com.uaudio.ua-connect", + "description": "UA Connect is a software installer and device manager for Universal Audio products." + }, + { + "name": "Ukelele", + "slug": "ukelele/darwin", + "platform": "darwin", + "unique_identifier": "org.sil.ukelele", + "description": "Ukelele is a unicode keyboard layout editor." + }, + { + "name": "UltiMaker Cura", + "slug": "ultimaker-cura/darwin", + "platform": "darwin", + "unique_identifier": "nl.ultimaker.cura.dmg", + "description": "UltiMaker Cura is a 3D printer and slicing GUI." + }, + { + "name": "Unclutter", + "slug": "unclutter/darwin", + "platform": "darwin", + "unique_identifier": "com.softwareambience.Unclutter", + "description": "Unclutter is a desktop storage area for notes, files and pasteboard clips." + }, + { + "name": "UnicodeChecker", + "slug": "unicodechecker/darwin", + "platform": "darwin", + "unique_identifier": "net.earthlingsoft.UnicodeChecker", + "description": "UnicodeChecker is an explore and convert Unicode." + }, + { + "name": "Unity Hub", + "slug": "unity-hub/darwin", + "platform": "darwin", + "unique_identifier": "com.unity3d.unityhub", + "description": "Unity Hub is a management tool for Unity." + }, + { + "name": "UPDF", + "slug": "updf/darwin", + "platform": "darwin", + "unique_identifier": "com.superace.updf.mac", + "description": "UPDF is a PDF editor." + }, + { + "name": "Upscayl", + "slug": "upscayl/darwin", + "platform": "darwin", + "unique_identifier": "org.upscayl.Upscayl", + "description": "Upscayl is an AI image upscaler." + }, + { + "name": "Usage", + "slug": "usage-app/darwin", + "platform": "darwin", + "unique_identifier": "com.mediaatelier.Usage", + "description": "Usage is a tracks application usage." + }, { "name": "UTM", "slug": "utm/darwin", diff --git a/ee/maintained-apps/outputs/ua-connect/darwin.json b/ee/maintained-apps/outputs/ua-connect/darwin.json new file mode 100644 index 00000000000..759af63e3d1 --- /dev/null +++ b/ee/maintained-apps/outputs/ua-connect/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.9.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.uaudio.ua-connect';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.uaudio.ua-connect' AND version_compare(bundle_short_version, '1.9.3') < 0);" + }, + "installer_url": "https://builds.uaudio.com/apps/UA_Connect/UA_Connect_1_9_3_3672_Mac.dmg", + "install_script_ref": "3d09e295", + "uninstall_script_ref": "0e6f3643", + "sha256": "35d18872f42fd3be98ed6d1a2cac6378848f27b5da5f0d0dc8514195afe724d2", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "0e6f3643": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.uaudio.bsd.helper'\nquit_application 'com.uaudio.ua-connect'\nsudo rm -rf '/Library/LaunchDaemons/com.uaudio.bsd.helper.plist'\nsudo rm -rf '/Library/PrivilegedHelperTools/com.uaudio.bsd.helper'\nsudo rm -rf \"$APPDIR/UA Connect.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/UA Connect'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Universal Audio/UA Connect'\ntrash $LOGGED_IN_USER '~/Library/Logs/UA Connect'\ntrash $LOGGED_IN_USER '~/Library/Logs/Universal Audio/UA Connect.log'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.uaudio.ua-connect.plist'\n", + "3d09e295": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.uaudio.ua-connect'\nif [ -d \"$APPDIR/UA Connect.app\" ]; then\n\tsudo mv \"$APPDIR/UA Connect.app\" \"$TMPDIR/UA Connect.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/UA Connect.app\" \"$APPDIR\"\nrelaunch_application 'com.uaudio.ua-connect'\n" + } +} diff --git a/ee/maintained-apps/outputs/ukelele/darwin.json b/ee/maintained-apps/outputs/ukelele/darwin.json new file mode 100644 index 00000000000..8e05452e3f4 --- /dev/null +++ b/ee/maintained-apps/outputs/ukelele/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.6.1", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'org.sil.ukelele';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'org.sil.ukelele' AND version_compare(bundle_short_version, '3.6.1') < 0);" + }, + "installer_url": "https://software.sil.org/downloads/r/ukelele/Ukelele_3.6.1.dmg", + "install_script_ref": "cc892aec", + "uninstall_script_ref": "134f131d", + "sha256": "ffa11a15824f4ac9bf3cc9807e8bc9b0d4247efebf03d7a55d052dbfaafac501", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "134f131d": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Ukelele.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/org.sil.ukelele.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Caches/org.sil.Ukelele'\ntrash $LOGGED_IN_USER '~/Library/Preferences/org.sil.ukelele.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/Ukelele'\n", + "cc892aec": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'org.sil.ukelele'\nif [ -d \"$APPDIR/Ukelele.app\" ]; then\n\tsudo mv \"$APPDIR/Ukelele.app\" \"$TMPDIR/Ukelele.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Ukelele.app\" \"$APPDIR\"\nrelaunch_application 'org.sil.ukelele'\n" + } +} diff --git a/ee/maintained-apps/outputs/ultimaker-cura/darwin.json b/ee/maintained-apps/outputs/ultimaker-cura/darwin.json new file mode 100644 index 00000000000..e9c66a4f29f --- /dev/null +++ b/ee/maintained-apps/outputs/ultimaker-cura/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.13.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'nl.ultimaker.cura.dmg';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'nl.ultimaker.cura.dmg' AND version_compare(bundle_short_version, '5.13.0') < 0);" + }, + "installer_url": "https://github.com/Ultimaker/Cura/releases/download/5.13.0/UltiMaker-Cura-5.13.0-macos-ARM64.dmg", + "install_script_ref": "fe0414cc", + "uninstall_script_ref": "887d8525", + "sha256": "1483806486a19728bc0f363f847d75be3f179ea43c7f074bfc327f5b5c6e05ad", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "887d8525": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'nl.ultimaker.cura.dmg'\nsudo rm -rf \"$APPDIR/UltiMaker Cura.app\"\ntrash $LOGGED_IN_USER '~/.cura'\ntrash $LOGGED_IN_USER '~/Library/Application Support/cura'\ntrash $LOGGED_IN_USER '~/Library/Caches/Ultimaker B.V./Ultimaker-Cura'\ntrash $LOGGED_IN_USER '~/Library/Logs/cura'\ntrash $LOGGED_IN_USER '~/Library/Preferences/nl.ultimaker.cura.dmg.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/nl.ultimaker.cura.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/nl.ultimaker.cura.dmg.savedState'\n", + "fe0414cc": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'nl.ultimaker.cura.dmg'\nif [ -d \"$APPDIR/UltiMaker Cura.app\" ]; then\n\tsudo mv \"$APPDIR/UltiMaker Cura.app\" \"$TMPDIR/UltiMaker Cura.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/UltiMaker Cura.app\" \"$APPDIR\"\nrelaunch_application 'nl.ultimaker.cura.dmg'\n" + } +} diff --git a/ee/maintained-apps/outputs/unclutter/darwin.json b/ee/maintained-apps/outputs/unclutter/darwin.json new file mode 100644 index 00000000000..2f4a2935b0c --- /dev/null +++ b/ee/maintained-apps/outputs/unclutter/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.2.18d", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.softwareambience.Unclutter';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.softwareambience.Unclutter' AND version_compare(bundle_short_version, '2.2.18d') < 0);" + }, + "installer_url": "https://unclutterapp.com/files/Unclutter.zip", + "install_script_ref": "e2747ae2", + "uninstall_script_ref": "f4809b02", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "e2747ae2": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'com.softwareambience.Unclutter'\nif [ -d \"$APPDIR/Unclutter.app\" ]; then\n\tsudo mv \"$APPDIR/Unclutter.app\" \"$TMPDIR/Unclutter.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Unclutter.app\" \"$APPDIR\"\nrelaunch_application 'com.softwareambience.Unclutter'\n", + "f4809b02": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Unclutter.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/*.group.com.softwareambience.Unclutter'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.softwareambience.unclutter.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Unclutter'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.softwareambience.Unclutter'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.softwareambience.Unclutter'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/*.group.com.softwareambience.Unclutter'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.softwareambience.Unclutter'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.softwareambience.Unclutter.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/unicodechecker/darwin.json b/ee/maintained-apps/outputs/unicodechecker/darwin.json new file mode 100644 index 00000000000..9b4f2ec007c --- /dev/null +++ b/ee/maintained-apps/outputs/unicodechecker/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.25.1", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'net.earthlingsoft.UnicodeChecker';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'net.earthlingsoft.UnicodeChecker' AND version_compare(bundle_short_version, '1.25.1') < 0);" + }, + "installer_url": "https://earthlingsoft.net/UnicodeChecker/UnicodeChecker%201.25.1%20(862).zip", + "install_script_ref": "97c8470f", + "uninstall_script_ref": "b07c4637", + "sha256": "f6cc0c4e6904e3429e600db741a7bf26bbda2d7efb9eabac5f56b9475a6bfa6f", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "97c8470f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'net.earthlingsoft.UnicodeChecker'\nif [ -d \"$APPDIR/UnicodeChecker.app\" ]; then\n\tsudo mv \"$APPDIR/UnicodeChecker.app\" \"$TMPDIR/UnicodeChecker.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/UnicodeChecker.app\" \"$APPDIR\"\nrelaunch_application 'net.earthlingsoft.UnicodeChecker'\n", + "b07c4637": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/UnicodeChecker.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/UnicodeChecker'\ntrash $LOGGED_IN_USER '~/Library/Caches/net.earthlingsoft.UnicodeChecker'\ntrash $LOGGED_IN_USER '~/Library/Preferences/net.earthlingsoft.UnicodeChecker.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/unity-hub/darwin.json b/ee/maintained-apps/outputs/unity-hub/darwin.json new file mode 100644 index 00000000000..aef34653db2 --- /dev/null +++ b/ee/maintained-apps/outputs/unity-hub/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.18.2", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.unity3d.unityhub';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.unity3d.unityhub' AND version_compare(bundle_short_version, '3.18.2') < 0);" + }, + "installer_url": "https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetup-arm64.dmg", + "install_script_ref": "c26804cb", + "uninstall_script_ref": "5b95ff58", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "5b95ff58": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'com.unity3d.unityhub'\nsudo rm -rf \"$APPDIR/Unity Hub.app\"\nsudo rmdir '/Applications/Unity/Hub'\ntrash $LOGGED_IN_USER '~/Library/Application Support/UnityHub'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.unity3d.unityhub.helper.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.unity3d.unityhub.plist'\n", + "c26804cb": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.unity3d.unityhub'\nif [ -d \"$APPDIR/Unity Hub.app\" ]; then\n\tsudo mv \"$APPDIR/Unity Hub.app\" \"$TMPDIR/Unity Hub.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Unity Hub.app\" \"$APPDIR\"\nrelaunch_application 'com.unity3d.unityhub'\n" + } +} diff --git a/ee/maintained-apps/outputs/updf/darwin.json b/ee/maintained-apps/outputs/updf/darwin.json new file mode 100644 index 00000000000..fa522b8f668 --- /dev/null +++ b/ee/maintained-apps/outputs/updf/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.5.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.superace.updf.mac';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.superace.updf.mac' AND version_compare(bundle_short_version, '2.5.3') < 0);" + }, + "installer_url": "https://download.updf.com/updf/basic/mac/apple/updf-mac-full.dmg", + "install_script_ref": "2bc5724d", + "uninstall_script_ref": "00530805", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "00530805": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/UPDF.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.superace.updf.installer'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.superace.updf.mac'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.superace.updf.installer'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.superace.updf.mac'\ntrash $LOGGED_IN_USER '~/Library/Caches/UPDF Installer'\ntrash $LOGGED_IN_USER '~/Library/Caches/UPDF'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.superace.updf.installer'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.superace.updf.mac'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.superace.updf.mac.binarycookies'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.superace.updf.installer.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.superace.updf.mac.file.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.superace.updf.mac.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.superace.updf.mac.savedState'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.superace.updf.mac'\n", + "2bc5724d": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.superace.updf.mac'\nif [ -d \"$APPDIR/UPDF.app\" ]; then\n\tsudo mv \"$APPDIR/UPDF.app\" \"$TMPDIR/UPDF.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/UPDF.app\" \"$APPDIR\"\nrelaunch_application 'com.superace.updf.mac'\n" + } +} diff --git a/ee/maintained-apps/outputs/upscayl/darwin.json b/ee/maintained-apps/outputs/upscayl/darwin.json new file mode 100644 index 00000000000..d0fd12fd177 --- /dev/null +++ b/ee/maintained-apps/outputs/upscayl/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.15.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'org.upscayl.Upscayl';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'org.upscayl.Upscayl' AND version_compare(bundle_short_version, '2.15.0') < 0);" + }, + "installer_url": "https://github.com/upscayl/upscayl/releases/download/v2.15.0/upscayl-2.15.0-mac.dmg", + "install_script_ref": "ea37f146", + "uninstall_script_ref": "67ec9c31", + "sha256": "0e53c9ee8c1800cb3e2ce0f574e4e1a35a51945e19ff2b93f33928bbd7fd4c5a", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "67ec9c31": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Upscayl.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Upscayl'\ntrash $LOGGED_IN_USER '~/Library/Preferences/org.upscayl.app.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/org.upscayl.app.savedState'\n", + "ea37f146": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'org.upscayl.Upscayl'\nif [ -d \"$APPDIR/Upscayl.app\" ]; then\n\tsudo mv \"$APPDIR/Upscayl.app\" \"$TMPDIR/Upscayl.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Upscayl.app\" \"$APPDIR\"\nrelaunch_application 'org.upscayl.Upscayl'\n" + } +} diff --git a/ee/maintained-apps/outputs/usage-app/darwin.json b/ee/maintained-apps/outputs/usage-app/darwin.json new file mode 100644 index 00000000000..30b4d1450f0 --- /dev/null +++ b/ee/maintained-apps/outputs/usage-app/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.4.6", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.mediaatelier.Usage';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.mediaatelier.Usage' AND version_compare(bundle_short_version, '1.4.6') < 0);" + }, + "installer_url": "https://mediaatelier.com/Usage/Usage_1.4.6.dmg", + "install_script_ref": "85b735d2", + "uninstall_script_ref": "b71eb62e", + "sha256": "1a782b03b08b544eb1277c18576ce14e9388510f53f6e3bda4a6793bd2780c66", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "85b735d2": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.mediaatelier.Usage'\nif [ -d \"$APPDIR/Usage.app\" ]; then\n\tsudo mv \"$APPDIR/Usage.app\" \"$TMPDIR/Usage.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Usage.app\" \"$APPDIR\"\nrelaunch_application 'com.mediaatelier.Usage'\n", + "b71eb62e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Usage.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.mediaatelier.Usage'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.mediaatelier.Usage'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.mediaatelier.Usage.plist'\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/UaConnect.tsx b/frontend/pages/SoftwarePage/components/icons/UaConnect.tsx new file mode 100644 index 00000000000..0ef1fcdba69 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/UaConnect.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const UaConnect = (props: SVGProps) => ( + + + +); +export default UaConnect; diff --git a/frontend/pages/SoftwarePage/components/icons/Ukelele.tsx b/frontend/pages/SoftwarePage/components/icons/Ukelele.tsx new file mode 100644 index 00000000000..8d436c8b494 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Ukelele.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Ukelele = (props: SVGProps) => ( + + + +); +export default Ukelele; diff --git a/frontend/pages/SoftwarePage/components/icons/UltimakerCura.tsx b/frontend/pages/SoftwarePage/components/icons/UltimakerCura.tsx new file mode 100644 index 00000000000..d682372cac9 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/UltimakerCura.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const UltimakerCura = (props: SVGProps) => ( + + + +); +export default UltimakerCura; diff --git a/frontend/pages/SoftwarePage/components/icons/Unclutter.tsx b/frontend/pages/SoftwarePage/components/icons/Unclutter.tsx new file mode 100644 index 00000000000..bc5cc3b4d37 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Unclutter.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Unclutter = (props: SVGProps) => ( + + + +); +export default Unclutter; diff --git a/frontend/pages/SoftwarePage/components/icons/Unicodechecker.tsx b/frontend/pages/SoftwarePage/components/icons/Unicodechecker.tsx new file mode 100644 index 00000000000..048182cd1ca --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Unicodechecker.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Unicodechecker = (props: SVGProps) => ( + + + +); +export default Unicodechecker; diff --git a/frontend/pages/SoftwarePage/components/icons/UnityHub.tsx b/frontend/pages/SoftwarePage/components/icons/UnityHub.tsx new file mode 100644 index 00000000000..98b224d8de6 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/UnityHub.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const UnityHub = (props: SVGProps) => ( + + + +); +export default UnityHub; diff --git a/frontend/pages/SoftwarePage/components/icons/Updf.tsx b/frontend/pages/SoftwarePage/components/icons/Updf.tsx new file mode 100644 index 00000000000..7da92402654 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Updf.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Updf = (props: SVGProps) => ( + + + +); +export default Updf; diff --git a/frontend/pages/SoftwarePage/components/icons/Upscayl.tsx b/frontend/pages/SoftwarePage/components/icons/Upscayl.tsx new file mode 100644 index 00000000000..fe9970844ae --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Upscayl.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Upscayl = (props: SVGProps) => ( + + + +); +export default Upscayl; diff --git a/frontend/pages/SoftwarePage/components/icons/UsageApp.tsx b/frontend/pages/SoftwarePage/components/icons/UsageApp.tsx new file mode 100644 index 00000000000..0b21691a358 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/UsageApp.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const UsageApp = (props: SVGProps) => ( + + + +); +export default UsageApp; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index 68113e53460..35575d5be5c 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -339,6 +339,15 @@ import Tower from "./Tower"; import Transmit from "./Transmit"; import Tunnelblick from "./Tunnelblick"; import Twingate from "./Twingate"; +import UaConnect from "./UaConnect"; +import Ukelele from "./Ukelele"; +import UltimakerCura from "./UltimakerCura"; +import Unclutter from "./Unclutter"; +import Unicodechecker from "./Unicodechecker"; +import UnityHub from "./UnityHub"; +import Updf from "./Updf"; +import Upscayl from "./Upscayl"; +import UsageApp from "./UsageApp"; import Utm from "./Utm"; import Vanilla from "./Vanilla"; import VcRedistX64 from "./VcRedistX64"; @@ -780,6 +789,15 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { transmit: Transmit, tunnelblick: Tunnelblick, twingate: Twingate, + "ua connect": UaConnect, + ukelele: Ukelele, + "ultimaker cura": UltimakerCura, + unclutter: Unclutter, + unicodechecker: Unicodechecker, + "unity hub": UnityHub, + updf: Updf, + upscayl: Upscayl, + usage: UsageApp, utm: Utm, vanilla: Vanilla, vellum: Vellum, diff --git a/website/assets/images/app-icon-ua-connect-60x60@2x.png b/website/assets/images/app-icon-ua-connect-60x60@2x.png new file mode 100644 index 00000000000..0dc1e89499b Binary files /dev/null and b/website/assets/images/app-icon-ua-connect-60x60@2x.png differ diff --git a/website/assets/images/app-icon-ukelele-60x60@2x.png b/website/assets/images/app-icon-ukelele-60x60@2x.png new file mode 100644 index 00000000000..dbb03f66836 Binary files /dev/null and b/website/assets/images/app-icon-ukelele-60x60@2x.png differ diff --git a/website/assets/images/app-icon-ultimaker-cura-60x60@2x.png b/website/assets/images/app-icon-ultimaker-cura-60x60@2x.png new file mode 100644 index 00000000000..629bf5bdb57 Binary files /dev/null and b/website/assets/images/app-icon-ultimaker-cura-60x60@2x.png differ diff --git a/website/assets/images/app-icon-unclutter-60x60@2x.png b/website/assets/images/app-icon-unclutter-60x60@2x.png new file mode 100644 index 00000000000..8f8c0c81908 Binary files /dev/null and b/website/assets/images/app-icon-unclutter-60x60@2x.png differ diff --git a/website/assets/images/app-icon-unicodechecker-60x60@2x.png b/website/assets/images/app-icon-unicodechecker-60x60@2x.png new file mode 100644 index 00000000000..04a814fd992 Binary files /dev/null and b/website/assets/images/app-icon-unicodechecker-60x60@2x.png differ diff --git a/website/assets/images/app-icon-unity-hub-60x60@2x.png b/website/assets/images/app-icon-unity-hub-60x60@2x.png new file mode 100644 index 00000000000..5bccf853044 Binary files /dev/null and b/website/assets/images/app-icon-unity-hub-60x60@2x.png differ diff --git a/website/assets/images/app-icon-updf-60x60@2x.png b/website/assets/images/app-icon-updf-60x60@2x.png new file mode 100644 index 00000000000..975aaa95fe2 Binary files /dev/null and b/website/assets/images/app-icon-updf-60x60@2x.png differ diff --git a/website/assets/images/app-icon-upscayl-60x60@2x.png b/website/assets/images/app-icon-upscayl-60x60@2x.png new file mode 100644 index 00000000000..12b7d13d089 Binary files /dev/null and b/website/assets/images/app-icon-upscayl-60x60@2x.png differ diff --git a/website/assets/images/app-icon-usage-app-60x60@2x.png b/website/assets/images/app-icon-usage-app-60x60@2x.png new file mode 100644 index 00000000000..4656859a922 Binary files /dev/null and b/website/assets/images/app-icon-usage-app-60x60@2x.png differ