antony-jr / appimageupdater Goto Github PK
View Code? Open in Web Editor NEWAppImage Updater for Humans built with QML/C++ with Qt5 :heart:.
License: GNU Lesser General Public License v3.0
AppImage Updater for Humans built with QML/C++ with Qt5 :heart:.
License: GNU Lesser General Public License v3.0
It would be nice to have the ability to invoke AppImageUpdater from the CLI and pass the AppImage that you want it to update.
Usecase:
$ ./AppImageUpdater.AppImage FreeCAD_0.19-18614.AppImage
Bonus: add a flag that automatically quits AppImageUpdater after it successfully completes its task.
Since only KDE and other few Desktop environments supports decent system tray icons. In other desktop environments this causes the application to continue running in the background but cannot open it or close it. So I think it's only logically to make the system tray opt-in.
Of course design is a subjective subject, so it's entirely up to you - but I think it would greatly help the adoption of the updater if it would look as minimalistic, "generic" as possible, trying to blend in with the native theme of Qt/the system rather than using bold/dark colors, large/custom fonts and such.
For example, the Sparkle framework is carefully designed to look as "native" and unobtrusive as possible on macOS:
This feels "seamless", "straightforward", and "lightweight" to me, and basically looks like it was coming from the system. If I was an application author, I would want this minimalistic and unobtrusive kind of "native" look for the updater.
Note that it does not say ".app .dmg Updater" or something like that, because that are technical details normal users are not interested in. Likewise, we do not need to say "AppImage Updater" or anything like that, just "Updating Subsurface", "Checking for updates...", etc. Also, I like how they use the application icon to make the updater look like a part of the application.
Downloads/AppImageUpdater-77e112e-x86_64.AppImage Downloads/Audacity-095ee91-x86_64.AppImage
Intended result:
In addition to the original (old) file Downloads/Audacity-095ee91-x86_64.AppImage
, there should be the updated (new) file Downloads/<FILENAME_OF_THE_NEW_FILE>
.
Actual result:
me@host:~$ diff Downloads/Audacity-095ee91-x86_64.AppImage*
Binary files Downloads/Audacity-095ee91-x86_64.AppImage and Downloads/Audacity-095ee91-x86_64.AppImage.zs-old differ
Updated file must also get the new name, otherwise the file name is misleading.
"Updater" button in the bottom left seemingly does nothing when clicked. It is unclear what it is supposed to do as well, so maybe it can be removed. Let's simplify as much as possible.
These "i" icons are added by AppImageUpdater to my menu bar and do absolutely nothing on my Xfce system. When I click on them, nothing happens. Right-click gives me Xfce's option to remove them. Personally I find them (and desktop notifications) rather annoying.
What do others think? Maybe I am missing how these things are adding value?
This is on Xubuntu 18.04, where these things are managed by:
This may have something to do with the way FreeCAD releases but here goes:
When I run AppImageUpdater-9b4000e-x86_64.AppImage
on: https://github.com/FreeCAD/FreeCAD/releases/tag/0.19_pre
specifically the current
FreeCAD_0.19-18614-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage (Note: link may not work if new version is released),
AppImageUpdater is downloading the same version and labeling it:
FreeCAD_0-revised-on-2019-10-30T07-52-00.19-18614-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage
to be clear, I'm updating a previously downloaded appimage: FreeCAD_0.19-18614-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage
Please do not create "revised-on" if we already have the "new" file, and it is the exact same file (as per its hash) as the "revised-on" one.
Example:
# This is what I already have locally
me@host:~/test$ ls
AppImageUpdater-7420c48-x86_64.AppImage AppImageUpdater-9b4000e-x86_64.AppImage
# This is the command. Note that I am trying to update the older AppImage (9b4000e) despite that I already have the currently latest version (7420c48):
me@host:~/test$ ./AppImageUpdater-7420c48-x86_64.AppImage -n -d ./AppImageUpdater-9b4000e-x86
# This is the result
me@host:~/test$ ls
AppImageUpdater-7420c48-x86_64.AppImage
AppImageUpdater-7420c48-x86_64-revised-on-2019-11-10T13-33-00.AppImage
AppImageUpdater-9b4000e-x86_64.AppImage
# The two files are identical:
me@host:~/test$ diff *7420c48*
me@host:~/test$
In this case, I do not need a second copy of what I already have. Only the mtime of AppImageUpdater-7420c48-x86_64.AppImage
should maybe be updated to reflect that we had worked on this version, although this is debatable.
Trying
Downloads/AppImageUpdater-77e112e-x86_64.AppImage /isodevice/Applications/appimagetool-x86_64.AppImage
Getting
Unable to update appimagetool-x86_64.AppImage because of unknow network interruption
Additional information:
strings /isodevice/Applications/appimagetool-x86_64.AppImage | grep zsyǹc
zsync|https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage.zsync
Note: Also notice that the title of the AppImage is truncated FreeCAD_0
Source AppImage: https://github.com/FreeCAD/FreeCAD/releases/tag/0.19_pre
Using AppImageUpdater-ff9ee1f-x86_64.AppImage
Not an issue, just to let you know how I have integrated AppImageUpdater into my experimental go-appimage appimaged
daemon:
https://www.youtube.com/watch?v=L00UjifUEfE
Thanks for this useful software. 👍
The updater should give a clear message if GitHub Release does not have an AppImage
Test file:
OldImageMagick-git.7a48608-x86_64.AppImage.zip
For comparison, AppImageUpdate says:
me@host:~$ /isodevice/Applications/AppImageUpdate-185-1c72f3b-x86_64.AppImage OldImageMagick-git.7a48608-x86_64.AppImage
AppImageUpdate version 1-alpha (commit 1c72f3b), build 185 built on 2018-01-03 16:41:48 UTC
Checking for updates...
Fetching release information for tag "continuous" from GitHub API.
GitHub API request failed!
Could not find any artifacts in release data. Please contact the author of the AppImage and tell them the files are missing on the releases page.
ZSync URL not available. See previous messages for details.
Hallo @antony-jr thanks for your great work on AppImageUpdater. 👍
One thing I am really less than thrilled about
Material Design
I would not want to put AppImageUpdater into my Qt based desktop applications if it doesn't look like the rest of the application. Let's make AppImageUpdater look and feel "native" to the desktop, not like an "alien" piece coming from Android.
Thanks for your consideration!
Separating this out of #18 (comment)
As seen in AppImageCommunity/AppImageUpdate#128 (comment)
CC: @luzpaz
Lets do any further discussions here to keep everything organized.
It would be nice if AppImageUpdater would print some verbose statements on the command line while it is working, e.g., when invoked with -v
or -verbose
, so that one could understand what it is trying to do (e.g., from which URLs it is trying to download).
Last version 2.0.0 has seqmentation fault, 2.0.0beta1 hasn't got faults except the need to launch it with export QT_STYLE_OVERRIDE=Fusion
OR -style=Fusion
.
Linux userpc 5.4.0-72-generic #80~18.04.1-Ubuntu SMP Mon Apr 12 XXX 2021 x86_64 x86_64 x86_64 GNU/Linux
OS: elementaryOS 5.12.9 Hera(Ubuntu 18.04 w/o any Qt installed)
echo $QT_QPA_PLATFORMTHEME
``— empty, /home/user/.AppImageUpdater.lock and /home/user/core files — deleted.
openat(AT_FDCWD, "/etc/os-release", O_RDONLY|O_CLOEXEC) = 12 fstat(12, {st_mode=S_IFREG|0644, st_size=393, ...}) = 0 read(12, "NAME=\"elementary OS\"\nVERSION=\"5."..., 393) = 393 close(12) = 0 write(11, "\1\0\0\0\0\0\0\0", 8) = 8 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x20a5e70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x209d360, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x209d364, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x209d310, FUTEX_WAKE_PRIVATE, 1) = 0 brk(0x212a000) = 0x212a000 access("/home/user/squashfs-root/usr/plugins/xcbglintegrations/.", F_OK) = 0 openat(AT_FDCWD, "/home/user/squashfs-root/usr/plugins/xcbglintegrations", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 12 fstat(12, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 getdents(12, /* 3 entries */, 32768) = 96 getdents(12, /* 0 entries */, 32768) = 0 close(12) = 0 lstat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/home/user", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 lstat("/home/user/squashfs-root", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/home/user/squashfs-root/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/home/user/squashfs-root/usr/plugins", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/home/user/squashfs-root/usr/plugins/xcbglintegrations", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 lstat("/home/user/squashfs-root/usr/plugins/xcbglintegrations/libqxcb-glx-integration.so", {st_mode=S_IFREG|0644, st_size=74416, ...}) = 0 openat(AT_FDCWD, "/home/user/squashfs-root/usr/plugins/xcbglintegrations/libqxcb-glx-integration.so", O_RDONLY|O_CLOEXEC) = 12 fstat(12, {st_mode=S_IFREG|0644, st_size=74416, ...}) = 0 fstat(12, {st_mode=S_IFREG|0644, st_size=74416, ...}) = 0 mmap(NULL, 74416, PROT_READ, MAP_SHARED, 12, 0) = 0x7fafaf5da000 close(12) = 0 munmap(0x7fafaf5da000, 74416) = 0 access("/home/user/squashfs-root/usr/bin/xcbglintegrations/.", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/home/user/squashfs-root/usr/plugins/xcbglintegrations/libqxcb-glx-integration.so.avx2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) access("/home/user/squashfs-root/usr/plugins/xcbglintegrations/libqxcb-glx-integration.so.avx2", F_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/home/user/squashfs-root/usr/plugins/xcbglintegrations/libqxcb-glx-integration.so", O_RDONLY|O_CLOEXEC) = 12 read(12, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832 fstat(12, {st_mode=S_IFREG|0644, st_size=74416, ...}) = 0 mmap(NULL, 76184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 12, 0) = 0x7fafaf5da000 mmap(0x7fafaf5eb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 12, 0x10000) = 0x7fafaf5eb000 close(12) = 0 mprotect(0x7fafaf5eb000, 4096, PROT_READ) = 0 poll([{fd=3, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=3, revents=POLLOUT}]) writev(3, [{iov_base="b\0\3\0\3\0\0\0GLX\0", iov_len=12}], 1) = 12 futex(0x7ffd2d58bf58, FUTEX_WAIT_PRIVATE, 0, NULL) = 0 futex(0x2058068, FUTEX_WAKE_PRIVATE, 1) = 0 poll([{fd=3, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=3, revents=POLLOUT}]) writev(3, [{iov_base="\230\7\3\0\1\0\0\0\4\0\0\0", iov_len=12}], 1) = 12 futex(0x2058068, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x2058068, FUTEX_WAKE_PRIVATE, 1) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x30535f4d4f} --- +++ killed by SIGSEGV (core dumped) +++ zsh: segmentation fault strace ~/squashfs-root/AppRun
wget -c "https://github.com/antony-jr/AppImageUpdater/releases/download/continuous/AppImageUpdater-bcdadb8-x86_64.AppImage"
chmod +x AppImageUpdater-bcdadb8-x86_64.AppImage
# Get "old" AppImage
wget -c "https://gitlab.com/probono/QtQuickApp/-/jobs/73879740/artifacts/raw/QtQuickApp-x86_64.AppImage"
# Try to update it
./AppImageUpdater-bcdadb8-x86_64.AppImage ./QtQuickApp-x86_64.AppImage
No protocol specified
QAIUpdateInformation:: "zsync|https://gitlab.com/probono/QtQuickApp/-/jobs/artifacts/master/raw/QtQuickApp-x86_64.AppImage.zsync?job=trusty"
AIUpdaterBridge:: zsyncURL :: QUrl("https://gitlab.com/probono/QtQuickApp/-/jobs/artifacts/master/raw/QtQuickApp-x86_64.AppImage.zsync?job=trusty") :: "./QtQuickApp-x86_64.AppImage"
AIUpdaterBridge::GOT:: zsync headers :: success!
AIUpdaterBridge:: your version of appimage is older:: "769ad296e9c0624e6e62583fede4c3e7e36b7494"
AIUpdaterBridge:: redirected url :: QUrl("https://gitlab.com/probono/QtQuickApp/-/jobs/artifacts/master/raw/?job=trustyQtQuickApp-x86_64.AppImage")
QNetworkReplyImplPrivate::error: Internal problem, this method must only be called once.
AIUpdaterBridge:: new updates available :: "3cf0c53ba08c31310cb0665cf4e7eb7243f86cc3"
AIUpdaterBridge:: got everything :: Updating
EOF from serverOther error? -1
AIUpdaterBridge:: zsync recieve failed :: "./QtQuickApp-x86_64.AppImage"
AIUpdaterBridge:: redirected url :
is wrong.
appimageupdatetool
has an option to simply check if there is an update. This would be very helpful if we're invoking appImageupdater
from a script.
-j, --check-for-update Check for update. Exits with code 1 if
changes are available, 0 if there are
not,other non-zero code in case of
errors.
Thanks for all you effort!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.