├── QAppImageUpdate.json ├── website ├── versions.json ├── static │ ├── img │ │ ├── bin.png │ │ ├── qt.png │ │ ├── light.png │ │ ├── favicon.png │ │ ├── clean_code.png │ │ ├── e2designer.png │ │ ├── AppImageUpdater.png │ │ ├── favicon │ │ │ └── favicon.ico │ │ ├── updatedeployqt.png │ │ └── AppImageUpdaterBridge.png │ └── css │ │ └── custom.css ├── sidebars.json ├── package.json ├── versioned_sidebars │ ├── version-2.0.0-sidebars.json │ └── version-1.1.9-sidebars.json ├── versioned_docs │ ├── version-2.0.0 │ │ ├── BuildingTests.md │ │ ├── Installation.md │ │ ├── SimpleExample.md │ │ ├── GUIExample.md │ │ ├── TorrentExample.md │ │ ├── UsingPlugin.md │ │ ├── ProxyUpdateExample.md │ │ ├── PyQt5PluginExample.md │ │ ├── ErrorCodes.md │ │ └── AddingQAppImageUpdate.md │ └── version-1.1.9 │ │ ├── Installation.md │ │ ├── AppImageUpdaterDialogExample.md │ │ ├── AppImageDeltaRevisionerExample.md │ │ ├── UsingPlugin.md │ │ ├── AppImageProxyUpdateExample.md │ │ ├── AppImageUpdaterBridgeStatusCodes.md │ │ ├── PyQt5PluginExample.md │ │ ├── AppImageUpdaterBridgeErrorCodes.md │ │ └── AddingAppImageUpdaterBridge.md ├── pages │ └── en │ │ ├── users.js │ │ ├── help.js │ │ ├── versions.js │ │ └── index.js ├── siteConfig.js └── core │ └── Footer.js ├── .img └── logo.png ├── tests ├── main.cc ├── tests.pro ├── CMakeLists.txt └── SimpleDownload.hpp ├── examples ├── Update │ ├── Update.pro │ ├── CMakeLists.txt │ └── main.cc ├── UpdateWithGUI │ ├── Update.pro │ ├── CMakeLists.txt │ └── main.cc ├── UpdateWithTorrent │ ├── Update.pro │ ├── CMakeLists.txt │ └── main.cc ├── UpdateWithGUIAndTorrent │ ├── Update.pro │ ├── CMakeLists.txt │ └── main.cc ├── CheckForUpdate │ ├── CheckForUpdate.pro │ ├── CMakeLists.txt │ └── main.cc ├── ProxyUpdate │ ├── ProxyUpdate.pro │ ├── CMakeLists.txt │ └── main.cc ├── GetEmbeddedInfo │ ├── GetEmbeddedInfo.pro │ ├── CMakeLists.txt │ └── main.cc ├── PyQt5Update │ └── Update.py └── PyQt5UpdateWithTorrent │ └── Update.py ├── .gitignore ├── other ├── cmake │ └── QAppImageUpdateConfig.cmake.in └── pkgconfig │ └── QAppImageUpdate.pc.in ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── link.txt └── workflows │ └── test-and-deploy.yml ├── include ├── helpers_p.hpp ├── seeder.hpp ├── rangereply.hpp ├── rangedownloader.hpp ├── torrentdownloader.hpp ├── softwareupdatedialog_p.hpp ├── qappimageupdatecodes.hpp ├── rangereply_p.hpp ├── seeder_p.hpp ├── qappimageupdateinterface.hpp ├── qappimageupdateinterfaceimpl.hpp ├── qappimageupdate.hpp ├── rangedownloader_p.hpp ├── torrentdownloader_p.hpp ├── zsyncinternalstructures_p.hpp ├── appimageupdateinformation_p.hpp ├── SoftwareUpdateDialog.ui ├── qappimageupdate_p.hpp ├── zsyncremotecontrolfileparser_p.hpp └── qappimageupdateenums.hpp ├── docs ├── BuildingTests.md ├── SimpleExample.md ├── Installation.md ├── GUIExample.md ├── TorrentExample.md ├── UsingPlugin.md ├── ProxyUpdateExample.md ├── PyQt5PluginExample.md └── ErrorCodes.md ├── src ├── seeder.cc ├── rangereply.cc ├── helpers_p.cc ├── torrentdownloader.cc ├── rangedownloader.cc ├── AppImageUpdaterDialog.ui ├── softwareupdatedialog_p.cc └── qappimageupdate.cc ├── LICENSE ├── QAppImageUpdate.pro ├── QAppImageUpdate ├── scripts └── docker_build.sh ├── QAppImageUpdate.pri └── CMakeLists.txt /QAppImageUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "QAppImageUpdate" 3 | } 4 | -------------------------------------------------------------------------------- /website/versions.json: -------------------------------------------------------------------------------- 1 | [ 2 | "2.0.1", 3 | "2.0.0", 4 | "1.1.9" 5 | ] 6 | -------------------------------------------------------------------------------- /.img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/.img/logo.png -------------------------------------------------------------------------------- /website/static/img/bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/bin.png -------------------------------------------------------------------------------- /website/static/img/qt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/qt.png -------------------------------------------------------------------------------- /website/static/img/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/light.png -------------------------------------------------------------------------------- /tests/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | QTEST_MAIN(QAppImageUpdateTests); 5 | 6 | -------------------------------------------------------------------------------- /website/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/favicon.png -------------------------------------------------------------------------------- /website/static/img/clean_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/clean_code.png -------------------------------------------------------------------------------- /website/static/img/e2designer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/e2designer.png -------------------------------------------------------------------------------- /website/static/img/AppImageUpdater.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/AppImageUpdater.png -------------------------------------------------------------------------------- /website/static/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/favicon/favicon.ico -------------------------------------------------------------------------------- /website/static/img/updatedeployqt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/updatedeployqt.png -------------------------------------------------------------------------------- /examples/Update/Update.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = Update 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /website/static/img/AppImageUpdaterBridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antony-jr/QAppImageUpdate/HEAD/website/static/img/AppImageUpdaterBridge.png -------------------------------------------------------------------------------- /examples/UpdateWithGUI/Update.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = Update 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /examples/UpdateWithTorrent/Update.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = Update 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /examples/UpdateWithGUIAndTorrent/Update.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = Update 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /examples/CheckForUpdate/CheckForUpdate.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = CheckForUpdate 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /examples/ProxyUpdate/ProxyUpdate.pro: -------------------------------------------------------------------------------- 1 | include(../../AppImageUpdaterBridge.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = ProxyUpdate 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /examples/GetEmbeddedInfo/GetEmbeddedInfo.pro: -------------------------------------------------------------------------------- 1 | include(../../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | TEMPLATE = app 4 | TARGET = GetEmbeddedInfo 5 | 6 | SOURCES += main.cc 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | lib/core/metadata.js 4 | lib/core/MetadataBlog.js 5 | website/translated_docs 6 | website/build/ 7 | website/yarn.lock 8 | website/node_modules 9 | 10 | website/i18n/* 11 | !website/i18n/en.json 12 | -------------------------------------------------------------------------------- /tests/tests.pro: -------------------------------------------------------------------------------- 1 | include(../QAppImageUpdate.pri) 2 | INCLUDEPATH += . 3 | CONFIG += release 4 | TARGET = tests 5 | QT += testlib concurrent 6 | SOURCES += main.cc 7 | HEADERS += QAppImageUpdateTests.hpp SimpleDownload.hpp 8 | 9 | QUICK_TEST { 10 | DEFINES += QUICK_TEST 11 | } 12 | -------------------------------------------------------------------------------- /other/cmake/QAppImageUpdateConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include(CMakeFindDependencyMacro) 4 | find_dependency(Qt5Core @MIN_QT_VERSION@) 5 | find_dependency(Qt5Network @MIN_QT_VERSION@) 6 | @PACKAGE_FIND_DEPENDENCY_QTWIDGETS@ 7 | 8 | include("${CMAKE_CURRENT_LIST_DIR}/QAppImageUpdateTargets.cmake") 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | **Select your issue type:** (check at least one) 5 | - [ ] Bug 6 | - [ ] Question 7 | - [ ] Suggestion 8 | - [ ] Other (please describe): 9 | 10 | **Describe your issue:** 11 | 12 | **Ways to Reproduce the issue (optional):** 13 | -------------------------------------------------------------------------------- /include/helpers_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef HELPERS_PRIVATE_HPP_INCLUDED 2 | #define HELPERS_PRIVATE_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | QMetaMethod getMethod(QObject*,const char*); 9 | short translateQNetworkReplyError(QNetworkReply::NetworkError); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **What kind of change does this pull request introduce?** (check at least one) 4 | 5 | - [ ] Bugfix 6 | - [ ] Feature 7 | - [ ] Code style update 8 | - [ ] Refactor 9 | - [ ] Build-related changes 10 | - [ ] Other, please describe: 11 | 12 | **Describe your Pull Request:** 13 | -------------------------------------------------------------------------------- /other/pkgconfig/QAppImageUpdate.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/QAppImageUpdate 4 | 5 | Name: QAppImageUpdate 6 | Description: A Qt5 library for delta updating the AppImage format 7 | Version: @PROJECT_VERSION@ 8 | Libs: -L${libdir} -lQAppImageUpdate 9 | Cflags: -I${includedir} 10 | -------------------------------------------------------------------------------- /website/static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* your custom css */ 2 | 3 | @media only screen and (min-device-width: 360px) and (max-device-width: 736px) { 4 | } 5 | 6 | @media only screen and (min-width: 1024px) { 7 | } 8 | 9 | @media only screen and (max-width: 1023px) { 10 | } 11 | 12 | @media only screen and (min-width: 1400px) { 13 | } 14 | 15 | @media only screen and (min-width: 1500px) { 16 | } -------------------------------------------------------------------------------- /website/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": { 3 | "Getting Started": [ 4 | "Installation", 5 | "AddingQAppImageUpdate", 6 | "BuildingTests", 7 | "UsingPlugin" 8 | ], 9 | "Guides" : [ 10 | "SimpleExample", 11 | "ProxyExample", 12 | "GUIExample", 13 | "PyQt5PluginExample", 14 | "TorrentExample" 15 | ], 16 | "API" : [ 17 | "ErrorCodes", 18 | "ClassQAppImageUpdate", 19 | "PluginInterface" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "examples": "docusaurus-examples", 4 | "start": "docusaurus-start", 5 | "build": "docusaurus-build", 6 | "publish-gh-pages": "docusaurus-publish", 7 | "write-translations": "docusaurus-write-translations", 8 | "version": "docusaurus-version", 9 | "rename-version": "docusaurus-rename-version" 10 | }, 11 | "devDependencies": { 12 | "docusaurus": "^1.14.4" 13 | }, 14 | "version": "2.0.1" 15 | } 16 | -------------------------------------------------------------------------------- /examples/Update/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(Update) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(Update main.cc) 22 | target_link_libraries(Update PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /examples/ProxyUpdate/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(ProxyUpdate) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(ProxyUpdate main.cc) 22 | target_link_libraries(ProxyUpdate PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /examples/CheckForUpdate/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(CheckForUpdate) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(CheckForUpdate main.cc) 22 | target_link_libraries(CheckForUpdate PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /examples/UpdateWithGUI/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(UpdateWithGUI) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(UpdateWithGUI main.cc) 22 | target_link_libraries(UpdateWithGUI PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /examples/GetEmbeddedInfo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(GetEmbeddedInfo) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(GetEmbeddedInfo main.cc) 22 | target_link_libraries(GetEmbeddedInfo PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /.github/link.txt: -------------------------------------------------------------------------------- 1 | download openssl 2 | cd openssl 3 | ./config no-shared 4 | make -j$(nproc) 5 | sudo make install 6 | 7 | download boost 8 | cd boost 9 | ./bootstrap.sh 10 | sudo cp b2 /usr/bin/ 11 | echo "using gcc ;" > ~/user-config.jam 12 | b2 cxxflags="-std=c++14" -j4 install --with-system 13 | 14 | cd .. 15 | download libtorrent-rasterbar 16 | cd libtorrent-rasterbar 17 | export BOOST_ROOT=/home/user/boost/ 18 | export BOOST_BUILD_PATH=/home/user/boost/tools/build/ 19 | b2 cxxflags="-std=c++14" variant=release boost-link=static link=static fpic=on crypto=openssl runtime-link=static install -j4 20 | # Now static version of libtorrent should been installed. 21 | -------------------------------------------------------------------------------- /examples/UpdateWithTorrent/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(UpdateWithTorrent) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(UpdateWithTorrent main.cc) 22 | target_link_libraries(UpdateWithTorrent PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /examples/UpdateWithGUIAndTorrent/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(UpdateWithGUIAndTorrent) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_EXAMPLES) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | 17 | # Include Directories. 18 | include_directories(.) 19 | include_directories(${CMAKE_BINARY_DIR}) 20 | 21 | add_executable(UpdateWithGUIAndTorrent main.cc) 22 | target_link_libraries(UpdateWithGUIAndTorrent PRIVATE QAppImageUpdate) 23 | -------------------------------------------------------------------------------- /docs/BuildingTests.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: BuildingTests 3 | title: Building QAppImageUpdate Unit Tests 4 | sidebar_label: Building Tests 5 | --- 6 | 7 | Running the entire unit tests requires **lot of bandwidth**,**hard drive space** and **cpu time.** 8 | You can however run a quick tests to make sure everything works somewhat okay. 9 | 10 | To build and run the tests from CMake, do the following. 11 | 12 | ``` 13 | $ cd QAppImageUpdate 14 | $ mkdir build 15 | $ cd build 16 | $ cmake -DBUILD_TESTS=ON .. 17 | $ make -j$(nproc) 18 | $ ./tests/QAppImageUpdateTests 19 | ``` 20 | 21 | 22 | **For a Quick Test**. 23 | 24 | ``` 25 | $ cmake -DBUILD_TESTS=ON -DQUICK_TEST=ON .. 26 | ``` 27 | 28 | 29 | -------------------------------------------------------------------------------- /website/versioned_sidebars/version-2.0.0-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "version-2.0.0-docs": { 3 | "Getting Started": [ 4 | "version-2.0.0-Installation", 5 | "version-2.0.0-AddingQAppImageUpdate", 6 | "version-2.0.0-BuildingTests", 7 | "version-2.0.0-UsingPlugin" 8 | ], 9 | "Guides": [ 10 | "version-2.0.0-SimpleExample", 11 | "version-2.0.0-ProxyExample", 12 | "version-2.0.0-GUIExample", 13 | "version-2.0.0-PyQt5PluginExample", 14 | "version-2.0.0-TorrentExample" 15 | ], 16 | "API": [ 17 | "version-2.0.0-ErrorCodes", 18 | "version-2.0.0-ClassQAppImageUpdate", 19 | "version-2.0.0-PluginInterface" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/BuildingTests.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-BuildingTests 3 | title: Building QAppImageUpdate Unit Tests 4 | sidebar_label: Building Tests 5 | original_id: BuildingTests 6 | --- 7 | 8 | Running the entire unit tests requires **lot of bandwidth**,**hard drive space** and **cpu time.** 9 | You can however run a quick tests to make sure everything works somewhat okay. 10 | 11 | To build and run the tests from CMake, do the following. 12 | 13 | ``` 14 | $ cd QAppImageUpdate 15 | $ mkdir build 16 | $ cd build 17 | $ cmake -DBUILD_TESTS=ON .. 18 | $ make -j$(nproc) 19 | $ ./tests/QAppImageUpdateTests 20 | ``` 21 | 22 | 23 | **For a Quick Test**. 24 | 25 | ``` 26 | $ cmake -DBUILD_TESTS=ON -DQUICK_TEST=ON .. 27 | ``` 28 | 29 | 30 | -------------------------------------------------------------------------------- /include/seeder.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SEEDER_HPP_INCLUDED 2 | #define SEEDER_HPP_INCLUDED 3 | #ifdef DECENTRALIZED_UPDATE_ENABLED 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class SeederPrivate; 11 | 12 | class Seeder : public QObject { 13 | Q_OBJECT 14 | QSharedPointer m_Private; 15 | public: 16 | Seeder(QNetworkAccessManager*, QObject *parent = nullptr); 17 | public Q_SLOTS: 18 | void start(QJsonObject); 19 | void cancel(); 20 | Q_SIGNALS: 21 | void started(); 22 | void canceled(); 23 | void error(short); 24 | 25 | void logger(QString); 26 | void torrentStatus(int,int); 27 | }; 28 | #endif // DECENTRALIZED_UPDATE_ENABLED 29 | #endif // SEEDER_HPP_INCLUDED 30 | -------------------------------------------------------------------------------- /website/versioned_sidebars/version-1.1.9-sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "version-1.1.9-docs": { 3 | "Getting Started": [ 4 | "version-1.1.9-Installation", 5 | "version-1.1.9-AddingAppImageUpdaterBridge", 6 | "version-1.1.9-UsingPlugin" 7 | ], 8 | "Guides": [ 9 | "version-1.1.9-AppImageDeltaRevisionerExample", 10 | "version-1.1.9-AppImageDeltaRevisionerProxyExample", 11 | "version-1.1.9-AppImageUpdaterDialogExample", 12 | "version-1.1.9-PyQt5PluginExample" 13 | ], 14 | "API": [ 15 | "version-1.1.9-AppImageUpdaterBridgeErrorCodes", 16 | "version-1.1.9-AppImageUpdaterBridgeStatusCodes", 17 | "version-1.1.9-ClassAppImageDeltaRevisioner", 18 | "version-1.1.9-ClassAppImageUpdaterDialog", 19 | "version-1.1.9-PluginInterface" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /include/rangereply.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGE_REPLY_HPP_INCLUDED 2 | #define RANGE_REPLY_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | 7 | class RangeReplyPrivate; // Forward Declare. 8 | 9 | class RangeReply : public QObject { 10 | Q_OBJECT 11 | QSharedPointer m_Private; 12 | public: 13 | RangeReply(int, QNetworkReply*, const QPair&); 14 | ~RangeReply(); 15 | public Q_SLOTS: 16 | void destroy(); 17 | void retry(int timeout = 3000); 18 | void cancel(); 19 | Q_SIGNALS: 20 | void restarted(int); 21 | void error(QNetworkReply::NetworkError, int, bool); 22 | void progress(qint64, int); 23 | void data(QByteArray*, bool); 24 | void finished(qint32,qint32, QByteArray*, int); 25 | void canceled(int); 26 | }; 27 | #endif // RANGE_REPLY_HPP_INCLUDED 28 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(QAppImageUpdateTests VERSION 2.0.0) 3 | 4 | set(CMAKE_CXX_STANDARD 11) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 10 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 11 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 12 | 13 | if(NOT BUILD_TESTS) 14 | find_package(QAppImageUpdate) 15 | endif() 16 | find_package(Qt5Test) 17 | find_package(Qt5Concurrent) 18 | 19 | # Include Directories. 20 | include_directories(.) 21 | include_directories(${CMAKE_BINARY_DIR}) 22 | 23 | if(QUICK_TEST) 24 | add_definitions(-DQUICK_TEST) 25 | endif() 26 | 27 | if(DECENTRALIZED_UPDATE_ENABLED) 28 | message("-- [*] IMPORTANT: Decentralized update feature will be TESTED.") 29 | add_definitions(-DDECENTRALIZED_UPDATE_ENABLED) 30 | endif() 31 | 32 | add_executable(QAppImageUpdateTests main.cc QAppImageUpdateTests.hpp SimpleDownload.hpp) 33 | target_link_libraries(QAppImageUpdateTests PRIVATE QAppImageUpdate Qt5::Test Qt5::Concurrent) 34 | -------------------------------------------------------------------------------- /include/rangedownloader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGE_DOWNLOADER_HPP_INCLUDED 2 | #define RANGE_DOWNLOADER_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class RangeDownloaderPrivate; 9 | 10 | class RangeDownloader : public QObject { 11 | Q_OBJECT 12 | QSharedPointer m_Private; 13 | public: 14 | RangeDownloader(QNetworkAccessManager*, QObject *parent = nullptr); 15 | public Q_SLOTS: 16 | void setBlockSize(qint32); 17 | void setTargetFileUrl(const QUrl&); 18 | void setTargetFileLength(qint32); 19 | void setBytesWritten(qint64); 20 | void setFullDownload(bool); 21 | void appendRange(qint32, qint32); 22 | 23 | void start(); 24 | void cancel(); 25 | Q_SIGNALS: 26 | void started(); 27 | void canceled(); 28 | void finished(); 29 | void error(QNetworkReply::NetworkError); 30 | 31 | void data(QByteArray *, bool); 32 | void rangeData(qint32, qint32, QByteArray *,bool); 33 | void progress(int, qint64, qint64, double, QString); 34 | }; 35 | #endif // RANGE_DOWNLOADER_HPP_INCLUDED 36 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-Installation 3 | title: Installing AppImage Updater Bridge to your Project. 4 | sidebar_label: Installation 5 | original_id: Installation 6 | --- 7 | 8 | Since AppImage Updater Birdge is specifically made for Qt , All you need is Qt's development tools 9 | and only that, Nothing more and nothing less. 10 | 11 | ## Dependencies 12 | 13 | * [Qt5 Framework](https://qt.io) 14 | 15 | 16 | ## Installing the latest release from github 17 | 18 | **Just execute this command on your project folder and everything will be done for you!** 19 | You must have **git** to do this , **don't worry** because most of the linux distro's must 20 | have **installed it already** for you , if not install it! 21 | 22 | ``` 23 | $ git clone https://github.com/antony-jr/AppImageUpdaterBridge 24 | ``` 25 | 26 | or **to install it in your git project folder** 27 | 28 | ``` 29 | $ git submodule init 30 | $ git submodule add https://github.com/antony-jr/AppImageUpdaterBridge 31 | $ git submodule update 32 | ``` 33 | 34 | Even though AppImage is specific to linux , this library is cross platform. 35 | -------------------------------------------------------------------------------- /include/torrentdownloader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TORRENT_DOWNLOADER_HPP_INCLUDED 2 | #define TORRENT_DOWNLOADER_HPP_INCLUDED 3 | #ifdef DECENTRALIZED_UPDATE_ENABLED 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class TorrentDownloaderPrivate; 11 | 12 | class TorrentDownloader : public QObject { 13 | Q_OBJECT 14 | QSharedPointer m_Private; 15 | public: 16 | TorrentDownloader(QNetworkAccessManager*, QObject *parent = nullptr); 17 | public Q_SLOTS: 18 | void setTargetFileDone(qint64); 19 | void setTargetFileLength(qint64); 20 | void setTargetFile(QTemporaryFile*); 21 | void setTorrentFileUrl(const QUrl&); 22 | void setTargetFileUrl(const QUrl&); 23 | 24 | void start(); 25 | void cancel(); 26 | Q_SIGNALS: 27 | void started(); 28 | void canceled(); 29 | void finished(); 30 | void error(QNetworkReply::NetworkError); 31 | 32 | void logger(QString); 33 | void progress(int, qint64, qint64, double, QString); 34 | void torrentStatus(int,int); 35 | }; 36 | #endif // DECENTRALIZED_UPDATE_ENABLED 37 | #endif // TORRENT_DOWNLOADER_HPP_INCLUDED 38 | -------------------------------------------------------------------------------- /src/seeder.cc: -------------------------------------------------------------------------------- 1 | #ifdef DECENTRALIZED_UPDATE_ENABLED 2 | #include "seeder.hpp" 3 | #include "seeder_p.hpp" 4 | #include "helpers_p.hpp" 5 | 6 | Seeder::Seeder(QNetworkAccessManager *manager, QObject *parent) 7 | : QObject(parent) { 8 | m_Private = QSharedPointer(new SeederPrivate(manager)); 9 | auto obj = m_Private.data(); 10 | 11 | connect(obj, &SeederPrivate::started, 12 | this, &Seeder::started, 13 | Qt::DirectConnection); 14 | 15 | connect(obj, &SeederPrivate::canceled, 16 | this, &Seeder::canceled, 17 | Qt::DirectConnection); 18 | 19 | connect(obj, &SeederPrivate::error, 20 | this, &Seeder::error, 21 | Qt::DirectConnection); 22 | 23 | connect(obj, &SeederPrivate::logger, 24 | this, &Seeder::logger, 25 | Qt::DirectConnection); 26 | 27 | connect(obj, &SeederPrivate::torrentStatus, 28 | this, &Seeder::torrentStatus, 29 | Qt::DirectConnection); 30 | } 31 | 32 | void Seeder::start(QJsonObject info) { 33 | getMethod(m_Private.data(), "start(QJsonObject)") 34 | .invoke(m_Private.data(), 35 | Qt::QueuedConnection, 36 | Q_ARG(QJsonObject,info)); 37 | 38 | } 39 | 40 | void Seeder::cancel() { 41 | getMethod(m_Private.data(), "cancel(void)") 42 | .invoke(m_Private.data(), 43 | Qt::QueuedConnection); 44 | } 45 | #endif // DECENTRALIZED_UPDATE_ENABLED 46 | -------------------------------------------------------------------------------- /include/softwareupdatedialog_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SOFTWARE_UPDATE_WIDGET_HPP_INCLUDED 2 | #define SOFTWARE_UPDATE_WIDGET_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class SoftwareUpdateDialog : public QDialog { 12 | Q_OBJECT 13 | public: 14 | enum { 15 | NoRemindMeLaterButton = 0x80, 16 | NoSkipThisVersionButton = 0x100, 17 | Default = 0 18 | }; 19 | SoftwareUpdateDialog(QWidget *parent = nullptr, QPixmap icon = QPixmap(), int flags = Default); 20 | ~SoftwareUpdateDialog(); 21 | public Q_SLOTS: 22 | void init(const QString&,const QString&,const QString&,const QString&); 23 | private Q_SLOTS: 24 | void pInit(); 25 | void handleRemindMeLater(); 26 | void handleSkipThisUpdate(); 27 | void handleInstallUpdate(); 28 | private: 29 | bool b_NoUseSettings = false; 30 | const QString m_TitleTemplate = 31 | QString::fromUtf8("A new version of %1 is available!"); 32 | const QString m_VersionDescTemplate = 33 | QString::fromUtf8("%1 (%2) is now available--you have (%3). Would you like to download it ?"); 34 | QPixmap m_Icon; 35 | QTimer m_Timer; 36 | QString m_Id; 37 | QScopedPointer m_Settings; 38 | Ui::SoftwareUpdateDialog m_Ui; 39 | }; 40 | 41 | #endif // SOFTWARE_UPDATE_WIDGET_HPP_INCLUDED 42 | -------------------------------------------------------------------------------- /website/pages/en/users.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | const CompLibrary = require('../../core/CompLibrary.js'); 11 | const Container = CompLibrary.Container; 12 | 13 | const siteConfig = require(process.cwd() + '/siteConfig.js'); 14 | 15 | class Users extends React.Component { 16 | render() { 17 | const showcase = siteConfig.users.map((user, i) => { 18 | return ( 19 | 20 | 21 | 22 | ); 23 | }); 24 | 25 | return ( 26 |
27 | 28 |
29 |
30 |

Who's Using This?

31 |

This project is used by many projects.

32 |
33 |
{showcase}
34 | 37 | List Yours Too! 38 | 39 |
40 |
41 |
42 | ); 43 | } 44 | } 45 | 46 | module.exports = Users; 47 | -------------------------------------------------------------------------------- /include/qappimageupdatecodes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QAPPIMAGE_UPDATE_CODES_HPP_INCLUDED 2 | #define QAPPIMAGE_UPDATE_CODES_HPP_INCLUDED 3 | 4 | struct QAppImageUpdateCodes { 5 | struct Action { 6 | enum : short { 7 | None, 8 | GetEmbeddedInfo, 9 | CheckForUpdate, 10 | Update, 11 | UpdateWithTorrent, 12 | UpdateWithGUI, 13 | UpdateWithGUIAndTorrent, 14 | Seed 15 | }; 16 | }; 17 | 18 | struct GuiFlag { 19 | enum : int { 20 | None = 0x0, 21 | ShowProgressDialog = 0x1, 22 | ShowBeforeProgress = 0x2, 23 | ShowUpdateConfirmationDialog = 0x4, 24 | ShowFinishedDialog = 0x8, 25 | ShowErrorDialog = 0x10, 26 | NoShowErrorDialogOnPermissionErrors = 0x20, 27 | NotifyWhenNoUpdateIsAvailable = 0x40, 28 | NoRemindMeLaterButton = 0x80, 29 | NoSkipThisVersionButton = 0x100, 30 | NoConfirmTorrentUsage = 0x200, 31 | Default = ShowBeforeProgress | 32 | ShowProgressDialog | 33 | ShowUpdateConfirmationDialog | 34 | ShowFinishedDialog | 35 | ShowErrorDialog | 36 | NotifyWhenNoUpdateIsAvailable | 37 | NoRemindMeLaterButton | 38 | NoSkipThisVersionButton 39 | }; 40 | }; 41 | }; 42 | 43 | #endif // QAPPIMAGE_UPDATE_CODES_HPP_INCLUDED 44 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-Installation 3 | title: Installing QAppImageUpdate to your Project. 4 | sidebar_label: Installation 5 | original_id: Installation 6 | --- 7 | 8 | Since QAppImageUpdate is specifically made for Qt, All you need is Qt's development tools 9 | and only that, Nothing more and nothing less. 10 | 11 | ## Dependencies 12 | 13 | * [Qt5 Framework](https://qt.io) 14 | 15 | 16 | ## Optional Dependencies (Specifically for Torrent Update Feature) 17 | 18 | * [Torrent Rasterbar](https://libtorrent.org) 19 | 20 | 21 | Using the torrent feature is strictly for brave hearts because it's a bit hard 22 | to get everything linked and compiled correctly. Please don't try this if don't 23 | know what you are doing. For reference you can see how [AppImage Updater](https://github.com/antony-jr/AppImageUpdater) 24 | compiles it. 25 | 26 | ## Installing the latest release from github 27 | 28 | **Just execute this command on your project folder and everything will be done for you!** 29 | You must have **git** to do this , **don't worry** because most of the linux distro's must 30 | have **installed it already** for you , if not install it! 31 | 32 | ``` 33 | $ git clone https://github.com/antony-jr/QAppImageUpdate 34 | ``` 35 | 36 | or **to install it in your git project folder** 37 | 38 | ``` 39 | $ git submodule init 40 | $ git submodule add https://github.com/antony-jr/QAppImageUpdate 41 | $ git submodule update 42 | ``` 43 | 44 | Even though AppImage is specific to linux, this library is cross platform. 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, Antony jr 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /examples/GetEmbeddedInfo/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "GetEmbeddedInfo, A Elf reader to get AppImage Update Info."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QCoreApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 22 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 23 | app.quit(); 24 | return; 25 | }); 26 | 27 | 28 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 29 | qInfo().noquote() << info; 30 | 31 | ++it; 32 | if(it >= parser.positionalArguments().count()) { 33 | app.quit(); 34 | } else { 35 | QString path(args[it]); 36 | updater.setAppImage(path); 37 | updater.start(QAppImageUpdate::Action::GetEmbeddedInfo); 38 | } 39 | return; 40 | }); 41 | 42 | QString path(args[it]); 43 | updater.setAppImage(path); 44 | updater.setShowLog(false); 45 | updater.start(QAppImageUpdate::Action::GetEmbeddedInfo); 46 | return app.exec(); 47 | } 48 | -------------------------------------------------------------------------------- /docs/SimpleExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: SimpleExample 3 | title: Updating an AppImage 4 | sidebar_label: Updating an AppImage 5 | --- 6 | 7 | This guide Demonstrates how to use the *QAppImageUpdate* APIs for updating a single AppImage file. 8 | This example parses the path from the program arguments. 9 | 10 | ## main.cpp 11 | 12 | ``` 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int ac , char **av) 18 | { 19 | if(ac == 1){ 20 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 21 | return 0; 22 | } 23 | 24 | QCoreApplication app(ac , av); 25 | QString AppImagePath = QString(av[1]); 26 | 27 | QAppImageUpdate updater(AppImagePath); 28 | QObject::connect(&updater , &QAppImageUpdate::finished , 29 | [&](QJsonObject newVersionDetails , short action){ 30 | if(action == QAppImageUpdate::Action::Update) { 31 | qInfo() << "New Version Details:: " << newVersionDetails; 32 | app.quit(); 33 | } 34 | }); 35 | QObject::connect(&updater, &QAppImageUpdate::error , 36 | [&](short e){ 37 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 38 | app.quit(); 39 | }); 40 | updater.setShowLog(true); // Display log? 41 | 42 | updater.start(QAppImageUpdate::Action::Update); /* Start the update. */ 43 | return app.exec(); 44 | } 45 | 46 | ``` 47 | 48 | ## update.pro 49 | 50 | ``` 51 | include(QAppImageUpdate/QAppImageUpdate.pri) 52 | TEMPLATE = app 53 | TARGET = update 54 | SOURCES += main.cpp 55 | ``` 56 | 57 | ## Compilation and Execution 58 | 59 | ``` 60 | $ mkdir build 61 | $ cd build 62 | $ qmake .. 63 | $ make -j$(nproc) 64 | $ ./update some.AppImage 65 | ``` 66 | 67 | A advanced verison of this program has been implemented in the examples directory. 68 | -------------------------------------------------------------------------------- /docs/Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: Installation 3 | title: Installing QAppImageUpdate to your Project. 4 | sidebar_label: Installation 5 | --- 6 | 7 | Since QAppImageUpdate is specifically made for Qt, All you need is Qt's development tools 8 | and only that, Nothing more and nothing less. 9 | 10 | ## Dependencies 11 | 12 | * [Qt5 Framework](https://qt.io) 13 | 14 | 15 | ## Optional Dependencies (Specifically for Torrent Update Feature) 16 | 17 | * [Torrent Rasterbar](https://libtorrent.org) 18 | 19 | 20 | Using the torrent feature is strictly for brave hearts because it's a bit hard 21 | to get everything linked and compiled correctly. Please don't try this if don't 22 | know what you are doing. For reference you can see how [AppImage Updater](https://github.com/antony-jr/AppImageUpdater) 23 | compiles it. 24 | 25 | ## Installing the latest release from github 26 | 27 | **Just execute this command on your project folder and everything will be done for you!** 28 | You must have **git** to do this , **don't worry** because most of the linux distro's must 29 | have **installed it already** for you , if not install it! 30 | 31 | ``` 32 | $ git clone https://github.com/antony-jr/QAppImageUpdate 33 | ``` 34 | 35 | or **to install it in your git project folder** 36 | 37 | ``` 38 | $ git submodule init 39 | $ git submodule add https://github.com/antony-jr/QAppImageUpdate 40 | $ git submodule update 41 | ``` 42 | 43 | Even though AppImage is specific to linux, this library is cross platform. 44 | 45 | 46 | ## Installing to the system 47 | 48 | ``` 49 | $ git clone https://github.com/antony-jr/QAppImageUpdate 50 | $ cd QAppImageUpdate 51 | $ cmake . 52 | $ make -j$(nproc) 53 | $ sudo make install 54 | ``` 55 | 56 | Now you can use QAppImage with CMake's **find_package()**. 57 | -------------------------------------------------------------------------------- /examples/UpdateWithGUI/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "Update, Update AppImages."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::canceled, [&](short action) { 22 | Q_UNUSED(action); 23 | app.quit(); 24 | }); 25 | 26 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 27 | Q_UNUSED(action); 28 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 29 | app.quit(); 30 | return; 31 | }); 32 | 33 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 34 | Q_UNUSED(action); 35 | qInfo().noquote() << info; 36 | 37 | ++it; 38 | if(it >= parser.positionalArguments().count()) { 39 | app.quit(); 40 | } else { 41 | QString path(args[it]); 42 | updater.setAppImage(path); 43 | updater.start(QAppImageUpdate::Action::Update); 44 | } 45 | return; 46 | }); 47 | 48 | QString path(args[it]); 49 | updater.setAppImage(path); 50 | updater.setShowLog(true); 51 | updater.start(QAppImageUpdate::Action::UpdateWithGUI); 52 | return app.exec(); 53 | } 54 | -------------------------------------------------------------------------------- /QAppImageUpdate.pro: -------------------------------------------------------------------------------- 1 | # BSD 3-Clause License 2 | # 3 | # Copyright (c) 2017-2019, Antony jr 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 9 | # * Redistributions of source code must retain the above copyright notice, this 10 | # list of conditions and the following disclaimer. 11 | # 12 | # * Redistributions in binary form must reproduce the above copyright notice, 13 | # this list of conditions and the following disclaimer in the documentation 14 | # and/or other materials provided with the distribution. 15 | # 16 | # * Neither the name of the copyright holder nor the names of its 17 | # contributors may be used to endorse or promote products derived from 18 | # this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | include(QAppImageUpdate.pri) 32 | TARGET = QAppImageUpdate 33 | TEMPLATE = lib 34 | CONFIG += release 35 | -------------------------------------------------------------------------------- /examples/CheckForUpdate/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "CheckForUpdate, Check for Update for AppImages."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QCoreApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::progress, 22 | [&](int percentage) { 23 | qInfo().noquote() << "Progress:: " << percentage; 24 | }); 25 | 26 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 27 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 28 | app.quit(); 29 | return; 30 | }); 31 | 32 | 33 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 34 | qInfo().noquote() << info; 35 | 36 | ++it; 37 | if(it >= parser.positionalArguments().count()) { 38 | app.quit(); 39 | } else { 40 | QString path(args[it]); 41 | updater.setAppImage(path); 42 | updater.start(QAppImageUpdate::Action::CheckForUpdate); 43 | } 44 | return; 45 | }); 46 | 47 | QString path(args[it]); 48 | updater.setAppImage(path); 49 | updater.setShowLog(false); 50 | updater.start(QAppImageUpdate::Action::CheckForUpdate); 51 | return app.exec(); 52 | } 53 | -------------------------------------------------------------------------------- /examples/UpdateWithGUIAndTorrent/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "Update, Update AppImages."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::canceled, [&](short action) { 22 | Q_UNUSED(action); 23 | app.quit(); 24 | }); 25 | 26 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 27 | Q_UNUSED(action); 28 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 29 | app.quit(); 30 | return; 31 | }); 32 | 33 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 34 | Q_UNUSED(action); 35 | qInfo().noquote() << info; 36 | 37 | ++it; 38 | if(it >= parser.positionalArguments().count()) { 39 | app.quit(); 40 | } else { 41 | QString path(args[it]); 42 | updater.setAppImage(path); 43 | updater.start(QAppImageUpdate::Action::Update); 44 | } 45 | return; 46 | }); 47 | 48 | QString path(args[it]); 49 | updater.setAppImage(path); 50 | updater.setShowLog(true); 51 | updater.start(QAppImageUpdate::Action::UpdateWithGUIAndTorrent); 52 | return app.exec(); 53 | } 54 | -------------------------------------------------------------------------------- /include/rangereply_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGE_REPLY_PRIVATE_HPP_INCLUDED 2 | #define RANGE_REPLY_PRIVATE_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | class RangeReplyPrivate : public QObject { 15 | Q_OBJECT 16 | public: 17 | RangeReplyPrivate(int, QNetworkReply*, const QPair&); 18 | ~RangeReplyPrivate(); 19 | 20 | public Q_SLOTS: 21 | void destroy(); 22 | void retry(int); 23 | void cancel(); 24 | 25 | private Q_SLOTS: 26 | void resetInternalFlags(bool value = false); 27 | void restart(); 28 | void handleData(qint64, qint64); 29 | void handleError(QNetworkReply::NetworkError); 30 | void handleFinish(); 31 | Q_SIGNALS: 32 | void restarted(int); 33 | void error(QNetworkReply::NetworkError, int, bool); 34 | void progress(qint64, int); 35 | void data(QByteArray*, bool); 36 | void finished(qint32,qint32,QByteArray*, int); 37 | void canceled(int); 38 | private: 39 | bool b_Running = true, /* When constructed, the reply will be running. */ 40 | b_Finished = false, 41 | b_Canceled = false, 42 | b_CancelRequested = false, 43 | b_Retrying = false, 44 | b_Halted = false, 45 | b_FullDownload = false; 46 | int n_Index; 47 | int n_Fails; 48 | qint64 n_BytesRecieved; 49 | qint32 n_FromBlock, 50 | n_ToBlock; 51 | QTimer m_Timer; 52 | QScopedPointer m_Reply; 53 | QNetworkRequest m_Request; 54 | QNetworkAccessManager *m_Manager; 55 | QScopedPointer m_Data; 56 | }; 57 | #endif // RANGE_REPLY_PRIVATE_INCLUDED 58 | -------------------------------------------------------------------------------- /docs/GUIExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: GUIExample 3 | title: Updating an AppImage with GUI 4 | sidebar_label: Updating an AppImage with GUI 5 | --- 6 | 7 | This guide demonstrates on using the QAppImageUpdate to update appimages through 8 | graphical user interface. 9 | 10 | ## main.cpp 11 | 12 | ``` 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int ac , char **av) 18 | { 19 | if(ac == 1){ 20 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 21 | return 0; 22 | } 23 | 24 | QApplication app(ac , av); 25 | QString AppImagePath = QString(av[1]); 26 | 27 | QAppImageUpdate updater(AppImagePath); 28 | updater.setShowLog(true); // Display log? 29 | 30 | QObject::connect(&updater , &QAppImage::finished , 31 | [&](QJsonObject info, short action){ 32 | if(action == QAppImageUpdate::Action::UpdateWithGUI) { 33 | qInfo() << "New Version Details:: " << info; 34 | app.quit(); 35 | } 36 | }); 37 | QObject::connect(&updater , &QAppImageUpdate::error , 38 | [&](short e, short action){ 39 | if(action == QAppImageUpdate::Action::UpdateWithGUI) { 40 | qInfo() << "error(" << e "):: " 41 | << QAppImageUpdate::errorCodeToDescriptionString(e); 42 | app.quit(); 43 | } 44 | }); 45 | 46 | updater.start(QAppImageUpdate::Action::UpdateWithGUI); 47 | return app.exec(); 48 | } 49 | 50 | ``` 51 | 52 | ## update.pro 53 | 54 | ``` 55 | include(QAppImageUpdate/QAppImageUpdate.pri) 56 | TEMPLATE = app 57 | TARGET = updategui 58 | SOURCES += main.cpp 59 | ``` 60 | 61 | ## Compilation and Execution 62 | 63 | ``` 64 | $ mkdir build 65 | $ cd build 66 | $ qmake .. 67 | $ make -j$(nproc) 68 | $ ./update some.AppImage 69 | ``` 70 | 71 | A advanced verison of this program has been implemented in the examples directory. 72 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/SimpleExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-SimpleExample 3 | title: Updating an AppImage 4 | sidebar_label: Updating an AppImage 5 | original_id: SimpleExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *QAppImageUpdate* APIs for updating a single AppImage file. 9 | This example parses the path from the program arguments. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int ac , char **av) 19 | { 20 | if(ac == 1){ 21 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 22 | return 0; 23 | } 24 | 25 | QCoreApplication app(ac , av); 26 | QString AppImagePath = QString(av[1]); 27 | 28 | QAppImageUpdate updater(AppImagePath); 29 | QObject::connect(&updater , &QAppImageUpdate::finished , 30 | [&](QJsonObject newVersionDetails , short action){ 31 | if(action == QAppImageUpdate::Action::Update) { 32 | qInfo() << "New Version Details:: " << newVersionDetails; 33 | app.quit(); 34 | } 35 | }); 36 | QObject::connect(&updater, &QAppImageUpdate::error , 37 | [&](short e){ 38 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 39 | app.quit(); 40 | }); 41 | updater.setShowLog(true); // Display log? 42 | 43 | updater.start(QAppImageUpdate::Action::Update); /* Start the update. */ 44 | return app.exec(); 45 | } 46 | 47 | ``` 48 | 49 | ## update.pro 50 | 51 | ``` 52 | include(QAppImageUpdate/QAppImageUpdate.pri) 53 | TEMPLATE = app 54 | TARGET = update 55 | SOURCES += main.cpp 56 | ``` 57 | 58 | ## Compilation and Execution 59 | 60 | ``` 61 | $ mkdir build 62 | $ cd build 63 | $ qmake .. 64 | $ make -j$(nproc) 65 | $ ./update some.AppImage 66 | ``` 67 | 68 | A advanced verison of this program has been implemented in the examples directory. 69 | -------------------------------------------------------------------------------- /QAppImageUpdate: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 3-Clause License 3 | * 4 | * Copyright (c) 2017-2019, Antony jr 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * * Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * @filename : QAppImageUpdate 33 | * The traditional proxy header file. 34 | */ 35 | #include "qappimageupdate.hpp" 36 | -------------------------------------------------------------------------------- /include/seeder_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SEEDER_PRIVATE_HPP_INCLUDED 2 | #define SEEDER_PRIVATE_HPP_INCLUDED 3 | #ifdef DECENTRALIZED_UPDATE_ENABLED 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | class SeederPrivate : public QObject { 25 | Q_OBJECT 26 | public: 27 | SeederPrivate(QNetworkAccessManager*); 28 | ~SeederPrivate(); 29 | public Q_SLOTS: 30 | void start(QJsonObject); 31 | void cancel(); 32 | private Q_SLOTS: 33 | void handleTorrentFileData(qint64, qint64); 34 | void handleTorrentFileError(QNetworkReply::NetworkError); 35 | void handleTorrentFileFinish(); 36 | void handleTimeout(); 37 | 38 | void torrentLoop(); 39 | 40 | Q_SIGNALS: 41 | void started(); 42 | void canceled(); 43 | void error(short); 44 | 45 | void logger(QString); 46 | void torrentStatus(int,int); 47 | private: 48 | bool b_Running = false, 49 | b_CancelRequested = false; 50 | 51 | QTimer m_Timer; 52 | QTimer m_TimeoutTimer; 53 | QString m_TargetFilePath; 54 | QNetworkAccessManager *m_Manager; 55 | QScopedPointer m_TorrentMeta; 56 | QScopedPointer m_Session; 57 | lt::torrent_handle m_Handle; 58 | }; 59 | #endif // DECENTRALIZED_UPDATE_ENABLED 60 | #endif // SEEDER_PRIVATE_HPP_INCLUDED 61 | -------------------------------------------------------------------------------- /docs/TorrentExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: TorrentExample 3 | title: Updating an AppImage with BitTorrent 4 | sidebar_label: Updating an AppImage with BitTorrent 5 | --- 6 | 7 | This guide Demonstrates how to use the *QAppImageUpdate* APIs for updating a single AppImage file using **Zsync + BitTorrent**. 8 | This example parses the path from the program arguments. 9 | 10 | ## main.cpp 11 | 12 | ``` 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int ac , char **av) 18 | { 19 | if(ac == 1){ 20 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 21 | return 0; 22 | } 23 | 24 | QCoreApplication app(ac , av); 25 | QString AppImagePath = QString(av[1]); 26 | 27 | QAppImageUpdate updater(AppImagePath); 28 | QObject::connect(&updater , &QAppImageUpdate::finished , 29 | [&](QJsonObject newVersionDetails , short action){ 30 | if(action == QAppImageUpdate::Action::Update) { 31 | qInfo() << "New Version Details:: " << newVersionDetails; 32 | app.quit(); 33 | } 34 | }); 35 | QObject::connect(&updater, &QAppImageUpdate::error , 36 | [&](short e){ 37 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 38 | app.quit(); 39 | }); 40 | updater.setShowLog(true); // Display log? 41 | 42 | 43 | /// This line is the only thing that changes. 44 | updater.start(QAppImageUpdate::Action::UpdateWithTorrent); 45 | return app.exec(); 46 | } 47 | 48 | ``` 49 | 50 | ## update.pro 51 | 52 | ``` 53 | include(QAppImageUpdate/QAppImageUpdate.pri) 54 | TEMPLATE = app 55 | TARGET = update 56 | SOURCES += main.cpp 57 | ``` 58 | 59 | ## Compilation and Execution 60 | 61 | ``` 62 | $ mkdir build 63 | $ cd build 64 | $ qmake .. 65 | $ make -j$(nproc) 66 | $ ./update some.AppImage 67 | ``` 68 | 69 | A advanced verison of this program has been implemented in the examples directory. 70 | -------------------------------------------------------------------------------- /include/qappimageupdateinterface.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QAPPIMAGE_UPDATE_INTERFACE_PRIVATE_HPP_INCLUDED 2 | #define QAPPIMAGE_UPDATE_INTERFACE_PRIVATE_HPP_INCLUDED 3 | #ifdef BUILD_AS_PLUGIN 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class QAppImageUpdateInterface { 11 | public Q_SLOTS: 12 | virtual void setApplicationName(const QString&) = 0; 13 | virtual void setGuiFlag(int) = 0; 14 | virtual void setIcon(QByteArray) = 0; 15 | virtual void setAppImagePath(const QString&) = 0; 16 | virtual void setAppImageFile(QFile*) = 0; 17 | virtual void setShowLog(bool) = 0; 18 | virtual void setOutputDirectory(const QString&) = 0; 19 | virtual void setProxy(const QNetworkProxy&) = 0; 20 | virtual void start(short) = 0; 21 | virtual void cancel() = 0; 22 | virtual void clear() = 0; 23 | 24 | virtual int getConstant(const QString&) = 0; 25 | virtual QObject *getObject() = 0; 26 | 27 | virtual QString errorCodeToString(short) = 0; 28 | virtual QString errorCodeToDescriptionString(short) = 0; 29 | Q_SIGNALS: 30 | virtual void torrentClientStarted() = 0; 31 | virtual void torrentStatus(int,int) = 0; 32 | virtual void started(short) = 0; 33 | virtual void canceled(short) = 0; 34 | virtual void finished(QJsonObject info, short) = 0; 35 | virtual void progress(int, qint64, qint64, double, QString, short) = 0; 36 | virtual void logger(QString, QString) = 0; 37 | virtual void error(short, short) = 0; 38 | virtual void quit() = 0; 39 | }; 40 | 41 | #ifndef QAppImageUpdateInterface_iid 42 | #define QAppImageUpdateInterface_iid "com.antony-jr.QAppImageUpdate" 43 | #endif 44 | 45 | Q_DECLARE_INTERFACE(QAppImageUpdateInterface, QAppImageUpdateInterface_iid); 46 | #endif // BUILD_AS_PLUGIN 47 | #endif // QAPPIMAGEUPDATE_INTERFACE_PRIVATE_HPP_INCLUDED 48 | -------------------------------------------------------------------------------- /examples/Update/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "Update, Update AppImages."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QCoreApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 22 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 23 | app.quit(); 24 | return; 25 | }); 26 | 27 | QObject::connect(&updater, &QAppImageUpdate::progress, 28 | [&](int percentage, qint64 rc, qint64 total, double speed, QString units) { 29 | qInfo().noquote() << "Updating " << percentage << "%: Revised " << rc << "/" << total 30 | << " bytes at " << speed << units << "... "; 31 | }); 32 | 33 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 34 | qInfo().noquote() << info; 35 | 36 | ++it; 37 | if(it >= parser.positionalArguments().count()) { 38 | app.quit(); 39 | } else { 40 | QString path(args[it]); 41 | updater.setAppImage(path); 42 | updater.start(QAppImageUpdate::Action::Update); 43 | } 44 | return; 45 | }); 46 | 47 | QString path(args[it]); 48 | updater.setAppImage(path); 49 | updater.setShowLog(true); 50 | updater.start(QAppImageUpdate::Action::Update); 51 | return app.exec(); 52 | } 53 | -------------------------------------------------------------------------------- /src/rangereply.cc: -------------------------------------------------------------------------------- 1 | #include "rangereply.hpp" 2 | #include "rangereply_p.hpp" 3 | #include "helpers_p.hpp" 4 | 5 | #include 6 | 7 | RangeReply::RangeReply(int index, QNetworkReply *reply, const QPair &range) 8 | : QObject() { 9 | m_Private = QSharedPointer( 10 | new RangeReplyPrivate(index, reply, range)); 11 | 12 | auto ptr = m_Private.data(); 13 | connect(ptr, &RangeReplyPrivate::restarted, 14 | this, &RangeReply::restarted, 15 | Qt::DirectConnection); 16 | connect(ptr, &RangeReplyPrivate::error, 17 | this, &RangeReply::error, 18 | Qt::DirectConnection); 19 | connect(ptr, &RangeReplyPrivate::finished, 20 | this, &RangeReply::finished, 21 | Qt::DirectConnection); 22 | connect(ptr, &RangeReplyPrivate::data, 23 | this, &RangeReply::data, 24 | Qt::DirectConnection); 25 | connect(ptr, &RangeReplyPrivate::canceled, 26 | this, &RangeReply::canceled, 27 | Qt::DirectConnection); 28 | connect(ptr, &RangeReplyPrivate::progress, 29 | this, &RangeReply::progress, 30 | Qt::DirectConnection); 31 | 32 | } 33 | 34 | RangeReply::~RangeReply() { 35 | getMethod(m_Private.data(), "destroy()") 36 | .invoke(m_Private.data(), Qt::QueuedConnection); 37 | } 38 | 39 | 40 | // Public Slots 41 | void RangeReply::destroy() { 42 | getMethod(m_Private.data(), "destroy()") 43 | .invoke(m_Private.data(), Qt::QueuedConnection); 44 | } 45 | 46 | void RangeReply::retry(int timeout) { 47 | getMethod(m_Private.data(), "retry(int)") 48 | .invoke(m_Private.data(), Qt::QueuedConnection, Q_ARG(int, timeout)); 49 | 50 | } 51 | 52 | void RangeReply::cancel() { 53 | getMethod(m_Private.data(), "cancel()") 54 | .invoke(m_Private.data(), Qt::QueuedConnection); 55 | } 56 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/GUIExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-GUIExample 3 | title: Updating an AppImage with GUI 4 | sidebar_label: Updating an AppImage with GUI 5 | original_id: GUIExample 6 | --- 7 | 8 | This guide demonstrates on using the QAppImageUpdate to update appimages through 9 | graphical user interface. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int ac , char **av) 19 | { 20 | if(ac == 1){ 21 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 22 | return 0; 23 | } 24 | 25 | QApplication app(ac , av); 26 | QString AppImagePath = QString(av[1]); 27 | 28 | QAppImageUpdate updater(AppImagePath); 29 | updater.setShowLog(true); // Display log? 30 | 31 | QObject::connect(&updater , &QAppImage::finished , 32 | [&](QJsonObject info, short action){ 33 | if(action == QAppImageUpdate::Action::UpdateWithGUI) { 34 | qInfo() << "New Version Details:: " << info; 35 | app.quit(); 36 | } 37 | }); 38 | QObject::connect(&updater , &QAppImageUpdate::error , 39 | [&](short e, short action){ 40 | if(action == QAppImageUpdate::Action::UpdateWithGUI) { 41 | qInfo() << "error(" << e "):: " 42 | << QAppImageUpdate::errorCodeToDescriptionString(e); 43 | app.quit(); 44 | } 45 | }); 46 | 47 | updater.start(QAppImageUpdate::Action::UpdateWithGUI); 48 | return app.exec(); 49 | } 50 | 51 | ``` 52 | 53 | ## update.pro 54 | 55 | ``` 56 | include(QAppImageUpdate/QAppImageUpdate.pri) 57 | TEMPLATE = app 58 | TARGET = updategui 59 | SOURCES += main.cpp 60 | ``` 61 | 62 | ## Compilation and Execution 63 | 64 | ``` 65 | $ mkdir build 66 | $ cd build 67 | $ qmake .. 68 | $ make -j$(nproc) 69 | $ ./update some.AppImage 70 | ``` 71 | 72 | A advanced verison of this program has been implemented in the examples directory. 73 | -------------------------------------------------------------------------------- /examples/UpdateWithTorrent/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int ac, char **av) { 6 | qInfo().noquote() << "Update, Update AppImages."; 7 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 8 | 9 | QCoreApplication app(ac, av); 10 | QAppImageUpdate updater; 11 | 12 | QCommandLineParser parser; 13 | parser.process(app); 14 | auto args = parser.positionalArguments(); 15 | if(args.count() == 0) { 16 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 17 | return -1; 18 | } 19 | int it = 0; 20 | 21 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 22 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 23 | app.quit(); 24 | return; 25 | }); 26 | 27 | QObject::connect(&updater, &QAppImageUpdate::progress, 28 | [&](int percentage, qint64 rc, qint64 total, double speed, QString units) { 29 | qInfo().noquote() << "Updating " << percentage << "%: Revised " << rc << "/" << total 30 | << " bytes at " << speed << units << "... "; 31 | }); 32 | 33 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 34 | qInfo().noquote() << info; 35 | 36 | ++it; 37 | if(it >= parser.positionalArguments().count()) { 38 | app.quit(); 39 | } else { 40 | QString path(args[it]); 41 | updater.setAppImage(path); 42 | updater.start(QAppImageUpdate::Action::UpdateWithTorrent); 43 | } 44 | return; 45 | }); 46 | 47 | QString path(args[it]); 48 | updater.setAppImage(path); 49 | updater.setShowLog(true); 50 | updater.start(QAppImageUpdate::Action::UpdateWithTorrent); 51 | return app.exec(); 52 | } 53 | -------------------------------------------------------------------------------- /src/helpers_p.cc: -------------------------------------------------------------------------------- 1 | #include "qappimageupdateenums.hpp" 2 | #include "helpers_p.hpp" 3 | 4 | QMetaMethod getMethod(QObject *object, const char *function) { 5 | auto metaObject = object->metaObject(); 6 | return metaObject->method(metaObject->indexOfMethod(QMetaObject::normalizedSignature(function))); 7 | } 8 | 9 | short translateQNetworkReplyError(QNetworkReply::NetworkError errorCode) { 10 | short e = 0; 11 | if(errorCode > 0 && errorCode < 101) { 12 | e = QAppImageUpdateEnums::Error::ConnectionRefusedError + ((short)errorCode - 1); 13 | } else if(errorCode == QNetworkReply::UnknownNetworkError) { 14 | e = QAppImageUpdateEnums::Error::UnknownNetworkError; 15 | } else if(errorCode == QNetworkReply::UnknownProxyError) { 16 | e = QAppImageUpdateEnums::Error::UnknownProxyError; 17 | } else if(errorCode >= 101 && errorCode < 201) { 18 | e = QAppImageUpdateEnums::Error::ProxyConnectionRefusedError + ((short)errorCode - 101); 19 | } else if(errorCode == QNetworkReply::ProtocolUnknownError) { 20 | e = QAppImageUpdateEnums::Error::ProtocolUnknownError; 21 | } else if(errorCode == QNetworkReply::ProtocolInvalidOperationError) { 22 | e = QAppImageUpdateEnums::Error::ProtocolInvalidOperationError; 23 | } else if(errorCode == QNetworkReply::UnknownContentError) { 24 | e = QAppImageUpdateEnums::Error::UnknownContentError; 25 | } else if(errorCode == QNetworkReply::ProtocolFailure) { 26 | e = QAppImageUpdateEnums::Error::ProtocolFailure; 27 | } else if(errorCode >= 201 && errorCode < 401) { 28 | e = QAppImageUpdateEnums::Error::ContentAccessDenied + ((short)errorCode - 201); 29 | } else if(errorCode >= 401 && errorCode <= 403) { 30 | e = QAppImageUpdateEnums::Error::InternalServerError + ((short)errorCode - 401); 31 | } else { 32 | e = QAppImageUpdateEnums::Error::UnknownServerError; 33 | } 34 | return e; 35 | } 36 | -------------------------------------------------------------------------------- /include/qappimageupdateinterfaceimpl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QAPPIMAGE_UPDATE_INTERFACE_IMPL_HPP_INCLUDED 2 | #define QAPPIMAGE_UPDATE_INTERFACE_IMPL_HPP_INCLUDED 3 | #ifdef BUILD_AS_PLUGIN 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "qappimageupdate.hpp" 14 | #include "qappimageupdateinterface.hpp" 15 | 16 | class QAppImageUpdateInterfaceImpl : public QObject, QAppImageUpdateInterface { 17 | Q_OBJECT 18 | Q_PLUGIN_METADATA(IID QAppImageUpdateInterface_iid FILE "QAppImageUpdate.json") 19 | Q_INTERFACES(QAppImageUpdateInterface) 20 | public: 21 | QAppImageUpdateInterfaceImpl(QObject *parent = nullptr); 22 | ~QAppImageUpdateInterfaceImpl(); 23 | public Q_SLOTS: 24 | void setApplicationName(const QString&); 25 | void setIcon(QByteArray); 26 | void setGuiFlag(int); 27 | void setAppImagePath(const QString&); 28 | void setAppImageFile(QFile*); 29 | void setShowLog(bool); 30 | void setOutputDirectory(const QString&); 31 | void setProxy(const QNetworkProxy&); 32 | void start(short action); 33 | void cancel(); 34 | void clear(); 35 | 36 | int getConstant(const QString&); 37 | QObject *getObject(); 38 | 39 | QString errorCodeToString(short); 40 | QString errorCodeToDescriptionString(short); 41 | Q_SIGNALS: 42 | void torrentClientStarted(); 43 | void torrentStatus(int,int); 44 | void started(short); 45 | void canceled(short); 46 | void finished(QJsonObject info, short); 47 | void progress(int, qint64, qint64, double, QString, short); 48 | void logger(QString, QString); 49 | void error(short, short); 50 | void quit(); 51 | private: 52 | QScopedPointer m_Private; 53 | }; 54 | #endif // BUILD_AS_PLUGIN 55 | #endif // QAPPIMAGE_UPDATE_INTERFACE_IMPL_HPP_INCLUDED 56 | -------------------------------------------------------------------------------- /website/pages/en/help.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | const CompLibrary = require('../../core/CompLibrary.js'); 11 | const Container = CompLibrary.Container; 12 | const GridBlock = CompLibrary.GridBlock; 13 | 14 | const siteConfig = require(process.cwd() + '/siteConfig.js'); 15 | 16 | class Help extends React.Component { 17 | render() { 18 | const supportLinks = [ 19 | { 20 | content: 21 | 'Learn more using the [documentation on this site.](/AppImageUpdaterBridge/docs/Installation.html)', 22 | title: 'Browse Docs', 23 | }, 24 | { 25 | content: 'If you have any questions about the author or the project just ask me , get in touch with me on '+ 26 | 'Ask Me Anything!', 27 | title: 'Ask the Author', 28 | }, 29 | { 30 | content: "If you ever face any problem , please raise a "+ 31 | "Issue to get it fixed asap!", 32 | title: 'Open an Issue on GitHub', 33 | }, 34 | ]; 35 | 36 | return ( 37 |
38 | 39 |
40 |
41 |

Need help?

42 |
43 |

44 | This project is maintained by Antony Jr. 45 |

46 | 47 |
48 |
49 |
50 | ); 51 | } 52 | } 53 | 54 | module.exports = Help; 55 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/TorrentExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-TorrentExample 3 | title: Updating an AppImage with BitTorrent 4 | sidebar_label: Updating an AppImage with BitTorrent 5 | original_id: TorrentExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *QAppImageUpdate* APIs for updating a single AppImage file using **Zsync + BitTorrent**. 9 | This example parses the path from the program arguments. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int ac , char **av) 19 | { 20 | if(ac == 1){ 21 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 22 | return 0; 23 | } 24 | 25 | QCoreApplication app(ac , av); 26 | QString AppImagePath = QString(av[1]); 27 | 28 | QAppImageUpdate updater(AppImagePath); 29 | QObject::connect(&updater , &QAppImageUpdate::finished , 30 | [&](QJsonObject newVersionDetails , short action){ 31 | if(action == QAppImageUpdate::Action::Update) { 32 | qInfo() << "New Version Details:: " << newVersionDetails; 33 | app.quit(); 34 | } 35 | }); 36 | QObject::connect(&updater, &QAppImageUpdate::error , 37 | [&](short e){ 38 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 39 | app.quit(); 40 | }); 41 | updater.setShowLog(true); // Display log? 42 | 43 | 44 | /// This line is the only thing that changes. 45 | updater.start(QAppImageUpdate::Action::UpdateWithTorrent); 46 | return app.exec(); 47 | } 48 | 49 | ``` 50 | 51 | ## update.pro 52 | 53 | ``` 54 | include(QAppImageUpdate/QAppImageUpdate.pri) 55 | TEMPLATE = app 56 | TARGET = update 57 | SOURCES += main.cpp 58 | ``` 59 | 60 | ## Compilation and Execution 61 | 62 | ``` 63 | $ mkdir build 64 | $ cd build 65 | $ qmake .. 66 | $ make -j$(nproc) 67 | $ ./update some.AppImage 68 | ``` 69 | 70 | A advanced verison of this program has been implemented in the examples directory. 71 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AppImageUpdaterDialogExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AppImageUpdaterDialogExample 3 | title: Updating an AppImage with GUI 4 | sidebar_label: Updating an AppImage with GUI 5 | original_id: AppImageUpdaterDialogExample 6 | --- 7 | 8 | This guide demonstrates on using the AppImage updater dialog to update appimages through 9 | graphical user interface. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main(int ac , char **av) 20 | { 21 | if(ac == 1){ 22 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 23 | return 0; 24 | } 25 | 26 | using AppImageUpdaterBridge::AppImageUpdaterDialog; 27 | using AppImageUpdaterBridge::AppImageDeltaRevisioner; 28 | QApplication app(ac , av); 29 | QString AppImagePath = QString(av[1]); 30 | 31 | AppImageDeltaRevisioner DRev(AppImagePath); 32 | DRev.setShowLog(true); // Display log? 33 | 34 | AppImageUpdaterDialog UWidget; 35 | QObject::connect(&UWidget , &AppImageUpdaterDialog::finished , 36 | [&](QJsonObject newVersionDetails){ 37 | qInfo() << "New Version Details:: " << newVersionDetails; 38 | app.quit(); 39 | }); 40 | QObject::connect(&UWidget , &AppImageUpdaterDialog::error , 41 | [&](QString eStr , short e){ 42 | qInfo() << "error(" << e "):: " << eStr; 43 | app.quit(); 44 | }); 45 | UWidget.init(&DRev); /* Start the update using GUI */ 46 | return app.exec(); 47 | } 48 | 49 | ``` 50 | 51 | ## update.pro 52 | 53 | ``` 54 | include(AppImageUpdaterBridge/AppImageUpdaterBridge.pri) 55 | TEMPLATE = app 56 | TARGET = updategui 57 | SOURCES += main.cpp 58 | ``` 59 | 60 | ## Compilation and Execution 61 | 62 | ``` 63 | $ mkdir build 64 | $ cd build 65 | $ qmake .. 66 | $ make -j$(nproc) 67 | $ ./update some.AppImage 68 | ``` 69 | 70 | A advanced verison of this program has been implemented in the examples directory. 71 | -------------------------------------------------------------------------------- /tests/SimpleDownload.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SIMPLE_DOWNLOAD_HPP_INCLUDED 2 | #define SIMPLE_DOWNLOAD_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | // Sync Downloader 15 | class SimpleDownload { 16 | QScopedPointer m_Manager; 17 | public: 18 | SimpleDownload() { 19 | m_Manager.reset(new QNetworkAccessManager); 20 | } 21 | 22 | int download(const QUrl &url, const QString &destination) { 23 | QScopedPointer reply; 24 | QScopedPointer file; 25 | QString fileName = QFileInfo(destination).fileName(); 26 | 27 | QNetworkRequest req; 28 | req.setUrl(url); 29 | req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); 30 | 31 | 32 | file.reset(new QFile); 33 | file->setFileName(destination); 34 | if(!file->open(QIODevice::WriteOnly)) { 35 | return -1; 36 | } 37 | 38 | reply.reset(m_Manager->get(req)); 39 | 40 | QElapsedTimer elapsed; 41 | elapsed.start(); 42 | 43 | qInfo().noquote() << "Downloading " << fileName; 44 | 45 | while(!reply->isFinished()) { 46 | if(reply->error() != QNetworkReply::NoError) { 47 | reply->deleteLater(); 48 | qCritical().noquote() << "Download Failed " << fileName << " : " << reply->error(); 49 | return -1; 50 | } 51 | if(reply->isReadable()) { 52 | file->write(reply->readAll()); 53 | } 54 | QCoreApplication::processEvents(); 55 | } 56 | 57 | file->write(reply->readAll()); 58 | file->close(); 59 | qInfo().noquote() << "Downloaded " << fileName; 60 | return 0; 61 | } 62 | 63 | ~SimpleDownload() { } 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AppImageDeltaRevisionerExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AppImageDeltaRevisionerExample 3 | title: Updating an AppImage 4 | sidebar_label: Updating an AppImage 5 | original_id: AppImageDeltaRevisionerExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *AppImageUpdaterBridge* APIs for updating a single AppImage file. 9 | This example parses the path from the program arguments , And uses the *[AppImageDeltaRevisioner](ClassAppImageDeltaRevisioner.html)* class to perform the actual delta update. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int ac , char **av) 19 | { 20 | if(ac == 1){ 21 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 22 | return 0; 23 | } 24 | 25 | using AppImageUpdaterBridge::AppImageDeltaRevisioner; 26 | QCoreApplication app(ac , av); 27 | QString AppImagePath = QString(av[1]); 28 | 29 | AppImageDeltaRevisioner DRevisioner(AppImagePath); 30 | QObject::connect(&DRevisioner , &AppImageDeltaRevisioner::finished , 31 | [&](QJsonObject newVersionDetails , QString oldVersionPath){ 32 | (void)oldVersionPath; 33 | qInfo() << "New Version Details:: " << newVersionDetails; 34 | app.quit(); 35 | }); 36 | QObject::connect(&DRevisioner , &AppImageDeltaRevisioner::error , 37 | [&](short e){ 38 | qInfo() << "error:: " << AppImageUpdaterBridge::errorCodeToString(e); 39 | app.quit(); 40 | }); 41 | DRevisioner.setShowLog(true); // Display log? 42 | 43 | DRevisioner.start(); /* Start the update. */ 44 | return app.exec(); 45 | } 46 | 47 | ``` 48 | 49 | ## update.pro 50 | 51 | ``` 52 | include(AppImageUpdaterBridge/AppImageUpdaterBridge.pri) 53 | TEMPLATE = app 54 | TARGET = update 55 | SOURCES += main.cpp 56 | ``` 57 | 58 | ## Compilation and Execution 59 | 60 | ``` 61 | $ mkdir build 62 | $ cd build 63 | $ qmake .. 64 | $ make -j$(nproc) 65 | $ ./update some.AppImage 66 | ``` 67 | 68 | A advanced verison of this program has been implemented in the examples directory. 69 | -------------------------------------------------------------------------------- /docs/UsingPlugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: UsingPlugin 3 | title: Build QAppImageUpdate as Qt Plugin 4 | sidebar_label: Building as Qt Plugin 5 | --- 6 | 7 | QAppImageUpdate can compiled as a **Qt Plugin**. When it is built as a Qt Plugin, QAppImageUpdate can be used from any programming language that supports Qt. 8 | 9 | Qt plugins thus makes us to maintain a single code base instead of maintaining a lot of ports. This makes less bug in the code base and there is no time wasted in making bindings. 10 | 11 | You can see the plugin interface [here](PluginInterface.html). 12 | 13 | To read more about Qt plugins, Please refer the official documentation. 14 | 15 | # Rules in Plugin Usage 16 | 17 | There are specific rules on how plugins are handled by Qt. The following are the key rules in plugin usage. 18 | 19 | * A Qt framework whose major version is higher or equal to the Qt framework 20 | used to build the plugin should work fine with no errors. 21 | 22 | * If you build against Qt Framework 5.6.0 then all Qt Framework above and equal to 23 | 5.6.0 can use the plugin without re-compiling. 24 | 25 | * You cannot use the plugin in Qt Framework having lower major version than the 26 | Qt Framework used to build the plugin. 27 | 28 | 29 | # Using QMake. 30 | 31 | You just need to enable the ```BUILD_AS_PLUGIN``` flag in your config. 32 | ``` 33 | $ qmake "CONFIG+=BUILD_AS_PLUGIN" [ProjectFolder] 34 | ``` 35 | 36 | Now you should have ```libQAppImageUpdate.so``` file which is your plugin. Now use this file 37 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 38 | 39 | See the guides on examples on how this is done. 40 | 41 | # Using CMake 42 | 43 | Same as in QMake, you just need to enable ```BUILD_AS_PLUGIN``` flag, 44 | 45 | ``` 46 | $ cmake -DBUILD_AS_PLUGIN=ON [ProjectFolder] 47 | ``` 48 | 49 | Now you should have ```libQAppImageUpdate.so``` file which is your plugin. Now use this file 50 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 51 | 52 | See the guides on examples on how this is done. 53 | -------------------------------------------------------------------------------- /examples/PyQt5Update/Update.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | from PyQt5.QtCore import QPluginLoader 5 | from PyQt5.QtCore import QCoreApplication 6 | 7 | if len(sys.argv) < 2: 8 | print("Usage: ./Update.py [APPIMAGE PATH]") 9 | sys.exit(0) 10 | 11 | app = QCoreApplication(sys.argv) 12 | 13 | # Try to load the plugin from predefined 14 | # Qt Plugin paths. 15 | loader = QPluginLoader() 16 | loader.setFileName('libQAppImageUpdate') 17 | if not loader.load(): 18 | try: 19 | plugin_path = os.environ['PLUGIN_PATH'] 20 | except: 21 | print("Unable to resolve plugin path.") 22 | sys.exit(0) 23 | loader.setFileName(plugin_path) 24 | if not loader.load(): 25 | print("Cannot load plugin because: {}".format(loader.errorString())) 26 | sys.exit(-1) 27 | 28 | 29 | appimage_path = sys.argv[1] 30 | obj = loader.instance() 31 | 32 | def handleError(code, action): 33 | print("ERROR: {}".format(obj.errorCodeToDescriptionString(code))) 34 | app.quit() 35 | 36 | def handleFinishedSignal(result, action): 37 | if action == obj.getConstant("Action::UpdateWithTorrent"): 38 | for i in result: 39 | if i == "UsedTorrent": 40 | used = "No" 41 | if result[i].toBool(): 42 | used = "Yes" 43 | print("{} : {}".format(i, used)) 44 | continue 45 | print("{} : {}".format(i, result[i].toString())) 46 | app.quit() 47 | elif action == obj.getConstant("Action::CheckForUpdate"): 48 | if result['UpdateAvailable'].toBool(): 49 | print("A new version of the AppImage is available.") 50 | print("Updating now... ") 51 | obj.start(obj.getConstant("Action::Update")) 52 | else: 53 | print("You have the latest AppImage!") 54 | app.quit() 55 | 56 | obj.finished.connect(handleFinishedSignal) 57 | obj.error.connect(handleError) 58 | 59 | obj.setAppImagePath(appimage_path) 60 | 61 | print("Checking for Update... ") 62 | obj.start(obj.getConstant("Action::CheckForUpdate")) 63 | sys.exit(app.exec_()) 64 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/UsingPlugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-UsingPlugin 3 | title: Build QAppImageUpdate as Qt Plugin 4 | sidebar_label: Building as Qt Plugin 5 | original_id: UsingPlugin 6 | --- 7 | 8 | QAppImageUpdate can compiled as a **Qt Plugin**. When it is built as a Qt Plugin, QAppImageUpdate can be used from any programming language that supports Qt. 9 | 10 | Qt plugins thus makes us to maintain a single code base instead of maintaining a lot of ports. This makes less bug in the code base and there is no time wasted in making bindings. 11 | 12 | You can see the plugin interface [here](PluginInterface.html). 13 | 14 | To read more about Qt plugins, Please refer the official documentation. 15 | 16 | # Rules in Plugin Usage 17 | 18 | There are specific rules on how plugins are handled by Qt. The following are the key rules in plugin usage. 19 | 20 | * A Qt framework whose major version is higher or equal to the Qt framework 21 | used to build the plugin should work fine with no errors. 22 | 23 | * If you build against Qt Framework 5.6.0 then all Qt Framework above and equal to 24 | 5.6.0 can use the plugin without re-compiling. 25 | 26 | * You cannot use the plugin in Qt Framework having lower major version than the 27 | Qt Framework used to build the plugin. 28 | 29 | 30 | # Using QMake. 31 | 32 | You just need to enable the ```BUILD_AS_PLUGIN``` flag in your config. 33 | ``` 34 | $ qmake "CONFIG+=BUILD_AS_PLUGIN" [ProjectFolder] 35 | ``` 36 | 37 | Now you should have ```libQAppImageUpdate.so``` file which is your plugin. Now use this file 38 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 39 | 40 | See the guides on examples on how this is done. 41 | 42 | # Using CMake 43 | 44 | Same as in QMake, you just need to enable ```BUILD_AS_PLUGIN``` flag, 45 | 46 | ``` 47 | $ cmake -DBUILD_AS_PLUGIN=ON [ProjectFolder] 48 | ``` 49 | 50 | Now you should have ```libQAppImageUpdate.so``` file which is your plugin. Now use this file 51 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 52 | 53 | See the guides on examples on how this is done. 54 | -------------------------------------------------------------------------------- /examples/ProxyUpdate/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int ac, char **av) { 7 | qInfo().noquote() << "ProxyUpdate, Update AppImages Through Proxy."; 8 | qInfo().noquote() << "Copyright (C) 2020, Antony Jr."; 9 | 10 | QCoreApplication app(ac, av); 11 | QAppImageUpdate updater; 12 | 13 | QCommandLineParser parser; 14 | parser.process(app); 15 | auto args = parser.positionalArguments(); 16 | if(args.count() == 0) { 17 | qInfo().noquote() << "\nUsage: " << app.arguments().at(0) << " [APPIMAGE PATH]."; 18 | return -1; 19 | } 20 | int it = 0; 21 | 22 | QObject::connect(&updater, &QAppImageUpdate::error, [&](short ecode, short action) { 23 | qCritical().noquote() << "error:: " << QAppImageUpdate::errorCodeToString(ecode); 24 | app.quit(); 25 | return; 26 | }); 27 | 28 | QObject::connect(&updater, &QAppImageUpdate::progress, 29 | [&](int percentage, qint64 rc, qint64 total, double speed, QString units) { 30 | qInfo().noquote() << "Updating " << percentage << "%: Revised " << rc << "/" << total 31 | << " bytes at " << speed << units << "... "; 32 | }); 33 | 34 | QObject::connect(&updater, &QAppImageUpdate::finished, [&](QJsonObject info, short action) { 35 | qInfo().noquote() << info; 36 | 37 | ++it; 38 | if(it >= parser.positionalArguments().count()) { 39 | app.quit(); 40 | } else { 41 | QString path(args[it]); 42 | updater.setAppImage(path); 43 | updater.start(QAppImageUpdate::Action::Update); 44 | } 45 | return; 46 | }); 47 | 48 | /* set proxy settings */ 49 | QNetworkProxy proxy; 50 | proxy.setType(QNetworkProxy::Socks5Proxy); 51 | proxy.setHostName("127.0.0.1"); 52 | proxy.setPort(9050); 53 | 54 | 55 | 56 | QString path(args[it]); 57 | updater.setAppImage(path); 58 | updater.setProxy(proxy); 59 | updater.setShowLog(true); 60 | updater.start(QAppImageUpdate::Action::Update); 61 | return app.exec(); 62 | } 63 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/UsingPlugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-UsingPlugin 3 | title: Build AppImage Updater Bridge as Qt Plugin 4 | sidebar_label: Building as Qt Plugin. 5 | original_id: UsingPlugin 6 | --- 7 | 8 | AppImage Updater Bridge can compiled as a **Qt Plugin**. When it is built as a Qt Plugin, AppImage Updater Bridge can be used from any programming language that supports Qt. 9 | 10 | Qt plugins thus makes us to maintain a single code base instead of maintaining a lot of ports. This makes less bug in the code base and there is no time wasted in making bindings. 11 | 12 | You can see the plugin interface [here](PluginInterface.html). 13 | 14 | To read more about Qt plugins, Please refer the official documentation. 15 | 16 | # Rules in Plugin Usage 17 | 18 | There are specific rules on how plugins are handled by Qt. The following are the key rules in plugin usage. 19 | 20 | * A Qt framework whose major version is higher or equal to the Qt framework 21 | used to build the plugin should work fine with no errors. 22 | 23 | * If you build against Qt Framework 5.6.0 then all Qt Framework above and equal to 24 | 5.6.0 can use the plugin without re-compiling. 25 | 26 | * You cannot use the plugin in Qt Framework having lower major version than the 27 | Qt Framework used to build the plugin. 28 | 29 | 30 | # Using QMake. 31 | 32 | You just need to enable the ```BUILD_AS_PLUGIN``` flag in your config. 33 | ``` 34 | $ qmake "CONFIG+=BUILD_AS_PLUGIN" [ProjectFolder] 35 | ``` 36 | 37 | Now you should have ```libAppImageUpdaterBridge.so``` file which is your plugin. Now use this file 38 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 39 | 40 | See the guides on examples on how this is done. 41 | 42 | # Using CMake 43 | 44 | Same as in QMake, you just need to enable ```BUILD_AS_PLUGIN``` flag, 45 | 46 | ``` 47 | $ cmake -DBUILD_AS_PLUGIN=ON [ProjectFolder] 48 | ``` 49 | 50 | Now you should have ```libAppImageUpdaterBridge.so``` file which is your plugin. Now use this file 51 | with ```QPluginLoader``` provided by your Qt bindings for your specific programming language. 52 | 53 | See the guides on examples on how this is done. 54 | -------------------------------------------------------------------------------- /docs/ProxyUpdateExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ProxyExample 3 | title: Updating an AppImage using Proxy 4 | sidebar_label: Updating an AppImage using Proxy 5 | --- 6 | 7 | This guide Demonstrates how to use the *QAppImageUpdate* API for updating a single AppImage file through a given **proxy**. 8 | This example parses the path from the program arguments. 9 | 10 | ## main.cpp 11 | 12 | ``` 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | int main(int ac , char **av) 19 | { 20 | if(ac == 1){ 21 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 22 | return 0; 23 | } 24 | 25 | QCoreApplication app(ac , av); 26 | QString AppImagePath = QString(av[1]); 27 | 28 | /* Set proxy settings */ 29 | QNetworkProxy proxy; 30 | /* For this demo, we assume we use a local tor instance. */ 31 | proxy.setType(QNetworkProxy::Socks5Proxy); 32 | proxy.setHostName("127.0.0.1"); 33 | proxy.setPort(9050); 34 | 35 | QAppImageUpdate updater(AppImagePath); 36 | QObject::connect(&updater , &QAppImageUpdate::finished , 37 | [&](QJsonObject info , short action){ 38 | if(action == QAppImageUpdate::Action::Update) { 39 | qInfo() << "New Version Details:: " << info; 40 | app.quit(); 41 | } 42 | }); 43 | QObject::connect(&updater , &QAppImageUpdate::error , 44 | [&](short e, short action){ 45 | if(action == QAppImageUpdate::Action::Update) { 46 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 47 | app.quit(); 48 | } 49 | }); 50 | updpater.setShowLog(true); // Display log 51 | 52 | /* Using proxy. */ 53 | updater.setProxy(proxy); 54 | 55 | updater.start(QAppImageUpdate::Action::Update); /* Start the update. */ 56 | return app.exec(); 57 | } 58 | 59 | ``` 60 | 61 | ## update.pro 62 | 63 | ``` 64 | include(QAppImageUpdate/QAppImageUpdate.pri) 65 | TEMPLATE = app 66 | TARGET = update 67 | SOURCES += main.cpp 68 | ``` 69 | 70 | ## Compilation and Execution 71 | 72 | ``` 73 | $ mkdir build 74 | $ cd build 75 | $ qmake .. 76 | $ make -j$(nproc) 77 | $ ./update some.AppImage 78 | ``` 79 | 80 | A advanced verison of this program has been implemented in the examples directory. 81 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/ProxyUpdateExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-ProxyExample 3 | title: Updating an AppImage using Proxy 4 | sidebar_label: Updating an AppImage using Proxy 5 | original_id: ProxyExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *QAppImageUpdate* API for updating a single AppImage file through a given **proxy**. 9 | This example parses the path from the program arguments. 10 | 11 | ## main.cpp 12 | 13 | ``` 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int main(int ac , char **av) 20 | { 21 | if(ac == 1){ 22 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 23 | return 0; 24 | } 25 | 26 | QCoreApplication app(ac , av); 27 | QString AppImagePath = QString(av[1]); 28 | 29 | /* Set proxy settings */ 30 | QNetworkProxy proxy; 31 | /* For this demo, we assume we use a local tor instance. */ 32 | proxy.setType(QNetworkProxy::Socks5Proxy); 33 | proxy.setHostName("127.0.0.1"); 34 | proxy.setPort(9050); 35 | 36 | QAppImageUpdate updater(AppImagePath); 37 | QObject::connect(&updater , &QAppImageUpdate::finished , 38 | [&](QJsonObject info , short action){ 39 | if(action == QAppImageUpdate::Action::Update) { 40 | qInfo() << "New Version Details:: " << info; 41 | app.quit(); 42 | } 43 | }); 44 | QObject::connect(&updater , &QAppImageUpdate::error , 45 | [&](short e, short action){ 46 | if(action == QAppImageUpdate::Action::Update) { 47 | qInfo() << "error:: " << QAppImageUpdate::errorCodeToString(e); 48 | app.quit(); 49 | } 50 | }); 51 | updpater.setShowLog(true); // Display log 52 | 53 | /* Using proxy. */ 54 | updater.setProxy(proxy); 55 | 56 | updater.start(QAppImageUpdate::Action::Update); /* Start the update. */ 57 | return app.exec(); 58 | } 59 | 60 | ``` 61 | 62 | ## update.pro 63 | 64 | ``` 65 | include(QAppImageUpdate/QAppImageUpdate.pri) 66 | TEMPLATE = app 67 | TARGET = update 68 | SOURCES += main.cpp 69 | ``` 70 | 71 | ## Compilation and Execution 72 | 73 | ``` 74 | $ mkdir build 75 | $ cd build 76 | $ qmake .. 77 | $ make -j$(nproc) 78 | $ ./update some.AppImage 79 | ``` 80 | 81 | A advanced verison of this program has been implemented in the examples directory. 82 | -------------------------------------------------------------------------------- /include/qappimageupdate.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QAPPIMAGE_UPDATE_HPP_INCLUDED 2 | #define QAPPIMAGE_UPDATE_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | /// Enums and Codes 13 | #include "qappimageupdateenums.hpp" 14 | #include "qappimageupdatecodes.hpp" 15 | /// ---- 16 | 17 | /// Forward declare private class. 18 | class QAppImageUpdatePrivate; 19 | 20 | class QAppImageUpdate : public QObject { 21 | Q_OBJECT 22 | public: 23 | QAppImageUpdate(bool singleThreaded = true, QObject *parent = nullptr); 24 | QAppImageUpdate(const QString &AppImagePath, bool singleThreaded = true, QObject *parent = nullptr); 25 | QAppImageUpdate(QFile *AppImage, bool singleThreaded = true, QObject *parent = nullptr); 26 | ~QAppImageUpdate(); 27 | 28 | struct Action : public QAppImageUpdateCodes::Action { }; 29 | struct GuiFlag : public QAppImageUpdateCodes::GuiFlag { }; 30 | struct Error : public QAppImageUpdateEnums::Error { }; 31 | 32 | static QString errorCodeToString(short); 33 | static QString errorCodeToDescriptionString(short); 34 | static QString versionString(); 35 | public Q_SLOTS: 36 | void setApplicationName(const QString&); 37 | void setIcon(QByteArray); 38 | void setGuiFlag(int); 39 | void setAppImage(const QString&); 40 | void setAppImage(QFile*); 41 | void setShowLog(bool); 42 | void setOutputDirectory(const QString&); 43 | void setProxy(const QNetworkProxy&); 44 | void start(short action = Action::Update, 45 | int flags = GuiFlag::None, 46 | QByteArray icon = QByteArray()); 47 | void cancel(); 48 | void clear(); 49 | 50 | Q_SIGNALS: 51 | void torrentClientStarted(); 52 | void torrentStatus(int,int); 53 | void started(short); 54 | void canceled(short); 55 | void finished(QJsonObject info, short); 56 | void progress(int, qint64, qint64, double, QString, short); 57 | void logger(QString, QString); 58 | void error(short, short); 59 | void quit(); 60 | 61 | private: 62 | QSharedPointer m_Private; 63 | }; 64 | 65 | #endif // QAPPIMAGE_UPDATE_HPP_INCLUDED 66 | -------------------------------------------------------------------------------- /examples/PyQt5UpdateWithTorrent/Update.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | from PyQt5.QtCore import QPluginLoader 5 | from PyQt5.QtCore import QCoreApplication 6 | 7 | if len(sys.argv) < 2: 8 | print("Usage: ./Update.py [APPIMAGE PATH]") 9 | sys.exit(0) 10 | 11 | app = QCoreApplication(sys.argv) 12 | 13 | # Try to load the plugin from predefined 14 | # Qt Plugin paths. 15 | loader = QPluginLoader() 16 | loader.setFileName('libQAppImageUpdate') 17 | if not loader.load(): 18 | try: 19 | plugin_path = os.environ['PLUGIN_PATH'] 20 | except: 21 | print("Unable to resolve plugin path.") 22 | sys.exit(0) 23 | loader.setFileName(plugin_path) 24 | if not loader.load(): 25 | print("Cannot load plugin because: {}".format(loader.errorString())) 26 | sys.exit(-1) 27 | 28 | 29 | appimage_path = sys.argv[1] 30 | obj = loader.instance() 31 | 32 | def handleError(code, action): 33 | print("ERROR: {}".format(obj.errorCodeToDescriptionString(code))) 34 | app.quit() 35 | 36 | def handleProgress(percentage): 37 | print("Done: {}".format(percentage)) 38 | 39 | def handleFinishedSignal(result, action): 40 | if action == obj.getConstant("Action::UpdateWithTorrent"): 41 | for i in result: 42 | if i == "UsedTorrent": 43 | used = "No" 44 | if result[i].toBool(): 45 | used = "Yes" 46 | print("{} : {}".format(i, used)) 47 | continue 48 | print("{} : {}".format(i, result[i].toString())) 49 | app.quit() 50 | elif action == obj.getConstant("Action::CheckForUpdate"): 51 | if result['UpdateAvailable'].toBool(): 52 | print("A new version of the AppImage is available.") 53 | print("Updating now... ") 54 | obj.start(obj.getConstant("Action::UpdateWithTorrent")) 55 | else: 56 | print("You have the latest AppImage!") 57 | app.quit() 58 | 59 | obj.finished.connect(handleFinishedSignal) 60 | obj.progress.connect(handleProgress) 61 | obj.error.connect(handleError) 62 | 63 | obj.setAppImagePath(appimage_path) 64 | 65 | print("Checking for Update... ") 66 | obj.start(obj.getConstant("Action::CheckForUpdate")) 67 | sys.exit(app.exec_()) 68 | -------------------------------------------------------------------------------- /include/rangedownloader_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RANGE_DOWNLOADER_PRIVATE_HPP_INCLUDED 2 | #define RANGE_DOWNLOADER_PRIVATE_HPP_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "rangereply.hpp" 11 | 12 | class RangeDownloaderPrivate : public QObject { 13 | Q_OBJECT 14 | public: 15 | RangeDownloaderPrivate(QNetworkAccessManager*, QObject *parent = nullptr); 16 | ~RangeDownloaderPrivate(); 17 | public Q_SLOTS: 18 | void setBlockSize(qint32); 19 | void setTargetFileUrl(const QUrl&); 20 | void setBytesWritten(qint64); 21 | void setTargetFileLength(qint32); 22 | void setFullDownload(bool); 23 | void appendRange(qint32, qint32); 24 | 25 | void start(); 26 | void cancel(); 27 | 28 | private Q_SLOTS: 29 | QNetworkRequest makeRangeRequest(const QUrl&, const QPair&); 30 | void handleUrlCheckError(QNetworkReply::NetworkError); 31 | void handleUrlCheck(qint64, qint64); 32 | void handleRangeReplyCancel(int); 33 | void handleRangeReplyRestart(int); 34 | void handleRangeReplyProgress(qint64, int); 35 | void handleRangeReplyError(QNetworkReply::NetworkError, int, bool); 36 | void handleRangeReplyFinished(qint32,qint32,QByteArray*, int); 37 | Q_SIGNALS: 38 | void started(); 39 | void canceled(); 40 | void finished(); 41 | void error(QNetworkReply::NetworkError); 42 | 43 | void data(QByteArray *, bool); 44 | void rangeData(qint32, qint32, QByteArray *, /*this is true when the given range is the last one*/bool); 45 | 46 | void progress(int, qint64, qint64, double, QString); 47 | private: 48 | bool b_Finished = false, 49 | b_Running = false, 50 | b_CancelRequested = false, 51 | b_FullDownload = false; 52 | int n_Active = -1, 53 | n_Done = 0; 54 | QUrl m_Url; 55 | qint32 n_BlockSize = 1024; 56 | qint64 n_BytesWritten = 0; 57 | qint64 n_TotalSize = -1; 58 | qint64 n_RecievedBytes; 59 | 60 | QNetworkAccessManager *m_Manager; 61 | QElapsedTimer m_ElapsedTimer; 62 | QVector> m_RequiredBlocks; 63 | QVector m_ActiveRequests; 64 | 65 | }; 66 | #endif // RANGE_DOWNLOADER_PRIVATE_HPP_INCLUDED 67 | -------------------------------------------------------------------------------- /website/siteConfig.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | /* List of projects/orgs using your project for the users page */ 9 | 10 | const users = [ 11 | { 12 | caption: 'AppImageUpdater', 13 | image: '/QAppImageUpdate/img/AppImageUpdater.png', 14 | infoLink: 'https://github.com/antony-jr/AppImageUpdater', 15 | pinned: true, 16 | }, 17 | { 18 | caption: 'e2designer', 19 | image: '/QAppImageUpdate/img/e2designer.png', 20 | infoLink: 'https://gitlab.com/technic93/e2designer', 21 | pinned: true, 22 | }, 23 | { 24 | caption: 'Update Deploy Qt', 25 | image: '/QAppImageUpdate/img/updatedeployqt.png', 26 | infoLink: 'https://github.com/TheFutureShell/updatedeployqt', 27 | pinned: true, 28 | }, 29 | ]; 30 | 31 | const siteConfig = { 32 | title: 'QAppImageUpdate' /* title for your website */, 33 | tagline: 'Qt Library and Plugin to AppImage Update Mechanism.', 34 | url: 'https://antony-jr.github.io' /* your website url */, 35 | baseUrl: '/QAppImageUpdate/' /* base url for your project */, 36 | projectName: 'QAppImageUpdate', 37 | headerLinks: [ 38 | {doc: 'Installation', label: 'Docs'}, 39 | {page: 'help', label: 'Help'}, 40 | {blog: false, label: 'Blog'}, 41 | ], 42 | users, 43 | /* path to images for header/footer */ 44 | headerIcon: 'img/AppImageUpdaterBridge.png', 45 | footerIcon: 'img/AppImageUpdaterBridge.png', 46 | favicon: 'img/favicon.png', 47 | /* colors for website */ 48 | colors: { 49 | primaryColor: '#709cb7', 50 | secondaryColor: '#1a8cff', 51 | }, 52 | // This copyright info is used in /core/Footer.js and blog rss/atom feeds. 53 | copyright: 54 | 'Copyright © ' + 55 | new Date().getFullYear() + 56 | ' Antony Jr.', 57 | organizationName: 'antony-jr', // or set an env variable ORGANIZATION_NAME 58 | highlight: { 59 | // Highlight.js theme to use for syntax highlighting in code blocks 60 | theme: 'default', 61 | }, 62 | scripts: ['https://buttons.github.io/buttons.js'], 63 | // You may provide arbitrary config keys to be used as needed by your template. 64 | repoUrl: 'https://github.com/antony-jr/QAppImageUpdate', 65 | }; 66 | 67 | module.exports = siteConfig; 68 | -------------------------------------------------------------------------------- /scripts/docker_build.sh: -------------------------------------------------------------------------------- 1 | # Run it like so, 2 | # docker run -v $PWD:/docker-share -it ubuntu:xenial bash scripts/docker_build.sh 3 | # To get libQAppImageUpdate.so Qt Plugin. 4 | 5 | # Install dependencies 6 | apt update 7 | apt upgrade -y 8 | apt install software-properties-common build-essential libarchive13 libarchive-dev wget expat -y 9 | add-apt-repository ppa:beineri/opt-qt563-xenial -y 10 | apt-get update -qq 11 | apt install libgl1-mesa-dev xvfb qt56base -y 12 | 13 | cd /docker-share/ 14 | rm -rf build 15 | mkdir build 16 | cd build 17 | 18 | # Build OpenSSL Static version 19 | wget "https://www.openssl.org/source/openssl-1.1.1j.tar.gz" 20 | tar -xf openssl-1.1.1j.tar.gz 21 | cd openssl-1.1.1j 22 | ./config no-shared --prefix=/usr/ --openssldir=/usr/ 23 | make -j$(nproc) 24 | make install -j$(nproc) 25 | cd .. 26 | 27 | # Install CURL 28 | wget "https://curl.se/download/curl-7.75.0.tar.gz" 29 | tar -xf curl-7.75.0.tar.gz 30 | cd curl-7.75.0 31 | ,/configure 32 | make -j$(nproc) 33 | make install -j$(nproc) 34 | cd .. 35 | 36 | # Install CMake 3.19.6 37 | wget "https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6.tar.gz" 38 | tar -xf cmake-3.19.6.tar.gz 39 | cd cmake-3.19.6 40 | ./bootstrap 41 | make -j$(nproc) 42 | make install -j$(nproc) 43 | cd .. 44 | 45 | # Install Boost libraries 46 | wget "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz" 47 | tar -xf boost_1_75_0.tar.gz 48 | cd boost_1_75_0 49 | ./bootstrap.sh 50 | cp b2 /usr/bin/ 51 | echo "using gcc ;" > ~/user-config.jam 52 | export BOOST_ROOT=$PWD 53 | export BOOST_BUILD_PATH=$PWD/tools/build 54 | BOOST_ROOT=$PWD BOOST_BUILD_PATH=$PWD/tools/build b2 cxxflags="-std=c++14" variant=release link=static install -j$(nproc) --with-system --with-chrono --with-random > /dev/null 55 | cd .. 56 | 57 | # Install Torrent Rasterbar 58 | wget "https://github.com/arvidn/libtorrent/releases/download/libtorrent-1.2.8/libtorrent-rasterbar-1.2.8.tar.gz" 59 | tar -xvf libtorrent-rasterbar-1.2.8.tar.gz 60 | cd libtorrent-rasterbar-1.2.8 61 | cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON . 62 | make -j$(nproc) 63 | make install -j$(nproc) 64 | cd .. 65 | 66 | # Now Build QAppImageUpdate Qt Plugin. 67 | source /opt/qt56/bin/qt56-env.sh 68 | cmake -DDECENTRALIZED_UPDATE_ENABLED=ON -DBUILD_AS_PLUGIN=ON .. 69 | make -j$(nproc) 70 | 71 | cp libQAppImageUpdate.* .. 72 | cd .. 73 | rm -rf build 74 | -------------------------------------------------------------------------------- /include/torrentdownloader_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TORRENT_DOWNLOADER_PRIVATE_HPP_INCLUDED 2 | #define TORRENT_DOWNLOADER_PRIVATE_HPP_INCLUDED 3 | #ifdef DECENTRALIZED_UPDATE_ENABLED 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | class TorrentDownloaderPrivate : public QObject { 25 | Q_OBJECT 26 | public: 27 | TorrentDownloaderPrivate(QNetworkAccessManager*); 28 | ~TorrentDownloaderPrivate(); 29 | public Q_SLOTS: 30 | void setTargetFileDone(qint64); 31 | void setTargetFileLength(qint64); 32 | void setTargetFile(QTemporaryFile*); 33 | void setTorrentFileUrl(const QUrl&); 34 | void setTargetFileUrl(const QUrl&); 35 | 36 | void start(); 37 | void cancel(); 38 | 39 | private Q_SLOTS: 40 | void handleTorrentFileData(qint64, qint64); 41 | void handleTorrentFileError(QNetworkReply::NetworkError); 42 | void handleTorrentFileFinish(); 43 | void handleTimeout(); 44 | 45 | void torrentLoop(); 46 | 47 | Q_SIGNALS: 48 | void started(); 49 | void canceled(); 50 | void finished(); 51 | void error(QNetworkReply::NetworkError); 52 | 53 | void logger(QString); 54 | void progress(int, qint64, qint64, double, QString); 55 | void torrentStatus(int,int); 56 | private: 57 | bool b_Finished = false, 58 | b_Running = false, 59 | b_CancelRequested = false; 60 | 61 | qint64 n_TargetFileLength, 62 | n_TargetFileDone; 63 | QTimer m_Timer; 64 | QTimer m_TimeoutTimer; 65 | QUrl m_TorrentFileUrl, 66 | m_TargetFileUrl; 67 | QTemporaryFile *m_File; 68 | QNetworkAccessManager *m_Manager; 69 | QScopedPointer m_TorrentMeta; 70 | QScopedPointer m_Session; 71 | lt::torrent_handle m_Handle; 72 | }; 73 | #endif // DECENTRALIZED_UPDATE_ENABLED 74 | #endif // TORRENT_DOWNLOADER_PRIVATE_HPP_INCLUDED 75 | -------------------------------------------------------------------------------- /include/zsyncinternalstructures_p.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 3-Clause License 3 | * 4 | * Copyright (c) 2018-2019, Antony jr 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * * Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * @filename : zsyncinternalstructures_p.hpp 33 | * @description : some data types from the legacy source code. 34 | */ 35 | #ifndef ZSYNC_INTERNAL_STRUCTURES_HPP_INCLUDED 36 | #define ZSYNC_INTERNAL_STRUCTURES_HPP_INCLUDED 37 | #include 38 | 39 | static constexpr unsigned short CHECKSUM_SIZE = 16; 40 | static constexpr unsigned short BITHASHBITS = 3; 41 | typedef qint32 zs_blockid; 42 | 43 | struct rsum { 44 | unsigned short a; 45 | unsigned short b; 46 | } __attribute__((packed)); 47 | 48 | struct hash_entry { 49 | struct hash_entry *next; /* next entry with the same rsum */ 50 | struct rsum r; 51 | unsigned char checksum[CHECKSUM_SIZE]; 52 | }; 53 | #endif // ZSYNC_INTERNAL_STRUCTURES_HPP_INCLUDED 54 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AppImageProxyUpdateExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AppImageDeltaRevisionerProxyExample 3 | title: Updating an AppImage using Proxy 4 | sidebar_label: Updating an AppImage using Proxy 5 | original_id: AppImageDeltaRevisionerProxyExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *AppImageUpdaterBridge* APIs for updating a single AppImage file through a given **proxy**. 9 | This example parses the path from the program arguments , And uses the *[AppImageDeltaRevisioner]()* class to 10 | perform the actual delta update. 11 | 12 | ## main.cpp 13 | 14 | ``` 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | int main(int ac , char **av) 21 | { 22 | if(ac == 1){ 23 | qInfo() << "Usage: " << av[0] << " [APPIMAGE PATH]"; 24 | return 0; 25 | } 26 | 27 | using AppImageUpdaterBridge::AppImageDeltaRevisioner; 28 | using AppImageUpdaterBridge::errorCodeToString; 29 | QCoreApplication app(ac , av); 30 | QString AppImagePath = QString(av[1]); 31 | 32 | /* Set proxy settings */ 33 | QNetworkProxy proxy; 34 | /* For this demo , we assume we use a local tor instance. */ 35 | proxy.setType(QNetworkProxy::Socks5Proxy); 36 | proxy.setHostName("127.0.0.1"); 37 | proxy.setPort(9050); 38 | 39 | AppImageDeltaRevisioner DRevisioner(AppImagePath); 40 | QObject::connect(&DRevisioner , &AppImageDeltaRevisioner::finished , 41 | [&](QJsonObject newVersionDetails , QString oldVersionPath){ 42 | (void)oldVersionPath; 43 | qInfo() << "New Version Details:: " << newVersionDetails; 44 | app.quit(); 45 | }); 46 | QObject::connect(&DRevisioner , &AppImageDeltaRevisioner::error , 47 | [&](short e){ 48 | qInfo() << "error:: " << errorCodeToString(e); 49 | app.quit(); 50 | }); 51 | DRevisioner.setShowLog(true); // Display log 52 | 53 | /* Using proxy. */ 54 | DRevisioner.setProxy(proxy); 55 | 56 | DRevisioner.start(); /* Start the update. */ 57 | return app.exec(); 58 | } 59 | 60 | ``` 61 | 62 | ## update.pro 63 | 64 | ``` 65 | include(AppImageUpdaterBridge/AppImageUpdaterBridge.pri) 66 | TEMPLATE = app 67 | TARGET = update 68 | SOURCES += main.cpp 69 | ``` 70 | 71 | ## Compilation and Execution 72 | 73 | ``` 74 | $ mkdir build 75 | $ cd build 76 | $ qmake .. 77 | $ make -j$(nproc) 78 | $ ./update some.AppImage 79 | ``` 80 | 81 | A advanced verison of this program has been implemented in the examples directory. 82 | -------------------------------------------------------------------------------- /docs/PyQt5PluginExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: PyQt5PluginExample 3 | title: Using QAppImageUpdate Plugin in PyQt5 4 | sidebar_label: Using Plugin in PyQt5 5 | --- 6 | 7 | This guide Demonstrates how to use the *QAppImageUpdate* plugin to update a single AppImage file. 8 | This example assumes you are using PyQt5 as your python binding to Qt framework. 9 | 10 | > Note that if the plugin is placed in the predefined Qt Plugin path, then you don't need the 11 | > absolute path of the plugin. Simply set the file name to 'libQAppImageUpdate'. 12 | 13 | 14 | ## Building the Plugin 15 | 16 | ``` 17 | $ git clone https://github.com/antony-jr/QAppImageUpdate 18 | $ cd QAppImageUpdate 19 | $ mkdir build 20 | $ cd build 21 | $ cmake -DBUILD_AS_PLUGIN .. 22 | $ make -j$(nproc) 23 | $ export PLUGIN_PATH=$(pwd)/libQAppImageUpdate.so 24 | ``` 25 | 26 | ## Update.py 27 | 28 | ``` 29 | #!/usr/bin/env python3 30 | import os 31 | import sys 32 | from PyQt5.QtCore import QPluginLoader 33 | from PyQt5.QtCore import QCoreApplication 34 | 35 | if len(sys.argv) < 2: 36 | print("Usage: ./Update.py [APPIMAGE PATH]") 37 | sys.exit(0) 38 | 39 | app = QCoreApplication(sys.argv) 40 | 41 | # Try to load the plugin from predefined 42 | # Qt Plugin paths. 43 | loader = QPluginLoader() 44 | loader.setFileName('libQAppImageUpdate') 45 | if not loader.load(): 46 | try: 47 | plugin_path = os.eviron['PLUGIN_PATH'] 48 | except: 49 | print("Unable to resolve plugin path.") 50 | sys.exit(0) 51 | loader.setFileName(plugin_path) 52 | if not loader.load(): 53 | print("Cannot load plugin because: {}".format(loader.errorString())) 54 | sys.exit(-1) 55 | 56 | 57 | appimage_path = sys.argv[1] 58 | obj = loader.instance() 59 | 60 | def handleFinish(info, action): 61 | if action == obj.getConstant("Action::CheckForUpdate"): 62 | if info["UpdateAvailable"].toBool(): 63 | print("A new version of the AppImage is available.") 64 | print("Updating now... ") 65 | obj.start(obj.getConstant("Action::Update")) 66 | elif action == obj.getConstant("Action::Update"): 67 | print(info) 68 | app.quit() 69 | 70 | def handleError(code): 71 | print("ERROR: {}".format(obj.errorCodeToDescriptionString(code))) 72 | app.quit() 73 | 74 | obj.finished.connect(handleFinish) 75 | obj.error.connect(handleError) 76 | 77 | obj.setAppImagePath(appimage_path) 78 | 79 | print("Checking for Update... ") 80 | obj.start(obj.getContant("Action::CheckForUpdate")) 81 | sys.exit(app.exec_()) 82 | ``` 83 | 84 | ## Execution 85 | 86 | ``` 87 | $ chmod +x Update.py 88 | $ ./Update.py some.AppImage 89 | ``` 90 | 91 | See the examples directory in the source tree for more examples. 92 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AppImageUpdaterBridgeStatusCodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AppImageUpdaterBridgeStatusCodes 3 | title: Handling Status from AppImageUpdaterBridge 4 | sidebar_label: Status Codes 5 | original_id: AppImageUpdaterBridgeStatusCodes 6 | --- 7 | 8 | Using ```AppImageUpdaterBridge::statusCodeToString(code)``` you can get the status code as 9 | a QString , The below table tabulates all status codes with respect to their status name. 10 | 11 | > Note: All are under the AppImageUpdaterBridge namespace so make sure to include it. 12 | 13 | 14 | | Status Code |Value| 15 | |--------------------------------------------------------------|-----| 16 | | Initializing | 0 | 17 | | Idle | 1 | 18 | | OpeningAppimage | 2 | 19 | | CalculatingAppimageSha1Hash | 3 | 20 | | ReadingAppimageMagicBytes | 4 | 21 | | ReadingAppimageUpdateInformation | 5 | 22 | | FindingAppimageType | 6 | 23 | | FindingAppimageArchitecture | 7 | 24 | | MappingAppimageToMemory | 8 | 25 | | SearchingForUpdateInformationSectionHeader | 9 | 26 | | UnmappingAppimageFromMemory | 10 | 27 | | FinalizingAppimageEmbededUpdateInformation | 11 | 28 | | ParsingAppimageEmbededUpdateInformation=50 | 50 | 29 | | RequestingGithubApi | 51 | 30 | | ParsingGithubApiResponse | 52 | 31 | | RequestingZsyncControlFile | 53 | 32 | | RequestingBintray | 54 | 33 | | ParsingBintrayRedirectedUrlForLatestPackageUrl | 55 | 34 | | ParsingZsyncControlFile | 56 | 35 | | SearchingTargetFileChecksumBlockOffsetInZsyncControlFile | 57 | 36 | | StoringZsyncControlFileDataToMemory | 58 | 37 | | FinalizingParsingZsyncControlFile | 59 | 38 | | WrittingDownloadedBlockRanges | 100 | 39 | | EmittingRequiredBlockRanges | 101 | 40 | | CheckingChecksumsForDownloadedBlockRanges | 102 | 41 | | WrittingDownloadedBlockRangesToTargetFile | 103 | 42 | | CalculatingTargetFileSha1Hash | 104 | 43 | | ConstructingTargetFile | 105 | 44 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/PyQt5PluginExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-PyQt5PluginExample 3 | title: Using AppImage Updater Bridge Plugin in PyQt5 4 | sidebar_label: Using Plugin in PyQt5 5 | original_id: PyQt5PluginExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *AppImageUpdaterBridge* plugin to update a single AppImage file. 9 | This example assumes you are using PyQt5 as your python binding to Qt framework. 10 | 11 | > Note that if the plugin is placed in the predefined Qt Plugin path, then you don't need the 12 | > absolute path of the plugin. Simply set the file name to 'libAppImageUpdaterBridge'. 13 | 14 | 15 | ## Building the Plugin 16 | 17 | ``` 18 | $ git clone https://github.com/antony-jr/AppImageUpdaterBridge 19 | $ cd AppImageUpdaterBridge 20 | $ mkdir build 21 | $ cd build 22 | $ cmake -DBUILD_AS_PLUGIN .. 23 | $ make -j$(nproc) 24 | $ export PLUGIN_PATH=$(pwd)/libAppImageUpdaterBridge.so 25 | ``` 26 | 27 | ## Update.py 28 | 29 | ``` 30 | #!/usr/bin/env python3 31 | import os 32 | import sys 33 | from PyQt5.QtCore import QPluginLoader 34 | from PyQt5.QtCore import QCoreApplication 35 | 36 | if len(sys.argv) < 2: 37 | print("Usage: ./Update.py [APPIMAGE PATH]") 38 | sys.exit(0) 39 | 40 | app = QCoreApplication(sys.argv) 41 | 42 | # Try to load the plugin from predefined 43 | # Qt Plugin paths. 44 | loader = QPluginLoader() 45 | loader.setFileName('libAppImageUpdaterBridge') 46 | if not loader.load(): 47 | try: 48 | plugin_path = os.eviron['PLUGIN_PATH'] 49 | except: 50 | print("Unable to resolve plugin path.") 51 | sys.exit(0) 52 | loader.setFileName(plugin_path) 53 | if not loader.load(): 54 | print("Cannot load plugin because: {}".format(loader.errorString())) 55 | sys.exit(-1) 56 | 57 | 58 | appimage_path = sys.argv[1] 59 | obj = loader.instance() 60 | 61 | def handleFinish(info, old_appimge_path): 62 | print(info) 63 | app.quit() 64 | 65 | def handleError(code): 66 | print("A error occured, error code: {}".format(code)) 67 | app.quit() 68 | 69 | def handleUpdate(avail): 70 | if avail: 71 | print("A new version of the AppImage is available.") 72 | print("Updating now... ") 73 | obj.start() 74 | else: 75 | print("You have the latest AppImage!") 76 | app.quit() 77 | 78 | obj.updateAvailable.connect(handleUpdate) 79 | obj.finished.connect(handleFinish) 80 | obj.error.connect(handleError) 81 | 82 | obj.setAppImage(appimage_path) 83 | 84 | print("Checking for Update... ") 85 | obj.checkForUpdate() 86 | sys.exit(app.exec_()) 87 | ``` 88 | 89 | ## Execution 90 | 91 | ``` 92 | $ chmod +x Update.py 93 | $ ./Update.py some.AppImage 94 | ``` 95 | 96 | See the examples directory in the source tree for more examples. 97 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/PyQt5PluginExample.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-PyQt5PluginExample 3 | title: Using QAppImageUpdate Plugin in PyQt5 4 | sidebar_label: Using Plugin in PyQt5 5 | original_id: PyQt5PluginExample 6 | --- 7 | 8 | This guide Demonstrates how to use the *QAppImageUpdate* plugin to update a single AppImage file. 9 | This example assumes you are using PyQt5 as your python binding to Qt framework. 10 | 11 | > Note that if the plugin is placed in the predefined Qt Plugin path, then you don't need the 12 | > absolute path of the plugin. Simply set the file name to 'libQAppImageUpdate'. 13 | 14 | 15 | ## Building the Plugin 16 | 17 | ``` 18 | $ git clone https://github.com/antony-jr/QAppImageUpdate 19 | $ cd QAppImageUpdate 20 | $ mkdir build 21 | $ cd build 22 | $ cmake -DBUILD_AS_PLUGIN .. 23 | $ make -j$(nproc) 24 | $ export PLUGIN_PATH=$(pwd)/libQAppImageUpdate.so 25 | ``` 26 | 27 | ## Update.py 28 | 29 | ``` 30 | #!/usr/bin/env python3 31 | import os 32 | import sys 33 | from PyQt5.QtCore import QPluginLoader 34 | from PyQt5.QtCore import QCoreApplication 35 | 36 | if len(sys.argv) < 2: 37 | print("Usage: ./Update.py [APPIMAGE PATH]") 38 | sys.exit(0) 39 | 40 | app = QCoreApplication(sys.argv) 41 | 42 | # Try to load the plugin from predefined 43 | # Qt Plugin paths. 44 | loader = QPluginLoader() 45 | loader.setFileName('libQAppImageUpdate') 46 | if not loader.load(): 47 | try: 48 | plugin_path = os.eviron['PLUGIN_PATH'] 49 | except: 50 | print("Unable to resolve plugin path.") 51 | sys.exit(0) 52 | loader.setFileName(plugin_path) 53 | if not loader.load(): 54 | print("Cannot load plugin because: {}".format(loader.errorString())) 55 | sys.exit(-1) 56 | 57 | 58 | appimage_path = sys.argv[1] 59 | obj = loader.instance() 60 | 61 | def handleFinish(info, action): 62 | if action == obj.getConstant("Action::CheckForUpdate"): 63 | if info["UpdateAvailable"].toBool(): 64 | print("A new version of the AppImage is available.") 65 | print("Updating now... ") 66 | obj.start(obj.getConstant("Action::Update")) 67 | elif action == obj.getConstant("Action::Update"): 68 | print(info) 69 | app.quit() 70 | 71 | def handleError(code): 72 | print("ERROR: {}".format(obj.errorCodeToDescriptionString(code))) 73 | app.quit() 74 | 75 | obj.finished.connect(handleFinish) 76 | obj.error.connect(handleError) 77 | 78 | obj.setAppImagePath(appimage_path) 79 | 80 | print("Checking for Update... ") 81 | obj.start(obj.getContant("Action::CheckForUpdate")) 82 | sys.exit(app.exec_()) 83 | ``` 84 | 85 | ## Execution 86 | 87 | ``` 88 | $ chmod +x Update.py 89 | $ ./Update.py some.AppImage 90 | ``` 91 | 92 | See the examples directory in the source tree for more examples. 93 | -------------------------------------------------------------------------------- /QAppImageUpdate.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD $$PWD/include 2 | QT += core network widgets 3 | CONFIG += staticlib 4 | HEADERS += \ 5 | $$PWD/include/appimageupdateinformation_p.hpp \ 6 | $$PWD/include/zsyncremotecontrolfileparser_p.hpp \ 7 | $$PWD/include/zsyncinternalstructures_p.hpp \ 8 | $$PWD/include/zsyncwriter_p.hpp \ 9 | $$PWD/include/rangereply_p.hpp \ 10 | $$PWD/include/rangereply.hpp \ 11 | $$PWD/include/rangedownloader_p.hpp \ 12 | $$PWD/include/rangedownloader.hpp \ 13 | $$PWD/include/qappimageupdateenums.hpp \ 14 | $$PWD/include/qappimageupdatecodes.hpp \ 15 | $$PWD/include/qappimageupdate_p.hpp \ 16 | $$PWD/include/qappimageupdate.hpp \ 17 | $$PWD/include/helpers_p.hpp \ 18 | $$PWD/include/softwareupdatedialog_p.hpp 19 | 20 | SOURCES += \ 21 | $$PWD/src/appimageupdateinformation_p.cc \ 22 | $$PWD/src/zsyncremotecontrolfileparser_p.cc \ 23 | $$PWD/src/zsyncwriter_p.cc \ 24 | $$PWD/src/rangereply_p.cc \ 25 | $$PWD/src/rangereply.cc \ 26 | $$PWD/src/rangedownloader_p.cc \ 27 | $$PWD/src/rangedownloader.cc \ 28 | $$PWD/src/qappimageupdate_p.cc \ 29 | $$PWD/src/qappimageupdate.cc \ 30 | $$PWD/src/helpers_p.cc \ 31 | $$PWD/src/softwareupdatedialog_p.cc 32 | 33 | 34 | FORMS += $$PWD/src/AppImageUpdaterDialog.ui \ 35 | $$PWD/include/SoftwareUpdateDialog.ui 36 | 37 | NO_GUI { 38 | message(QAppImageUpdate widgets will be disabled for this build.) 39 | QT -= widgets 40 | DEFINES += NO_GUI 41 | HEADERS -= $$PWD/include/softwareupdatedialog_p.hpp 42 | SOURCES -= $$PWD/src/softwareupdatedialog_p.cc 43 | 44 | FORMS -= $$PWD/src/AppImageUpdaterDialog.ui \ 45 | $$PWD/include/SoftwareUpdateDialog.ui 46 | } 47 | 48 | LOGGING_DISABLED { 49 | message(Logging will be disabled for this build.) 50 | DEFINES += LOGGING_DISABLED 51 | } 52 | 53 | DECENTRALIZED_UPDATE_ENABLED { 54 | message(Decentralized update feature will be enabled for this build.) 55 | DEFINES += DECENTRALIZED_UPDATE_ENABLED 56 | HEADERS += $$PWD/include/torrentdownloader.hpp 57 | HEADERS += $$PWD/include/torrentdownloader_p.hpp 58 | HEADERS += $$PWD/include/seeder.hpp 59 | HEADERS += $$PWD/include/seeder_p.hpp 60 | 61 | SOURCES += $$PWD/src/torrentdownloader.cc 62 | SOURCES += $$PWD/src/torrentdownloader_p.cc 63 | SOURCES += $$PWD/src/seeder.cc 64 | SOURCES += $$PWD/src/seeder_p.cc 65 | 66 | LIBS += -ltorrent 67 | }else { 68 | message(Decentralized update feature is not enabled.) 69 | } 70 | 71 | BUILD_AS_PLUGIN { 72 | message(QAppImageUpdate will be built as an Qt Plugin) 73 | CONFIG -= staticlib 74 | CONFIG += plugin 75 | DEFINES += BUILD_AS_PLUGIN 76 | OTHER_FILES += $$PWD/QAppImageUpdate.json 77 | 78 | HEADERS += $$PWD/include/qappimageupdateinterface.hpp \ 79 | $$PWD/include/qappimageupdateinterfaceimpl.hpp 80 | 81 | SOURCES += $$PWD/src/qappimageupdateinterfaceimpl.cc 82 | } 83 | -------------------------------------------------------------------------------- /website/core/Footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | class Footer extends React.Component { 11 | render() { 12 | const currentYear = new Date().getFullYear(); 13 | return ( 14 | 80 | ); 81 | } 82 | } 83 | 84 | module.exports = Footer; 85 | -------------------------------------------------------------------------------- /src/torrentdownloader.cc: -------------------------------------------------------------------------------- 1 | #ifdef DECENTRALIZED_UPDATE_ENABLED 2 | #include "torrentdownloader.hpp" 3 | #include "torrentdownloader_p.hpp" 4 | #include "helpers_p.hpp" 5 | 6 | TorrentDownloader::TorrentDownloader(QNetworkAccessManager *manager, QObject *parent) 7 | : QObject(parent) { 8 | m_Private = QSharedPointer(new TorrentDownloaderPrivate(manager)); 9 | auto obj = m_Private.data(); 10 | 11 | connect(obj, &TorrentDownloaderPrivate::started, 12 | this, &TorrentDownloader::started, 13 | Qt::DirectConnection); 14 | 15 | connect(obj, &TorrentDownloaderPrivate::canceled, 16 | this, &TorrentDownloader::canceled, 17 | Qt::DirectConnection); 18 | 19 | connect(obj, &TorrentDownloaderPrivate::finished, 20 | this, &TorrentDownloader::finished, 21 | Qt::DirectConnection); 22 | 23 | connect(obj, &TorrentDownloaderPrivate::error, 24 | this, &TorrentDownloader::error, 25 | Qt::DirectConnection); 26 | 27 | connect(obj, &TorrentDownloaderPrivate::logger, 28 | this, &TorrentDownloader::logger, 29 | Qt::DirectConnection); 30 | 31 | connect(obj, &TorrentDownloaderPrivate::progress, 32 | this, &TorrentDownloader::progress, 33 | Qt::DirectConnection); 34 | 35 | connect(obj, &TorrentDownloaderPrivate::torrentStatus, 36 | this, &TorrentDownloader::torrentStatus, 37 | Qt::DirectConnection); 38 | } 39 | 40 | void TorrentDownloader::setTargetFileDone(qint64 n) { 41 | getMethod(m_Private.data(), "setTargetFileDone(qint64)") 42 | .invoke(m_Private.data(), 43 | Qt::QueuedConnection, 44 | Q_ARG(qint64,n)); 45 | 46 | } 47 | 48 | 49 | void TorrentDownloader::setTargetFileLength(qint64 n) { 50 | getMethod(m_Private.data(), "setTargetFileLength(qint64)") 51 | .invoke(m_Private.data(), 52 | Qt::QueuedConnection, 53 | Q_ARG(qint64,n)); 54 | 55 | } 56 | 57 | 58 | 59 | void TorrentDownloader::setTorrentFileUrl(const QUrl &url) { 60 | getMethod(m_Private.data(), "setTorrentFileUrl(const QUrl&)") 61 | .invoke(m_Private.data(), 62 | Qt::QueuedConnection, 63 | Q_ARG(QUrl,url)); 64 | 65 | } 66 | 67 | void TorrentDownloader::setTargetFileUrl(const QUrl &url) { 68 | getMethod(m_Private.data(), "setTargetFileUrl(const QUrl&)") 69 | .invoke(m_Private.data(), 70 | Qt::QueuedConnection, 71 | Q_ARG(QUrl,url)); 72 | 73 | } 74 | 75 | void TorrentDownloader::setTargetFile(QTemporaryFile *file) { 76 | getMethod(m_Private.data(), "setTargetFile(QTemporaryFile*)") 77 | .invoke(m_Private.data(), 78 | Qt::QueuedConnection, 79 | Q_ARG(QTemporaryFile*,file)); 80 | 81 | } 82 | 83 | void TorrentDownloader::start() { 84 | getMethod(m_Private.data(), "start(void)") 85 | .invoke(m_Private.data(), 86 | Qt::QueuedConnection); 87 | } 88 | 89 | void TorrentDownloader::cancel() { 90 | getMethod(m_Private.data(), "cancel(void)") 91 | .invoke(m_Private.data(), 92 | Qt::QueuedConnection); 93 | } 94 | #endif // DECENTRALIZED_UPDATE_ENABLED 95 | -------------------------------------------------------------------------------- /src/rangedownloader.cc: -------------------------------------------------------------------------------- 1 | #include "rangedownloader.hpp" 2 | #include "rangedownloader_p.hpp" 3 | #include "helpers_p.hpp" 4 | 5 | RangeDownloader::RangeDownloader(QNetworkAccessManager *manager, QObject *parent) 6 | : QObject(parent) { 7 | m_Private = QSharedPointer(new RangeDownloaderPrivate(manager)); 8 | auto obj = m_Private.data(); 9 | 10 | connect(obj, &RangeDownloaderPrivate::started, 11 | this, &RangeDownloader::started, 12 | Qt::DirectConnection); 13 | 14 | connect(obj, &RangeDownloaderPrivate::canceled, 15 | this, &RangeDownloader::canceled, 16 | Qt::DirectConnection); 17 | 18 | connect(obj, &RangeDownloaderPrivate::finished, 19 | this, &RangeDownloader::finished, 20 | Qt::DirectConnection); 21 | 22 | connect(obj, &RangeDownloaderPrivate::error, 23 | this, &RangeDownloader::error, 24 | Qt::DirectConnection); 25 | 26 | connect(obj, &RangeDownloaderPrivate::data, 27 | this, &RangeDownloader::data, 28 | Qt::DirectConnection); 29 | 30 | connect(obj, &RangeDownloaderPrivate::rangeData, 31 | this, &RangeDownloader::rangeData, 32 | Qt::DirectConnection); 33 | 34 | connect(obj, &RangeDownloaderPrivate::progress, 35 | this, &RangeDownloader::progress, 36 | Qt::DirectConnection); 37 | } 38 | 39 | 40 | void RangeDownloader::setBlockSize(qint32 blockSize) { 41 | getMethod(m_Private.data(), "setBlockSize(qint32)") 42 | .invoke(m_Private.data(), 43 | Qt::QueuedConnection, 44 | Q_ARG(qint32, blockSize)); 45 | 46 | } 47 | 48 | 49 | 50 | void RangeDownloader::setTargetFileUrl(const QUrl &url) { 51 | getMethod(m_Private.data(), "setTargetFileUrl(const QUrl&)") 52 | .invoke(m_Private.data(), 53 | Qt::QueuedConnection, 54 | Q_ARG(QUrl,url)); 55 | 56 | } 57 | 58 | void RangeDownloader::setTargetFileLength(qint32 n) { 59 | getMethod(m_Private.data(), "setTargetFileLength(qint32)") 60 | .invoke(m_Private.data(), 61 | Qt::QueuedConnection, 62 | Q_ARG(qint32,n)); 63 | } 64 | 65 | void RangeDownloader::setBytesWritten(qint64 n) { 66 | getMethod(m_Private.data(), "setBytesWritten(qint64)") 67 | .invoke(m_Private.data(), 68 | Qt::QueuedConnection, 69 | Q_ARG(qint64,n)); 70 | } 71 | 72 | 73 | void RangeDownloader::setFullDownload(bool choice) { 74 | getMethod(m_Private.data(), "setFullDownload(bool)") 75 | .invoke(m_Private.data(), 76 | Qt::QueuedConnection, 77 | Q_ARG(bool,choice)); 78 | } 79 | 80 | void RangeDownloader::appendRange(qint32 from, qint32 to) { 81 | getMethod(m_Private.data(), "appendRange(qint32,qint32)") 82 | .invoke(m_Private.data(), 83 | Qt::QueuedConnection, 84 | Q_ARG(qint32,from), Q_ARG(qint32,to)); 85 | } 86 | 87 | void RangeDownloader::start() { 88 | getMethod(m_Private.data(), "start()") 89 | .invoke(m_Private.data(), 90 | Qt::QueuedConnection); 91 | } 92 | 93 | void RangeDownloader::cancel() { 94 | getMethod(m_Private.data(), "cancel()") 95 | .invoke(m_Private.data(), 96 | Qt::QueuedConnection); 97 | } 98 | 99 | -------------------------------------------------------------------------------- /include/appimageupdateinformation_p.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 3-Clause License 3 | * 4 | * Copyright (c) 2018-2019, Antony jr 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * * Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * @filename : appimageupdateinformation_p.hpp 33 | * @description : This is where the extraction of embeded update information 34 | * from AppImages is described. 35 | */ 36 | #ifndef APPIMAGE_UPDATE_INFORMATION_PRIVATE_HPP_INCLUDED 37 | #define APPIMAGE_UPDATE_INFORMATION_PRIVATE_HPP_INCLUDED 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | class AppImageUpdateInformationPrivate : public QObject { 50 | Q_OBJECT 51 | public: 52 | explicit AppImageUpdateInformationPrivate(QObject *parent = nullptr); 53 | ~AppImageUpdateInformationPrivate(); 54 | public Q_SLOTS: 55 | void setAppImage(const QString&); 56 | void setAppImage(QFile *); 57 | void setShowLog(bool); 58 | void setLoggerName(const QString&); 59 | void getInfo(void); 60 | void clear(void); 61 | 62 | #ifndef LOGGING_DISABLED 63 | private Q_SLOTS: 64 | void handleLogMessage(QString, QString); 65 | #endif // LOGGING_DISABLED 66 | 67 | Q_SIGNALS: 68 | void operatingAppImagePath(QString); 69 | void info(QJsonObject); 70 | void progress(int); 71 | void error(short); 72 | void logger(QString, QString); 73 | 74 | private: 75 | bool b_Busy = false; 76 | QJsonObject m_Info; 77 | QString s_AppImageName, /* cache to avoid the overhead for QFileInfo. */ 78 | s_AppImagePath, 79 | #ifndef LOGGING_DISABLED 80 | s_LogBuffer, 81 | s_LoggerName, 82 | #endif // LOGGING_DISABLED 83 | s_AppImageSHA1; 84 | #ifndef LOGGING_DISABLED 85 | QScopedPointer p_Logger; 86 | #endif // LOGGING_DISABLED 87 | QFile *p_AppImage = nullptr; 88 | }; 89 | #endif // APPIMAGE_UPDATE_INFORMATION_PRIVATE_HPP_INCLUDED 90 | -------------------------------------------------------------------------------- /website/pages/en/versions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | const CWD = process.cwd(); 11 | 12 | const versions = require(`${CWD}/versions.json`); 13 | 14 | function Versions(props) { 15 | const {config: siteConfig} = props; 16 | const latestVersion = versions[0]; 17 | const repoUrl = `https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`; 18 | return ( 19 |
20 |
21 |
22 |
23 |

{siteConfig.title} Versions

24 |
25 |

Current version (Stable)

26 |

Latest version of QAppImageUpdate.

27 | 28 | 29 | 30 | 31 | 37 | 42 | 43 | 44 |
{latestVersion} 32 | 34 | Documentation 35 | 36 | 38 | 39 | Release Notes 40 | 41 |
45 |

Latest Version

46 | Here you can find the latest documentation and unreleased code. 47 | 48 | 49 | 50 | 51 | 57 | 60 | 61 | 62 |
master 52 | 54 | Documentation 55 | 56 | 58 | Source Code 59 |
63 |

Past Versions

64 |

65 | Here you can find documentation for previous versions of QAppImageUpdate. 66 |

67 | 68 | 69 | {versions.map( 70 | (version) => 71 | version !== latestVersion && ( 72 | 73 | 77 | 83 | 84 | ), 85 | )} 86 | 87 |
74 | {version === versions[versions.length - 1] ? '<=' : ''} 75 | {version} 76 | 78 | 80 | Documentation 81 | 82 |
88 |

89 | You can find past versions of this project on{' '} 90 | GitHub. 91 |

92 |
93 |
94 |
95 | ); 96 | } 97 | 98 | Versions.title = 'Versions'; 99 | 100 | module.exports = Versions; 101 | 102 | 103 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AppImageUpdaterBridgeErrorCodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AppImageUpdaterBridgeErrorCodes 3 | title: Handling Errors from AppImageUpdaterBridge 4 | sidebar_label: Error Codes 5 | original_id: AppImageUpdaterBridgeErrorCodes 6 | --- 7 | 8 | Using static function ```AppImageUpdaterBridge::errorCodeToString(short)``` you can get the error code name as 9 | a QString , The below table tabulates all error codes with respect to their error name. 10 | 11 | > Note: All are under the AppImageUpdaterBridge namespace so make sure to include it. 12 | 13 | 14 | | Error Code | Value | 15 | |----------------------------------|------ | 16 | | NoError | 0 | 17 | | NoAppimagePathGiven | 1 | 18 | | AppimageNotReadable | 2 | 19 | | NoReadPermission | 3 | 20 | | AppimageNotFound | 4 | 21 | | CannotOpenAppimage | 5 | 22 | | EmptyUpdateInformation | 6 | 23 | | InvalidAppimageType | 7 | 24 | | InvalidMagicBytes | 8 | 25 | | InvalidUpdateInformation | 9 | 26 | | NotEnoughMemory | 10 | 27 | | SectionHeaderNotFound | 11 | 28 | | UnsupportedElfFormat | 12 | 29 | | UnsupportedTransport | 13 | 30 | | IoReadError | 50 | 31 | | ErrorResponseCode | 51 | 32 | | GithubApiRateLimitReached | 52 | 33 | | NoMarkerFoundInControlFile | 53 | 34 | | InvalidZsyncHeadersNumber | 54 | 35 | | InvalidZsyncMakeVersion | 55 | 36 | | InvalidZsyncTargetFilename | 56 | 37 | | InvalidZsyncMtime | 57 | 38 | | InvalidZsyncBlocksize | 58 | 39 | | InvalidTargetFileLength | 59 | 40 | | InvalidHashLengthLine | 60 | 41 | | InvalidHashLengths | 61 | 42 | | InvalidTargetFileUrl | 62 | 43 | | InvalidTargetFileSha1 | 63 | 44 | | ConnectionRefusedError | 64 | 45 | | RemoteHostClosedError | 65 | 46 | | HostNotFoundError | 66 | 47 | | TimeoutError | 67 | 48 | | OperationCanceledError | 68 | 49 | | SslHandshakeFailedError | 69 | 50 | | TemporaryNetworkFailureError | 70 | 51 | | NetworkSessionFailedError | 71 | 52 | | BackgroundRequestNotAllowedError | 72 | 53 | | TooManyRedirectsError | 73 | 54 | | InsecureRedirectError | 74 | 55 | | ProxyConnectionRefusedError | 75 | 56 | | ProxyConnectionClosedError | 76 | 57 | | ProxyNotFoundError | 77 | 58 | | ProxyTimeoutError | 78 | 59 | | ProxyAuthenticationRequiredError | 79 | 60 | | ContentAccessDenied | 80 | 61 | | ContentOperationNotPermittedError| 81 | 62 | | ContentNotFoundError | 82 | 63 | | AuthenticationRequiredError | 83 | 64 | | ContentReSendError | 84 | 65 | | ContentConflictError | 85 | 66 | | ContentGoneError | 86 | 67 | | InternalServerError | 87 | 68 | | OperationNotImplementedError | 88 | 69 | | ServiceUnavailableError | 89 | 70 | | ProtocolUnknownError | 90 | 71 | | ProtocolInvalidOperationError | 91 | 72 | | UnknownNetworkError | 92 | 73 | | UnknownProxyError | 93 | 74 | | UnknownContentError | 94 | 75 | | ProtocolFailure | 95 | 76 | | UnknownServerError | 96 | 77 | | ZsyncControlFileNotFound | 97 | 78 | | HashTableNotAllocated | 100 | 79 | | InvalidTargetFileChecksumBlocks | 101 | 80 | | CannotOpenTargetFileChecksumBlocks| 102 | 81 | | CannotConstructHashTable | 103 | 82 | | QbufferIoReadError | 104 | 83 | | SourceFileNotFound | 105 | 84 | | NoPermissionToReadSourceFile | 106 | 85 | | CannotOpenSourceFile | 107 | 86 | | NoPermissionToReadWriteTargetFile| 108 | 87 | | CannotOpenTargetFile | 109 | 88 | | TargetFileSha1HashMismatch | 110 | 89 | -------------------------------------------------------------------------------- /.github/workflows/test-and-deploy.yml: -------------------------------------------------------------------------------- 1 | name: "Test and Deploy" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | Test-and-Deploy: 10 | runs-on: ubuntu-18.04 11 | defaults: 12 | run: 13 | working-directory: website 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: lukka/get-cmake@latest 17 | 18 | 19 | - name: Install PVS Studio 20 | run: | 21 | wget -q -O - https://files.viva64.com/etc/pubkey.txt | sudo apt-key add - 22 | sudo wget -O /etc/apt/sources.list.d/viva64.list https://files.viva64.com/etc/viva64.list 23 | sudo apt-get update -qq 24 | sudo apt-get -y install pvs-studio 25 | 26 | - name: Install Qt 27 | run: | 28 | sudo add-apt-repository ppa:beineri/opt-qt-5.11.0-bionic -y 29 | sudo apt-get update -qq 30 | sudo apt-get -y install build-essential libgl1-mesa-dev xvfb qt511base \ 31 | libboost-system-dev libboost-python-dev libboost-chrono-dev \ 32 | libboost-random-dev libssl-dev 33 | source /opt/qt*/bin/qt*-env.sh || true 34 | 35 | - name: Install Torrent Rasterbar 36 | run: | 37 | cd .. 38 | mkdir torrent-rasterbar 39 | cd torrent-rasterbar 40 | wget -q "https://github.com/arvidn/libtorrent/releases/download/libtorrent-1.2.8/libtorrent-rasterbar-1.2.8.tar.gz" 41 | tar -xvf libtorrent-rasterbar-1.2.8.tar.gz 42 | cd libtorrent-rasterbar-1.2.8 43 | mkdir build 44 | cd build 45 | cmake .. 46 | make -j$(nproc) 47 | sudo make install -j$(nproc) 48 | sudo ln -s /usr/local/lib/libtorrent-rasterbar.so.1.2.8 /usr/lib/libtorrent-rasterbar.so.10 49 | cd .. 50 | cd .. 51 | cd .. 52 | rm -rf torrent-rasterbar 53 | 54 | - name: Run Unit Tests 55 | run: | 56 | Xvfb :100 -ac & 57 | export DISPLAY=:100.0 58 | source /opt/qt*/bin/qt*-env.sh || true 59 | cd .. 60 | mkdir test-build 61 | cd test-build 62 | cmake -DBUILD_TESTS=ON .. 63 | make -j$(nproc) 64 | ./tests/QAppImageUpdateTests 65 | cd .. 66 | rm -rf test-build 67 | mkdir build 68 | cd build 69 | cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DDECENTRALIZED_UPDATE_ENABLED=ON -DBUILD_TESTS=ON .. 70 | make -j$(nproc) 71 | cd tests 72 | ./QAppImageUpdateTests 73 | cd .. 74 | cd .. 75 | 76 | - name: Setup Node 77 | uses: actions/setup-node@v2 78 | with: 79 | node-version: '14.x' 80 | 81 | - name: Get yarn cache 82 | id: yarn-cache 83 | run: echo "::set-output name=dir::$(yarn cache dir)" 84 | 85 | - name: Cache dependencies 86 | uses: actions/cache@v2 87 | with: 88 | path: ${{ steps.yarn-cache.outputs.dir }} 89 | key: ${{ runner.os }}-website-${{ hashFiles('**/yarn.lock') }} 90 | restore-keys: | 91 | ${{ runner.os }}-website- 92 | 93 | - run: yarn install --frozen-lockfile 94 | - run: yarn build 95 | 96 | - name: Run PVS Analysis 97 | env: 98 | PVS_LIC_NAME: ${{secrets.PVS_LICENSE_NAME}} 99 | PVS_LIC_KEY: ${{secrets.PVS_LICENSE_KEY}} 100 | run: | 101 | cd .. 102 | cd build 103 | pvs-studio-analyzer credentials "$PVS_LIC_NAME" "$PVS_LIC_KEY" -o pvs.lic 104 | pvs-studio-analyzer analyze -l pvs.lic \ 105 | -e "/opt/qt511/*" \ 106 | -e "*moc_*" \ 107 | -o project.log -j$(nproc) 108 | plog-converter -a GA:1,2 -t fullhtml \ 109 | -o ../website/build/QAppImageUpdate/PVSStudioAnalysis project.log 110 | cd .. 111 | rm -rf build 112 | cd website 113 | 114 | - name: Deploy 115 | uses: peaceiris/actions-gh-pages@v3 116 | with: 117 | github_token: ${{ secrets.GITHUB_TOKEN }} 118 | publish_dir: ./website/build/QAppImageUpdate 119 | -------------------------------------------------------------------------------- /include/SoftwareUpdateDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SoftwareUpdateDialog 4 | 5 | 6 | Qt::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 725 13 | 355 14 | 15 | 16 | 17 | Software Update 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Install Update 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 125 34 | 125 35 | 36 | 37 | 38 | 39 | 125 40 | 125 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | 49 | 50 | Qt::AlignCenter 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 10 59 | 50 60 | false 61 | 62 | 63 | 64 | 65 | 66 | 67 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 68 | 69 | 70 | true 71 | 72 | 73 | 74 | 75 | 76 | 77 | Remind Me Later 78 | 79 | 80 | 81 | 82 | 83 | 84 | Automatically download and install updates in the future 85 | 86 | 87 | 88 | 89 | 90 | 91 | Skip This Version 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 10 100 | 75 101 | true 102 | 103 | 104 | 105 | Release Notes: 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 12 114 | 75 115 | true 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/AppImageUpdaterDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AppImageUpdaterDialog 4 | 5 | 6 | Qt::ApplicationModal 7 | 8 | 9 | 10 | 0 11 | 0 12 | 432 13 | 136 14 | 15 | 16 | 17 | Updating 18 | 19 | 20 | 21 | 22 | 23 | 0 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | 36 | 37 | 38 | 39 | Checking for Update... 40 | 41 | 42 | Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 100 53 | 100 54 | 55 | 56 | 57 | 58 | 100 59 | 100 60 | 61 | 62 | 63 | 64 | 65 | 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 100 88 | 100 89 | 90 | 91 | 92 | 93 | 100 94 | 100 95 | 96 | 97 | 98 | 99 | 100 | 101 | true 102 | 103 | 104 | 105 | 106 | 107 | 108 | Cancel 109 | 110 | 111 | 112 | 113 | 114 | 115 | 0 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/softwareupdatedialog_p.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../include/softwareupdatedialog_p.hpp" 6 | 7 | static bool isSkipThisVersion(const QString &id, QScopedPointer &settings) { 8 | if(settings.isNull()) { 9 | return false; 10 | } 11 | QCryptographicHash hasher(QCryptographicHash::Md5); 12 | hasher.addData(id.toUtf8()); 13 | QString hash(hasher.result().toHex()); 14 | return settings->value(hash).toBool(); 15 | } 16 | 17 | SoftwareUpdateDialog::SoftwareUpdateDialog(QWidget *parent, QPixmap icon,int flags) 18 | : QDialog(parent, Qt::WindowStaysOnTopHint) { 19 | m_Icon = icon; 20 | m_Ui.setupUi(this); 21 | 22 | if((flags & NoRemindMeLaterButton) && (flags & NoSkipThisVersionButton)) { 23 | b_NoUseSettings = true; 24 | (m_Ui.autoUpdateCheckBox)->setVisible(false); 25 | } else { 26 | m_Settings.reset(new QSettings(QSettings::UserScope, 27 | QString::fromUtf8("updatedeployqt"), 28 | QApplication::applicationName())); 29 | } 30 | 31 | connect(&m_Timer, &QTimer::timeout, this, &SoftwareUpdateDialog::pInit); 32 | 33 | if(flags & NoRemindMeLaterButton) { 34 | (m_Ui.remindMeLater)->setVisible(false); 35 | } else { 36 | connect(m_Ui.remindMeLater, &QPushButton::clicked, this, &SoftwareUpdateDialog::handleRemindMeLater); 37 | } 38 | 39 | if(flags & NoSkipThisVersionButton) { 40 | (m_Ui.skipVersionBtn)->setVisible(false); 41 | } else { 42 | connect(m_Ui.skipVersionBtn, &QPushButton::clicked, this, &SoftwareUpdateDialog::handleSkipThisUpdate); 43 | } 44 | connect(m_Ui.installUpdateBtn, &QPushButton::clicked, this, &SoftwareUpdateDialog::handleInstallUpdate); 45 | return; 46 | } 47 | 48 | SoftwareUpdateDialog::~SoftwareUpdateDialog() { 49 | } 50 | 51 | void SoftwareUpdateDialog::init(const QString &AppName, const QString &OldVersion, 52 | const QString &NewVersion, const QString &ReleaseNotes) { 53 | 54 | m_Id.clear(); 55 | m_Id.append(AppName); 56 | m_Id.append(OldVersion); 57 | m_Id.append(NewVersion); 58 | m_Id.append(ReleaseNotes); 59 | 60 | if(!b_NoUseSettings) { 61 | /* Check if the user choose to skip this version update. */ 62 | if(isSkipThisVersion(m_Id, m_Settings)) { 63 | setResult(QDialog::Rejected); 64 | emit rejected(); 65 | return; 66 | } 67 | 68 | /* Check if we want to automatically download and install update. */ 69 | if(m_Settings->value("autoUpdateOnFuture").toBool()) { 70 | setResult(QDialog::Accepted); 71 | emit accepted(); 72 | return; 73 | } 74 | 75 | 76 | /* Set if the users want to update automatically in the future. */ 77 | m_Settings->setValue("autoUpdateOnFuture", 78 | ((m_Ui.autoUpdateCheckBox)->checkState() == Qt::Checked) ? true : false); 79 | 80 | } 81 | 82 | /* Set the title , description , and release notes. */ 83 | (m_Ui.titleLbl)->setText(m_TitleTemplate.arg(AppName)); 84 | (m_Ui.descLbl)->setText(m_VersionDescTemplate.arg(AppName, NewVersion, OldVersion)); 85 | (m_Ui.releaseNotesTxtBox)->setHtml(ReleaseNotes); 86 | 87 | setWindowIcon(m_Icon); 88 | (m_Ui.softwareIcon)->setPixmap(m_Icon); 89 | 90 | /* Center the dialog in the primary screen. */ 91 | move(QGuiApplication::primaryScreen()->geometry().center() - this->rect().center()); 92 | show(); 93 | m_Timer.stop(); 94 | } 95 | 96 | /* private handles */ 97 | 98 | void SoftwareUpdateDialog::pInit() { 99 | move(QGuiApplication::primaryScreen()->geometry().center() - this->rect().center()); 100 | show(); 101 | m_Timer.stop(); 102 | } 103 | 104 | void SoftwareUpdateDialog::handleRemindMeLater() { 105 | hide(); 106 | m_Timer.setInterval(3600 * 1000); /* 1 hour interval */ 107 | m_Timer.setSingleShot(true); 108 | m_Timer.start(); 109 | } 110 | 111 | void SoftwareUpdateDialog::handleInstallUpdate() { 112 | hide(); 113 | m_Timer.stop(); 114 | setResult(QDialog::Accepted); 115 | emit accepted(); 116 | } 117 | 118 | void SoftwareUpdateDialog::handleSkipThisUpdate() { 119 | hide(); 120 | m_Timer.stop(); 121 | 122 | QCryptographicHash hasher(QCryptographicHash::Md5); 123 | hasher.addData(m_Id.toUtf8()); 124 | QString hash(hasher.result().toHex()); 125 | m_Settings->setValue(hash, true); 126 | 127 | setResult(QDialog::Rejected); 128 | emit rejected(); 129 | } 130 | -------------------------------------------------------------------------------- /include/qappimageupdate_p.hpp: -------------------------------------------------------------------------------- 1 | #ifndef QAPPIMAGE_UPDATE_PRIVATE_INCLUDED 2 | #define QAPPIMAGE_UPDATE_PRIVATE_INCLUDED 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "qappimageupdatecodes.hpp" 14 | #include "appimageupdateinformation_p.hpp" 15 | #include "zsyncremotecontrolfileparser_p.hpp" 16 | #include "zsyncwriter_p.hpp" 17 | #ifdef DECENTRALIZED_UPDATE_ENABLED 18 | #include "seeder.hpp" 19 | #endif 20 | 21 | #ifndef NO_GUI 22 | #include 23 | // forward declare 24 | class SoftwareUpdateDialog; 25 | namespace Ui { 26 | class AppImageUpdaterDialog; 27 | } 28 | #endif // NO_GUI 29 | 30 | class QAppImageUpdatePrivate : public QObject { 31 | Q_OBJECT 32 | public: 33 | QAppImageUpdatePrivate(bool singleThreaded = true, QObject *parent = nullptr); 34 | QAppImageUpdatePrivate(const QString &AppImagePath, bool singleThreaded = true, QObject *parent = nullptr); 35 | QAppImageUpdatePrivate(QFile *AppImage, bool singleThreaded = true, QObject *parent = nullptr); 36 | ~QAppImageUpdatePrivate(); 37 | 38 | struct Action : public QAppImageUpdateCodes::Action { }; 39 | struct GuiFlag : public QAppImageUpdateCodes::GuiFlag { }; 40 | 41 | static QString errorCodeToString(short); 42 | static QString errorCodeToDescriptionString(short); 43 | static QString versionString(); 44 | public Q_SLOTS: 45 | void setApplicationName(const QString&); 46 | void setIcon(QByteArray); 47 | void setGuiFlag(int); 48 | void setAppImage(const QString&); 49 | void setAppImage(QFile*); 50 | void setShowLog(bool); 51 | void setOutputDirectory(const QString&); 52 | void setProxy(const QNetworkProxy&); 53 | void start(short action = Action::Update, 54 | int flags = GuiFlag::None, 55 | QByteArray icon = QByteArray()); 56 | void cancel(); 57 | void clear(); 58 | 59 | private Q_SLOTS: 60 | void setCurrentAppImagePath(QString); 61 | void handleGetEmbeddedInfoError(short); 62 | void redirectEmbeddedInformation(QJsonObject); 63 | void handleCheckForUpdateError(short); 64 | #ifdef DECENTRALIZED_UPDATE_ENABLED 65 | void handleSeedError(short); 66 | void handleSeedCancel(); 67 | #endif 68 | void redirectUpdateCheck(QJsonObject); 69 | void handleCheckForUpdateProgress(int); 70 | void handleGetEmbeddedInfoProgress(int); 71 | void handleUpdateProgress(int, qint64, qint64, double, QString); 72 | void handleUpdateStart(); 73 | void handleUpdateCancel(); 74 | void handleUpdateFinished(QJsonObject, QString); 75 | void handleUpdateError(short); 76 | #ifndef NO_GUI 77 | void showWidget(); 78 | void handleGUIConfirmationRejected(); 79 | void handleGUIConfirmationAccepted(); 80 | 81 | void doGUIUpdate(); 82 | void handleGUIUpdateCheck(QJsonObject); 83 | void handleGUIUpdateCheckError(short); 84 | void handleGUIUpdateProgress(int, qint64, qint64, double, QString); 85 | void handleGUIUpdateCheckProgress(int); 86 | void handleGUIUpdateStart(); 87 | void handleGUIUpdateCancel(); 88 | void handleGUIUpdateFinished(QJsonObject, QString); 89 | void handleGUIUpdateError(short); 90 | #endif // NOT NO_GUI 91 | 92 | Q_SIGNALS: 93 | void torrentClientStarted(); 94 | void torrentStatus(int,int); 95 | void started(short); 96 | void canceled(short); 97 | void finished(QJsonObject info, short); 98 | void progress(int, qint64, qint64, double, QString, short); 99 | void logger(QString, QString); 100 | void error(short, short); 101 | void quit(); 102 | private: 103 | QByteArray m_Icon; 104 | int n_GuiFlag = GuiFlag::None; 105 | short n_CurrentAction = Action::None; 106 | bool b_Started = false, 107 | b_Finished = false, 108 | b_Canceled = false, 109 | b_Running = false, 110 | b_CancelRequested = false, 111 | b_GuiClassesConstructed = false; 112 | QString m_CurrentAppImagePath; 113 | QString m_ApplicationName; 114 | QScopedPointer m_UpdateInformation; 115 | QScopedPointer m_ControlFileParser; 116 | QScopedPointer m_DeltaWriter; 117 | #ifdef DECENTRALIZED_UPDATE_ENABLED 118 | QScopedPointer m_Seeder; 119 | #endif 120 | QScopedPointer m_SharedThread; 121 | QScopedPointer m_SharedNetworkAccessManager; 122 | #ifndef NO_GUI 123 | QScopedPointer m_UpdaterDialog; 124 | QSharedPointer m_ConfirmationDialog; 125 | QSharedPointer m_Ui; 126 | #endif // NOT NO_GUI 127 | }; 128 | 129 | #endif // QAPPIMAGE_UPDATE_PRIVATE_INCLUDED 130 | -------------------------------------------------------------------------------- /src/qappimageupdate.cc: -------------------------------------------------------------------------------- 1 | #ifdef BUILD_AS_PLUGIN 2 | #include "qappimageupdateinterface.hpp" 3 | #endif 4 | #include "qappimageupdate.hpp" 5 | #include "qappimageupdate_p.hpp" 6 | #include "helpers_p.hpp" 7 | 8 | QAppImageUpdate::QAppImageUpdate(bool singleThreaded, QObject *parent) 9 | : QObject(parent) { 10 | m_Private = QSharedPointer( 11 | new QAppImageUpdatePrivate(singleThreaded = singleThreaded)); 12 | auto s = m_Private.data(); 13 | 14 | connect(s, &QAppImageUpdatePrivate::torrentClientStarted, 15 | this, &QAppImageUpdate::torrentClientStarted, Qt::DirectConnection); 16 | connect(s, &QAppImageUpdatePrivate::torrentStatus, 17 | this, &QAppImageUpdate::torrentStatus, Qt::DirectConnection); 18 | connect(s, &QAppImageUpdatePrivate::started, 19 | this, &QAppImageUpdate::started, Qt::DirectConnection); 20 | connect(s, &QAppImageUpdatePrivate::canceled, 21 | this, &QAppImageUpdate::canceled, Qt::DirectConnection); 22 | connect(s, &QAppImageUpdatePrivate::finished, 23 | this, &QAppImageUpdate::finished, Qt::DirectConnection); 24 | connect(s, &QAppImageUpdatePrivate::progress, 25 | this, &QAppImageUpdate::progress, Qt::DirectConnection); 26 | connect(s, &QAppImageUpdatePrivate::logger, 27 | this, &QAppImageUpdate::logger, Qt::DirectConnection); 28 | connect(s, &QAppImageUpdatePrivate::error, 29 | this, &QAppImageUpdate::error, Qt::DirectConnection); 30 | connect(s, &QAppImageUpdatePrivate::quit, 31 | this, &QAppImageUpdate::quit, Qt::DirectConnection); 32 | } 33 | 34 | QAppImageUpdate::QAppImageUpdate(const QString &AppImagePath, bool singleThreaded, QObject *parent) 35 | : QAppImageUpdate(singleThreaded, parent) { 36 | setAppImage(AppImagePath); 37 | } 38 | 39 | QAppImageUpdate::QAppImageUpdate(QFile *AppImage, bool singleThreaded, QObject *parent) 40 | : QAppImageUpdate(singleThreaded, parent) { 41 | setAppImage(AppImage); 42 | } 43 | 44 | QAppImageUpdate::~QAppImageUpdate() { } 45 | 46 | void QAppImageUpdate::setApplicationName(const QString &applicationName) { 47 | getMethod(m_Private.data(), "setApplicationName(const QString&)") 48 | .invoke(m_Private.data(), 49 | Qt::QueuedConnection, 50 | Q_ARG(QString, applicationName)); 51 | } 52 | 53 | void QAppImageUpdate::setIcon(QByteArray icon) { 54 | getMethod(m_Private.data(), "setIcon(QByteArray)") 55 | .invoke(m_Private.data(), 56 | Qt::QueuedConnection, 57 | Q_ARG(QByteArray,icon)); 58 | } 59 | 60 | 61 | void QAppImageUpdate::setGuiFlag(int flags) { 62 | getMethod(m_Private.data(), "setGuiFlag(int)") 63 | .invoke(m_Private.data(), 64 | Qt::QueuedConnection, 65 | Q_ARG(int,flags)); 66 | } 67 | 68 | 69 | void QAppImageUpdate::setAppImage(const QString &AppImagePath) { 70 | getMethod(m_Private.data(), "setAppImage(const QString&)") 71 | .invoke(m_Private.data(), 72 | Qt::QueuedConnection, 73 | Q_ARG(QString,AppImagePath)); 74 | } 75 | void QAppImageUpdate::setAppImage(QFile *AppImage) { 76 | getMethod(m_Private.data(), "setAppImage(QFile*)") 77 | .invoke(m_Private.data(), 78 | Qt::QueuedConnection, 79 | Q_ARG(QFile*,AppImage)); 80 | } 81 | void QAppImageUpdate::setShowLog(bool boolean) { 82 | getMethod(m_Private.data(), "setShowLog(bool)") 83 | .invoke(m_Private.data(), 84 | Qt::QueuedConnection, 85 | Q_ARG(bool,boolean)); 86 | } 87 | 88 | void QAppImageUpdate::setOutputDirectory(const QString &OutputDirectory) { 89 | getMethod(m_Private.data(), "setOutputDirectory(const QString&)") 90 | .invoke(m_Private.data(), 91 | Qt::QueuedConnection, 92 | Q_ARG(QString,OutputDirectory)); 93 | } 94 | 95 | void QAppImageUpdate::setProxy(const QNetworkProxy &Proxy) { 96 | getMethod(m_Private.data(), "setProxy(const QNetworkProxy&)") 97 | .invoke(m_Private.data(), 98 | Qt::QueuedConnection, 99 | Q_ARG(QNetworkProxy, Proxy)); 100 | } 101 | 102 | void QAppImageUpdate::start(short action, int flags, QByteArray icon) { 103 | getMethod(m_Private.data(), "start(short, int, QByteArray)") 104 | .invoke(m_Private.data(), 105 | Qt::QueuedConnection, 106 | Q_ARG(short, action), 107 | Q_ARG(int, flags), 108 | Q_ARG(QByteArray, icon)); 109 | 110 | } 111 | 112 | void QAppImageUpdate::cancel() { 113 | getMethod(m_Private.data(), "cancel()") 114 | .invoke(m_Private.data(), 115 | Qt::QueuedConnection); 116 | } 117 | 118 | void QAppImageUpdate::clear() { 119 | getMethod(m_Private.data(), "clear()") 120 | .invoke(m_Private.data(), 121 | Qt::QueuedConnection); 122 | } 123 | 124 | 125 | //// Static Methods 126 | QString QAppImageUpdate::errorCodeToString(short errorCode) { 127 | return QAppImageUpdatePrivate::errorCodeToString(errorCode); 128 | } 129 | 130 | QString QAppImageUpdate::errorCodeToDescriptionString(short errorCode) { 131 | return QAppImageUpdatePrivate::errorCodeToDescriptionString(errorCode); 132 | } 133 | 134 | QString QAppImageUpdate::versionString() { 135 | return QAppImageUpdatePrivate::versionString(); 136 | } 137 | -------------------------------------------------------------------------------- /include/zsyncremotecontrolfileparser_p.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 3-Clause License 3 | * 4 | * Copyright (c) 2018-2019, Antony jr 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * * Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * @filename : zsyncremotecontrolfileparser_p.hpp 33 | * @description : This is where the ZsyncRemoteControlFileParserPrivate in described. 34 | * This class is responsible to parse the remote zsync control file from the given 35 | * embeded appimage information. 36 | */ 37 | #ifndef ZSYNC_CONTROL_FILE_PARSER_PRIVATE_HPP_INCLUDED 38 | #define ZSYNC_CONTROL_FILE_PARSER_PRIVATE_HPP_INCLUDED 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #include "qappimageupdateenums.hpp" 58 | #include "zsyncinternalstructures_p.hpp" 59 | 60 | class ZsyncRemoteControlFileParserPrivate : public QObject { 61 | Q_OBJECT 62 | public: 63 | explicit ZsyncRemoteControlFileParserPrivate(QNetworkAccessManager*); 64 | ~ZsyncRemoteControlFileParserPrivate(); 65 | public Q_SLOTS: 66 | void clear(void); 67 | void setControlFileUrl(const QUrl&); 68 | void setControlFileUrl(QJsonObject); 69 | void setLoggerName(const QString&); 70 | void setShowLog(bool); 71 | void setUseBittorrent(bool); 72 | void getControlFile(void); 73 | void getUpdateCheckInformation(void); 74 | void getZsyncInformation(void); 75 | 76 | private Q_SLOTS: 77 | void checkHeadTargetFileUrl(qint64, qint64); 78 | void handleBintrayRedirection(const QUrl&); 79 | void handleGithubMarkdownParsed(void); 80 | void handleGithubAPIResponse(void); 81 | void handleDownloadProgress(qint64, qint64); 82 | void handleControlFile(void); 83 | void handleNetworkError(QNetworkReply::NetworkError); 84 | void handleErrorSignal(short); 85 | #ifndef LOGGING_DISABLED 86 | void handleLogMessage(QString, QString); 87 | #endif // LOGGING_DISABLED 88 | Q_SIGNALS: 89 | void zsyncInformation(qint32,qint32,qint32, 90 | qint32,qint32,qint32, 91 | QString,QString,QString, 92 | QUrl,QBuffer*,bool,QUrl); 93 | void updateCheckInformation(QJsonObject); 94 | void receiveControlFile(void); 95 | void progress(int); 96 | void error(short); 97 | void logger(QString, QString); 98 | private: 99 | bool b_AcceptRange = false, 100 | b_Busy = false, 101 | b_WithBT = false; 102 | QJsonObject j_UpdateInformation; 103 | QString s_ZsyncMakeVersion, 104 | s_ZsyncFileName, /* only used for github transport. */ 105 | s_TargetFileName, 106 | s_AppImagePath, 107 | s_ReleaseNotes, 108 | s_TargetFileSHA1 109 | #ifndef LOGGING_DISABLED 110 | ,s_LoggerName, 111 | s_LogBuffer; 112 | #else 113 | ; 114 | #endif // LOGGING_DISABLED 115 | QDateTime m_MTime; 116 | qint32 n_TargetFileBlockSize = 0, 117 | n_TargetFileLength = 0, 118 | n_TargetFileBlocks = 0; 119 | qint32 n_WeakCheckSumBytes = 0, 120 | n_StrongCheckSumBytes = 0, 121 | n_ConsecutiveMatchNeeded = 0; 122 | qint64 n_CheckSumBlocksOffset = 0; 123 | QUrl u_TargetFileUrl, 124 | u_ControlFileUrl, 125 | u_TorrentFile; 126 | 127 | #ifndef LOGGING_DISABLED 128 | QScopedPointer p_Logger; 129 | #endif // LOGGING_DISABLED 130 | QScopedPointer p_ControlFile; 131 | QNetworkAccessManager *p_NManager = nullptr; 132 | }; 133 | 134 | #endif //ZSYNC_CONTROL_FILE_PARSER_PRIVATE_HPP_INCLUDED 135 | -------------------------------------------------------------------------------- /docs/ErrorCodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ErrorCodes 3 | title: QAppImageUpdate Error Codes 4 | sidebar_label: Error Codes 5 | --- 6 | 7 | Using static function ```QAppImageUpdate::errorCodeToString(short)``` you can get the error code name as 8 | a QString, The below table tabulates all error codes with respect to their error name. 9 | 10 | 11 | | Error Code | Value | 12 | |----------------------------------------------------------|------ | 13 | | QAppImageUpdate::Error::NoError | 0 | 14 | | QAppImageUpdate::Error::NoAppimagePathGiven | 1 | 15 | | QAppImageUpdate::Error::AppimageNotReadable | 2 | 16 | | QAppImageUpdate::Error::NoReadPermission | 3 | 17 | | QAppImageUpdate::Error::AppimageNotFound | 4 | 18 | | QAppImageUpdate::Error::CannotOpenAppimage | 5 | 19 | | QAppImageUpdate::Error::EmptyUpdateInformation | 6 | 20 | | QAppImageUpdate::Error::InvalidAppimageType | 7 | 21 | | QAppImageUpdate::Error::InvalidMagicBytes | 8 | 22 | | QAppImageUpdate::Error::InvalidUpdateInformation | 9 | 23 | | QAppImageUpdate::Error::NotEnoughMemory | 10 | 24 | | QAppImageUpdate::Error::SectionHeaderNotFound | 11 | 25 | | QAppImageUpdate::Error::UnsupportedElfFormat | 12 | 26 | | QAppImageUpdate::Error::UnsupportedTransport | 13 | 27 | | QAppImageUpdate::Error::IoReadError | 50 | 28 | | QAppImageUpdate::Error::ErrorResponseCode | 51 | 29 | | QAppImageUpdate::Error::GithubApiRateLimitReached | 52 | 30 | | QAppImageUpdate::Error::NoMarkerFoundInControlFile | 53 | 31 | | QAppImageUpdate::Error::InvalidZsyncHeadersNumber | 54 | 32 | | QAppImageUpdate::Error::InvalidZsyncMakeVersion | 55 | 33 | | QAppImageUpdate::Error::InvalidZsyncTargetFilename | 56 | 34 | | QAppImageUpdate::Error::InvalidZsyncMtime | 57 | 35 | | QAppImageUpdate::Error::InvalidZsyncBlocksize | 58 | 36 | | QAppImageUpdate::Error::InvalidTargetFileLength | 59 | 37 | | QAppImageUpdate::Error::InvalidHashLengthLine | 60 | 38 | | QAppImageUpdate::Error::InvalidHashLengths | 61 | 39 | | QAppImageUpdate::Error::InvalidTargetFileUrl | 62 | 40 | | QAppImageUpdate::Error::InvalidTargetFileSha1 | 63 | 41 | | QAppImageUpdate::Error::ConnectionRefusedError | 64 | 42 | | QAppImageUpdate::Error::RemoteHostClosedError | 65 | 43 | | QAppImageUpdate::Error::HostNotFoundError | 66 | 44 | | QAppImageUpdate::Error::TimeoutError | 67 | 45 | | QAppImageUpdate::Error::OperationCanceledError | 68 | 46 | | QAppImageUpdate::Error::SslHandshakeFailedError | 69 | 47 | | QAppImageUpdate::Error::TemporaryNetworkFailureError | 70 | 48 | | QAppImageUpdate::Error::NetworkSessionFailedError | 71 | 49 | | QAppImageUpdate::Error::BackgroundRequestNotAllowedError | 72 | 50 | | QAppImageUpdate::Error::TooManyRedirectsError | 73 | 51 | | QAppImageUpdate::Error::InsecureRedirectError | 74 | 52 | | QAppImageUpdate::Error::ProxyConnectionRefusedError | 75 | 53 | | QAppImageUpdate::Error::ProxyConnectionClosedError | 76 | 54 | | QAppImageUpdate::Error::ProxyNotFoundError | 77 | 55 | | QAppImageUpdate::Error::ProxyTimeoutError | 78 | 56 | | QAppImageUpdate::Error::ProxyAuthenticationRequiredError | 79 | 57 | | QAppImageUpdate::Error::ContentAccessDenied | 80 | 58 | | QAppImageUpdate::Error::ContentOperationNotPermittedError| 81 | 59 | | QAppImageUpdate::Error::ContentNotFoundError | 82 | 60 | | QAppImageUpdate::Error::AuthenticationRequiredError | 83 | 61 | | QAppImageUpdate::Error::ContentReSendError | 84 | 62 | | QAppImageUpdate::Error::ContentConflictError | 85 | 63 | | QAppImageUpdate::Error::ContentGoneError | 86 | 64 | | QAppImageUpdate::Error::InternalServerError | 87 | 65 | | QAppImageUpdate::Error::OperationNotImplementedError | 88 | 66 | | QAppImageUpdate::Error::ServiceUnavailableError | 89 | 67 | | QAppImageUpdate::Error::ProtocolUnknownError | 90 | 68 | | QAppImageUpdate::Error::ProtocolInvalidOperationError | 91 | 69 | | QAppImageUpdate::Error::UnknownNetworkError | 92 | 70 | | QAppImageUpdate::Error::UnknownProxyError | 93 | 71 | | QAppImageUpdate::Error::UnknownContentError | 94 | 72 | | QAppImageUpdate::Error::ProtocolFailure | 95 | 73 | | QAppImageUpdate::Error::UnknownServerError | 96 | 74 | | QAppImageUpdate::Error::ZsyncControlFileNotFound | 97 | 75 | | QAppImageUpdate::Error::HashTableNotAllocated | 100 | 76 | | QAppImageUpdate::Error::InvalidTargetFileChecksumBlocks | 101 | 77 | | QAppImageUpdate::Error::CannotOpenTargetFileChecksumBlocks| 102 | 78 | | QAppImageUpdate::Error::CannotConstructHashTable | 103 | 79 | | QAppImageUpdate::Error::QbufferIoReadError | 104 | 80 | | QAppImageUpdate::Error::SourceFileNotFound | 105 | 81 | | QAppImageUpdate::Error::NoPermissionToReadSourceFile | 106 | 82 | | QAppImageUpdate::Error::CannotOpenSourceFile | 107 | 83 | | QAppImageUpdate::Error::NoPermissionToReadWriteTargetFile| 108 | 84 | | QAppImageUpdate::Error::CannotOpenTargetFile | 109 | 85 | | QAppImageUpdate::Error::TargetFileSha1HashMismatch | 110 | 86 | | QAppImageUpdate::Error::UnsupportedActionForBuild | 200 | 87 | | QAppImageUpdate::Error::InvalidAction | 201 | 88 | -------------------------------------------------------------------------------- /include/qappimageupdateenums.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BSD 3-Clause License 3 | * 4 | * Copyright (c) 2018-2019, Antony jr 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, this 11 | * list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright notice, 14 | * this list of conditions and the following disclaimer in the documentation 15 | * and/or other materials provided with the distribution. 16 | * 17 | * * Neither the name of the copyright holder nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * @filename : qappimageupdateenums.hpp 33 | * @description : Error codes are described here. 34 | */ 35 | #ifndef QAPPIMAGE_UPDATE_ENUMS_HPP_INCLUDED 36 | #define QAPPIMAGE_UPDATE_ENUMS_HPP_INCLUDED 37 | 38 | struct QAppImageUpdateEnums { 39 | /* Error codes for all process. */ 40 | struct Error { 41 | enum : short { 42 | /* Common error. */ 43 | NoError = 0, 44 | 45 | /* AppImage Update Information parser errors. */ 46 | NoAppimagePathGiven = 1, 47 | AppimageNotReadable, 48 | NoReadPermission, 49 | AppimageNotFound, 50 | CannotOpenAppimage, 51 | EmptyUpdateInformation, 52 | InvalidAppimageType, 53 | InvalidMagicBytes, 54 | InvalidUpdateInformation, 55 | NotEnoughMemory, 56 | SectionHeaderNotFound, 57 | UnsupportedElfFormat, 58 | UnsupportedTransport, 59 | 60 | /* Zsync Control File parser errors. */ 61 | IoReadError = 50, 62 | ErrorResponseCode, 63 | GithubApiRateLimitReached, 64 | NoMarkerFoundInControlFile, 65 | InvalidZsyncHeadersNumber, 66 | InvalidZsyncMakeVersion, 67 | InvalidZsyncTargetFilename, 68 | InvalidZsyncMtime, 69 | InvalidZsyncBlocksize, 70 | InvalidTargetFileLength, 71 | InvalidHashLengthLine, 72 | InvalidHashLengths, 73 | InvalidTargetFileUrl, 74 | InvalidTargetFileSha1, 75 | ConnectionRefusedError, 76 | RemoteHostClosedError, 77 | HostNotFoundError, 78 | TimeoutError, 79 | OperationCanceledError, 80 | SslHandshakeFailedError, 81 | TemporaryNetworkFailureError, 82 | NetworkSessionFailedError, 83 | BackgroundRequestNotAllowedError, 84 | TooManyRedirectsError, 85 | InsecureRedirectError, 86 | ProxyConnectionRefusedError, 87 | ProxyConnectionClosedError, 88 | ProxyNotFoundError, 89 | ProxyTimeoutError, 90 | ProxyAuthenticationRequiredError, 91 | ContentAccessDenied, 92 | ContentOperationNotPermittedError, 93 | ContentNotFoundError, 94 | AuthenticationRequiredError, 95 | ContentReSendError, 96 | ContentConflictError, 97 | ContentGoneError, 98 | InternalServerError, 99 | OperationNotImplementedError, 100 | ServiceUnavailableError, 101 | ProtocolUnknownError, 102 | ProtocolInvalidOperationError, 103 | UnknownNetworkError, 104 | UnknownProxyError, 105 | UnknownContentError, 106 | ProtocolFailure, 107 | UnknownServerError, 108 | ZsyncControlFileNotFound, 109 | 110 | /* Zsync writer errors. */ 111 | HashTableNotAllocated = 100, 112 | InvalidTargetFileChecksumBlocks, 113 | CannotOpenTargetFileChecksumBlocks, 114 | CannotConstructHashTable, 115 | QbufferIoReadError, 116 | SourceFileNotFound, 117 | NoPermissionToReadSourceFile, 118 | CannotOpenSourceFile, 119 | NoPermissionToReadWriteTargetFile, 120 | CannotOpenTargetFile, 121 | TargetFileSha1HashMismatch, 122 | 123 | /* Seeder errors. */ 124 | TorrentNotSupported = 200, 125 | TorrentSeedFailed, 126 | OutdatedAppImageForSeed, 127 | IncompleteAppImageForSeed, 128 | 129 | /* Library errors. */ 130 | UnsupportedActionForBuild = 300, 131 | InvalidAction 132 | }; 133 | }; 134 | }; 135 | #endif // QAPPIMAGE_UPDATE_ENUMS_HPP_INCLUDED 136 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/ErrorCodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-ErrorCodes 3 | title: QAppImageUpdate Error Codes 4 | sidebar_label: Error Codes 5 | original_id: ErrorCodes 6 | --- 7 | 8 | Using static function ```QAppImageUpdate::errorCodeToString(short)``` you can get the error code name as 9 | a QString, The below table tabulates all error codes with respect to their error name. 10 | 11 | 12 | | Error Code | Value | 13 | |----------------------------------------------------------|------ | 14 | | QAppImageUpdate::Error::NoError | 0 | 15 | | QAppImageUpdate::Error::NoAppimagePathGiven | 1 | 16 | | QAppImageUpdate::Error::AppimageNotReadable | 2 | 17 | | QAppImageUpdate::Error::NoReadPermission | 3 | 18 | | QAppImageUpdate::Error::AppimageNotFound | 4 | 19 | | QAppImageUpdate::Error::CannotOpenAppimage | 5 | 20 | | QAppImageUpdate::Error::EmptyUpdateInformation | 6 | 21 | | QAppImageUpdate::Error::InvalidAppimageType | 7 | 22 | | QAppImageUpdate::Error::InvalidMagicBytes | 8 | 23 | | QAppImageUpdate::Error::InvalidUpdateInformation | 9 | 24 | | QAppImageUpdate::Error::NotEnoughMemory | 10 | 25 | | QAppImageUpdate::Error::SectionHeaderNotFound | 11 | 26 | | QAppImageUpdate::Error::UnsupportedElfFormat | 12 | 27 | | QAppImageUpdate::Error::UnsupportedTransport | 13 | 28 | | QAppImageUpdate::Error::IoReadError | 50 | 29 | | QAppImageUpdate::Error::ErrorResponseCode | 51 | 30 | | QAppImageUpdate::Error::GithubApiRateLimitReached | 52 | 31 | | QAppImageUpdate::Error::NoMarkerFoundInControlFile | 53 | 32 | | QAppImageUpdate::Error::InvalidZsyncHeadersNumber | 54 | 33 | | QAppImageUpdate::Error::InvalidZsyncMakeVersion | 55 | 34 | | QAppImageUpdate::Error::InvalidZsyncTargetFilename | 56 | 35 | | QAppImageUpdate::Error::InvalidZsyncMtime | 57 | 36 | | QAppImageUpdate::Error::InvalidZsyncBlocksize | 58 | 37 | | QAppImageUpdate::Error::InvalidTargetFileLength | 59 | 38 | | QAppImageUpdate::Error::InvalidHashLengthLine | 60 | 39 | | QAppImageUpdate::Error::InvalidHashLengths | 61 | 40 | | QAppImageUpdate::Error::InvalidTargetFileUrl | 62 | 41 | | QAppImageUpdate::Error::InvalidTargetFileSha1 | 63 | 42 | | QAppImageUpdate::Error::ConnectionRefusedError | 64 | 43 | | QAppImageUpdate::Error::RemoteHostClosedError | 65 | 44 | | QAppImageUpdate::Error::HostNotFoundError | 66 | 45 | | QAppImageUpdate::Error::TimeoutError | 67 | 46 | | QAppImageUpdate::Error::OperationCanceledError | 68 | 47 | | QAppImageUpdate::Error::SslHandshakeFailedError | 69 | 48 | | QAppImageUpdate::Error::TemporaryNetworkFailureError | 70 | 49 | | QAppImageUpdate::Error::NetworkSessionFailedError | 71 | 50 | | QAppImageUpdate::Error::BackgroundRequestNotAllowedError | 72 | 51 | | QAppImageUpdate::Error::TooManyRedirectsError | 73 | 52 | | QAppImageUpdate::Error::InsecureRedirectError | 74 | 53 | | QAppImageUpdate::Error::ProxyConnectionRefusedError | 75 | 54 | | QAppImageUpdate::Error::ProxyConnectionClosedError | 76 | 55 | | QAppImageUpdate::Error::ProxyNotFoundError | 77 | 56 | | QAppImageUpdate::Error::ProxyTimeoutError | 78 | 57 | | QAppImageUpdate::Error::ProxyAuthenticationRequiredError | 79 | 58 | | QAppImageUpdate::Error::ContentAccessDenied | 80 | 59 | | QAppImageUpdate::Error::ContentOperationNotPermittedError| 81 | 60 | | QAppImageUpdate::Error::ContentNotFoundError | 82 | 61 | | QAppImageUpdate::Error::AuthenticationRequiredError | 83 | 62 | | QAppImageUpdate::Error::ContentReSendError | 84 | 63 | | QAppImageUpdate::Error::ContentConflictError | 85 | 64 | | QAppImageUpdate::Error::ContentGoneError | 86 | 65 | | QAppImageUpdate::Error::InternalServerError | 87 | 66 | | QAppImageUpdate::Error::OperationNotImplementedError | 88 | 67 | | QAppImageUpdate::Error::ServiceUnavailableError | 89 | 68 | | QAppImageUpdate::Error::ProtocolUnknownError | 90 | 69 | | QAppImageUpdate::Error::ProtocolInvalidOperationError | 91 | 70 | | QAppImageUpdate::Error::UnknownNetworkError | 92 | 71 | | QAppImageUpdate::Error::UnknownProxyError | 93 | 72 | | QAppImageUpdate::Error::UnknownContentError | 94 | 73 | | QAppImageUpdate::Error::ProtocolFailure | 95 | 74 | | QAppImageUpdate::Error::UnknownServerError | 96 | 75 | | QAppImageUpdate::Error::ZsyncControlFileNotFound | 97 | 76 | | QAppImageUpdate::Error::HashTableNotAllocated | 100 | 77 | | QAppImageUpdate::Error::InvalidTargetFileChecksumBlocks | 101 | 78 | | QAppImageUpdate::Error::CannotOpenTargetFileChecksumBlocks| 102 | 79 | | QAppImageUpdate::Error::CannotConstructHashTable | 103 | 80 | | QAppImageUpdate::Error::QbufferIoReadError | 104 | 81 | | QAppImageUpdate::Error::SourceFileNotFound | 105 | 82 | | QAppImageUpdate::Error::NoPermissionToReadSourceFile | 106 | 83 | | QAppImageUpdate::Error::CannotOpenSourceFile | 107 | 84 | | QAppImageUpdate::Error::NoPermissionToReadWriteTargetFile| 108 | 85 | | QAppImageUpdate::Error::CannotOpenTargetFile | 109 | 86 | | QAppImageUpdate::Error::TargetFileSha1HashMismatch | 110 | 87 | | QAppImageUpdate::Error::UnsupportedActionForBuild | 200 | 88 | | QAppImageUpdate::Error::InvalidAction | 201 | 89 | -------------------------------------------------------------------------------- /website/pages/en/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2017-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const React = require('react'); 9 | 10 | const CompLibrary = require('../../core/CompLibrary.js'); 11 | const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */ 12 | const Container = CompLibrary.Container; 13 | const GridBlock = CompLibrary.GridBlock; 14 | 15 | const siteConfig = require(process.cwd() + '/siteConfig.js'); 16 | 17 | class Button extends React.Component { 18 | render() { 19 | return ( 20 | 25 | ); 26 | } 27 | } 28 | 29 | Button.defaultProps = { 30 | target: '_self', 31 | }; 32 | 33 | class HomeSplash extends React.Component { 34 | render() { 35 | return ( 36 |
37 |
38 |
39 |
40 | 41 |
42 |
43 |

44 | {siteConfig.title} 45 | {siteConfig.tagline} 46 |

47 |
48 |
49 |
50 | 58 | 66 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | ); 77 | } 78 | } 79 | 80 | class Index extends React.Component { 81 | render() { 82 | let language = this.props.language || 'en'; 83 | const showcase = siteConfig.users 84 | .filter(user => { 85 | return user.pinned; 86 | }) 87 | .map(user => { 88 | return ( 89 | 90 | 91 | 92 | ); 93 | }); 94 | 95 | return ( 96 |
97 | 98 |
99 | 100 | Codacy with a A Project Certification' + 120 | ' and thus integrating this library will not affect your source , So this project is also'+ 121 | ' best suited for those who care about code taste.', 122 | image: siteConfig.baseUrl + 'img/clean_code.png', 123 | imageAlign: 'top', 124 | title: 'Clean C++ API.', 125 | }, 126 | 127 | ]} 128 | layout="threeColumn" 129 | /> 130 | 131 | 132 |
133 |

{"Who's Using This?"}

134 |

This project is used by all these people

135 |
{showcase}
136 | 145 |
146 |
147 |
148 | ); 149 | } 150 | } 151 | 152 | module.exports = Index; 153 | -------------------------------------------------------------------------------- /website/versioned_docs/version-1.1.9/AddingAppImageUpdaterBridge.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-1.1.9-AddingAppImageUpdaterBridge 3 | title: Add AppImage Updater Bridge to your Project 4 | sidebar_label: Adding to your Project. 5 | original_id: AddingAppImageUpdaterBridge 6 | --- 7 | 8 | AppImage Updater Bridge can compiled with both *QMake* and *CMake* , I recommend you to use *QMake* if you are 9 | building your application statically with Qt. Use *CMake* for normal compilation and other stuff , This is because *CMake* is 10 | easy to use than *QMake* when compiling with shared libraries of Qt. But *CMake* is very hard to work with when using a static 11 | version of Qt , So to save some madness be a good boy/girl and use *QMake* instead. 12 | 13 | 14 | # Using QMake. 15 | 16 | ## The Simple Way for Single Application. 17 | 18 | * Go to your project folder. 19 | * Install AppImageUpdaterBridge as a git submodule or just clone it. 20 | 21 | * Add this line to your project file. 22 | ``` 23 | include(AppImageUpdaterBridge/AppImageUpdaterBridge.pri) 24 | ``` 25 | 26 | * Add AppImageUpdaterBridge headers to your source file. 27 | ``` 28 | #include 29 | ``` 30 | 31 | * Finally , Just Compile. 32 | ``` 33 | $ mkdir build ; cd build ; qmake .. ; make -j$(nproc) 34 | ``` 35 | 36 | ## The Hard And Standard Way for Large Applications and Libraries. 37 | 38 | Since your project uses qmake as the makefile generator then you have to follow a specific directory 39 | hierarchy , The structure is show below. 40 | 41 | ``` 42 | -MyCoolApplication 43 | --libs 44 | ---AppImageUpdaterBridge 45 | ---libs.pro 46 | --src 47 | ---main.cpp 48 | ---mainwindow.hpp 49 | ---mainwindow.cpp 50 | ---src.pro 51 | --MyCoolApplication.pro 52 | ``` 53 | 54 | 55 | ### The Library Subdir Project file (libs.pro) 56 | 57 | This is where you keep all third party libraries including **AppImageUpdaterBridge**. 58 | Just add a **git submodule** or execute the steps mentioned in the **Installation** 59 | in the **libs** directory of your project folder. 60 | 61 | 62 | 63 | ``` 64 | TEMPLATE = subdirs 65 | CONFIG += ordered 66 | SUBDIRS = AppImageUpdaterBridge 67 | ``` 68 | 69 | ### Your Source's Project file (src.pro) 70 | 71 | ``` 72 | TEMPLATE = app 73 | TARGET = ../MyCoolApplication 74 | 75 | QT += core gui # Modules thats needed by your app. 76 | 77 | # Put your dynamic libs after AppImageUpdaterBridge. 78 | LIBS += ../libs/AppImageUpdaterBridge/libAppImageUpdaterBridge.a 79 | 80 | INCLUDEPATH += . .. \ 81 | ../libs/AppImageUpdaterBridge/ # This is important 82 | 83 | SOURCES += main.cpp mainwindow.cpp # All your source files. 84 | HEADERS += mainwindow.hpp # All your header files. 85 | ``` 86 | 87 | ### Your Main Project file ( MyCoolApplication.pro ) 88 | 89 | ``` 90 | TEMPLATE = subdirs 91 | CONFIG += ordered 92 | SUBDIRS = libs \ # Always use this order 93 | src 94 | ``` 95 | 96 | 97 | ### Including AppImageUpdaterBridge in your Source 98 | 99 | Whenever you want to use **AppImageUpdaterBridge** , you just need to include it! 100 | 101 | ``` 102 | #include 103 | ``` 104 | 105 | 106 | Thats it , All you have to do is to build your project with **qmake**. 107 | 108 | ``` 109 | $ mkdir build; cd build ; qmake .. ; make -j$(nproc) 110 | ``` 111 | 112 | 113 | # Using CMake 114 | 115 | It is recommended for you to keep your source files at the top level and then add 116 | AppImageUpdaterBridge as a subdirectory in your CMakeList.txt 117 | 118 | Here is a small example on how it is done! 119 | 120 | ``` 121 | CMAKE_MINIMUM_REQUIRED( VERSION 3.2) 122 | project(MyCoolApplication) 123 | 124 | set(CMAKE_CXX_STANDARD 11) 125 | 126 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 127 | # Instruct CMake to run moc automatically when needed. 128 | set(CMAKE_AUTOMOC ON) 129 | 130 | # Find the QtCore library 131 | find_package(Qt5Core) 132 | find_package(Qt5Network) 133 | find_package(Qt5Widgets) 134 | 135 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) # just in case! 136 | # Add include directory 137 | include_directories(AppImageUpdaterBridge) 138 | include_directories(AppImageUpdaterBridge/include) 139 | 140 | # include subdirectories 141 | add_subdirectory(AppImageUpdaterBridge) 142 | 143 | add_executable(MyCoolApplication MyMain.cpp) 144 | target_link_libraries(MyCoolApplication AppImageUpdaterBridge 145 | Qt5::Core 146 | Qt5::Network 147 | Qt5::Widgets) 148 | ``` 149 | 150 | Where **MyCoolApplication** is the application that you are currently working with. 151 | 152 | # Disable Logging in QMake or CMake 153 | 154 | For some reasone if you think you don't want logging support whatsoever , i.e no signal from logger signal in 155 | AppImageDeltaRevisioner. 156 | 157 | In QMake like this , 158 | 159 | ``` 160 | $ qmake "CONFIG+=LOGGING_DISABLED" [ProjectFolder] 161 | ``` 162 | 163 | and 164 | 165 | In CMake like this , 166 | 167 | ``` 168 | $ cmake -DLOGGING_DISABLED=ON [ProjectFolder] 169 | ``` 170 | 171 | Compiling without logger support can reduce your binary by approx. 100 KiB and 172 | also saves some runtime overhead and memory usage. 173 | 174 | # Disable building AppImageUpdaterDialog 175 | 176 | AppImageUpdaterDialog is a class provided by the library for an easy use of the updater 177 | through a nice graphical modal dialog which can be handy at times. 178 | But if you want to disable this for some reason then you can do so by doing like this , 179 | 180 | In QMake , 181 | 182 | ``` 183 | $ qmake "CONFIG+=NO_GUI" [ProjectFolder] 184 | ``` 185 | 186 | and 187 | 188 | In CMake , 189 | 190 | ``` 191 | $ cmake -DNO_GUI=ON [ProjectFolder] 192 | ``` 193 | -------------------------------------------------------------------------------- /website/versioned_docs/version-2.0.0/AddingQAppImageUpdate.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: version-2.0.0-AddingQAppImageUpdate 3 | title: Add QAppImageUpdate to your Project 4 | sidebar_label: Adding to your Project 5 | original_id: AddingQAppImageUpdate 6 | --- 7 | 8 | QAppImage can compiled with both *QMake* and *CMake* , I recommend you to use *QMake* if you are 9 | building your application statically with Qt. Use *CMake* for normal compilation and other stuff, This is because *CMake* is 10 | easy to use than *QMake* when compiling with shared libraries of Qt. But *CMake* is very hard to work with when using a static 11 | version of Qt , So to save some madness be a good boy/girl and use *QMake* instead. 12 | 13 | 14 | # Using QMake. 15 | 16 | ## The Simple Way for Single Application. 17 | 18 | * Go to your project folder. 19 | * Install QAppImageUpdate as a git submodule or just clone it. 20 | 21 | * Add this line to your project file. 22 | ``` 23 | include(QAppImageUpdate/QAppImageUpdate.pri) 24 | ``` 25 | 26 | * Add QAppImageUpdate headers to your source file. 27 | ``` 28 | #include 29 | ``` 30 | 31 | * Finally , Just Compile. 32 | ``` 33 | $ mkdir build ; cd build ; qmake .. ; make -j$(nproc) 34 | ``` 35 | 36 | ## The Hard And Standard Way for Large Applications and Libraries. 37 | 38 | Since your project uses qmake as the makefile generator then you have to follow a specific directory 39 | hierarchy , The structure is show below. 40 | 41 | ``` 42 | -MyCoolApplication 43 | --libs 44 | ---QAppImageUpdate 45 | ---libs.pro 46 | --src 47 | ---main.cpp 48 | ---mainwindow.hpp 49 | ---mainwindow.cpp 50 | ---src.pro 51 | --MyCoolApplication.pro 52 | ``` 53 | 54 | 55 | ### The Library Subdir Project file (libs.pro) 56 | 57 | This is where you keep all third party libraries including **QAppImageUpdate**. 58 | Just add a **git submodule** or execute the steps mentioned in the **Installation** 59 | in the **libs** directory of your project folder. 60 | 61 | 62 | 63 | ``` 64 | TEMPLATE = subdirs 65 | CONFIG += ordered 66 | SUBDIRS = QAppImageUpdate 67 | ``` 68 | 69 | ### Your Source's Project file (src.pro) 70 | 71 | ``` 72 | TEMPLATE = app 73 | TARGET = ../MyCoolApplication 74 | 75 | QT += core gui # Modules thats needed by your app. 76 | 77 | # Put your dynamic libs after QAppImageUpdate. 78 | LIBS += ../libs/QAppImageUpdate/libQAppImageUpdate.a 79 | 80 | INCLUDEPATH += . .. \ 81 | ../libs/QAppImageUpdate/ # This is important 82 | 83 | SOURCES += main.cpp mainwindow.cpp # All your source files. 84 | HEADERS += mainwindow.hpp # All your header files. 85 | ``` 86 | 87 | ### Your Main Project file ( MyCoolApplication.pro ) 88 | 89 | ``` 90 | TEMPLATE = subdirs 91 | CONFIG += ordered 92 | SUBDIRS = libs \ # Always use this order 93 | src 94 | ``` 95 | 96 | 97 | ### Including QAppImageUpdate in your Source 98 | 99 | Whenever you want to use **QAppImageUpdate**, you just need to include it! 100 | 101 | ``` 102 | #include 103 | ``` 104 | 105 | 106 | Thats it, All you have to do is to build your project with **qmake**. 107 | 108 | ``` 109 | $ mkdir build; cd build ; qmake .. ; make -j$(nproc) 110 | ``` 111 | 112 | 113 | # Using CMake 114 | 115 | It is recommended for you to keep your source files at the top level and then add 116 | QAppImageUpdate as a subdirectory in your CMakeList.txt 117 | 118 | Here is a small example on how it is done! 119 | 120 | ``` 121 | CMAKE_MINIMUM_REQUIRED( VERSION 3.2) 122 | project(MyCoolApplication) 123 | 124 | set(CMAKE_CXX_STANDARD 11) 125 | 126 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 127 | # Instruct CMake to run moc automatically when needed. 128 | set(CMAKE_AUTOMOC ON) 129 | 130 | # Find the QtCore library 131 | find_package(Qt5Core) 132 | find_package(Qt5Network) 133 | find_package(Qt5Widgets) 134 | 135 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) # just in case! 136 | # Add include directory 137 | include_directories(QAppImageUpdate) 138 | 139 | # include subdirectories 140 | add_subdirectory(QAppImageUpdate) 141 | 142 | add_executable(MyCoolApplication MyMain.cpp) 143 | target_link_libraries(MyCoolApplication QAppImageUpdate 144 | Qt5::Core 145 | Qt5::Network 146 | Qt5::Widgets) 147 | ``` 148 | 149 | Where **MyCoolApplication** is the application that you are currently working with. 150 | 151 | # Disable Logging in QMake or CMake 152 | 153 | For some reasone if you think you don't want logging support whatsoever , i.e no signal from logger signal in 154 | AppImageDeltaRevisioner. 155 | 156 | In QMake like this , 157 | 158 | ``` 159 | $ qmake "CONFIG+=LOGGING_DISABLED" [ProjectFolder] 160 | ``` 161 | 162 | and 163 | 164 | In CMake like this , 165 | 166 | ``` 167 | $ cmake -DLOGGING_DISABLED=ON [ProjectFolder] 168 | ``` 169 | 170 | Compiling without logger support can reduce your binary by approx. 100 KiB and 171 | also saves some runtime overhead and memory usage. 172 | 173 | # Disable GUI Support 174 | 175 | QAppImageUpdate gives a basic gui implementation, if you don't want it use this. 176 | 177 | In QMake , 178 | 179 | ``` 180 | $ qmake "CONFIG+=NO_GUI" [ProjectFolder] 181 | ``` 182 | 183 | and 184 | 185 | In CMake , 186 | 187 | ``` 188 | $ cmake -DNO_GUI=ON [ProjectFolder] 189 | ``` 190 | 191 | 192 | # Enable Torrent Update Feature 193 | 194 | As of v2.0 QAppImageUpdate supports updating AppImages via Bittorrent protocol. 195 | 196 | **But you should have torrent rasterbar installed, At least v1.2.8 is needed for QAppImageUpdate.** 197 | 198 | 199 | In QMake , 200 | 201 | ``` 202 | $ qmake "CONFIG+=DECENTRALIZED_UPDATE_ENABLED" [ProjectFolder] 203 | ``` 204 | 205 | and 206 | 207 | In CMake , 208 | 209 | ``` 210 | $ cmake -DDECENTRALIZED_UPDATE_ENABLED=ON [ProjectFolder] 211 | ``` 212 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.2) 2 | project(QAppImageUpdate VERSION 2.0.2) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_AUTOMOC ON) 7 | set(CMAKE_AUTOUIC ON) 8 | 9 | option(LG "LOGGING_DISABLED" OFF) 10 | option(NG "NO_GUI" OFF) 11 | option(BAP "BUILD_AS_PLUGIN" OFF) 12 | 13 | # Let cmake know that this is a release build. 14 | if(NOT CMAKE_BUILD_TYPE) 15 | set(CMAKE_BUILD_TYPE Release) 16 | endif() 17 | 18 | set(CMAKE_CXX_FLAGS "-Wall -Wextra") 19 | set(CMAKE_CXX_FLAGS_DEBUG "-g") 20 | set(CMAKE_CXX_FLAGS_RELEASE "-O3") 21 | 22 | set(MIN_QT_VERSION "5.6.0") 23 | 24 | find_package(Qt5Core ${MIN_QT_VERSION}) 25 | find_package(Qt5Network ${MIN_QT_VERSION}) 26 | 27 | if(NOT NO_GUI) 28 | find_package(Qt5Widgets ${MIN_QT_VERSION}) 29 | endif() 30 | 31 | # cmake macros used 32 | include(GNUInstallDirs) 33 | include(CMakePackageConfigHelpers) 34 | 35 | # Include Directories. 36 | include_directories(.) 37 | include_directories(include) 38 | include_directories(${CMAKE_BINARY_DIR}) 39 | 40 | if(BUILD_TESTS) 41 | add_subdirectory(tests) 42 | endif() 43 | 44 | if(BUILD_EXAMPLES) 45 | add_subdirectory(examples/CheckForUpdate) 46 | add_subdirectory(examples/GetEmbeddedInfo) 47 | add_subdirectory(examples/ProxyUpdate) 48 | add_subdirectory(examples/Update) 49 | add_subdirectory(examples/UpdateWithTorrent) 50 | add_subdirectory(examples/UpdateWithGUI) 51 | add_subdirectory(examples/UpdateWithGUIAndTorrent) 52 | endif() 53 | 54 | SET(source) 55 | list(APPEND source 56 | src/qappimageupdate.cc 57 | src/qappimageupdate_p.cc 58 | src/rangereply.cc 59 | src/rangereply_p.cc 60 | src/rangedownloader.cc 61 | src/rangedownloader_p.cc 62 | src/zsyncremotecontrolfileparser_p.cc 63 | src/appimageupdateinformation_p.cc 64 | src/zsyncwriter_p.cc 65 | src/helpers_p.cc 66 | include/qappimageupdate.hpp 67 | include/qappimageupdate_p.hpp 68 | include/rangereply.hpp 69 | include/rangereply_p.hpp 70 | include/zsyncremotecontrolfileparser_p.hpp 71 | include/appimageupdateinformation_p.hpp 72 | include/rangedownloader.hpp 73 | include/rangedownloader_p.hpp 74 | include/zsyncinternalstructures_p.hpp 75 | include/zsyncwriter_p.hpp 76 | include/qappimageupdatecodes.hpp 77 | include/qappimageupdateenums.hpp 78 | include/helpers_p.hpp) 79 | 80 | SET(toinstall) 81 | list(APPEND toinstall 82 | QAppImageUpdate 83 | include/qappimageupdate.hpp 84 | include/qappimageupdateenums.hpp 85 | include/qappimageupdatecodes.hpp 86 | ) 87 | 88 | if(LOGGING_DISABLED) 89 | message("-- [*] IMPORTANT: Logging will be disabled for this build.") 90 | add_definitions(-DLOGGING_DISABLED) 91 | endif() 92 | 93 | if(NO_GUI) 94 | message("-- [*] IMPORTANT: No gui classes will be included in this build.") 95 | add_definitions(-DNO_GUI) 96 | else() 97 | list(APPEND source src/softwareupdatedialog_p.cc 98 | include/softwareupdatedialog_p.hpp) 99 | endif() 100 | 101 | 102 | if(DECENTRALIZED_UPDATE_ENABLED) 103 | message("-- [*] IMPORTANT: Decentralized update feature is ENABLED.") 104 | add_definitions(-DDECENTRALIZED_UPDATE_ENABLED) 105 | list(APPEND source src/torrentdownloader.cc 106 | src/torrentdownloader_p.cc 107 | src/seeder.cc 108 | src/seeder_p.cc 109 | include/torrentdownloader.hpp 110 | include/torrentdownloader_p.hpp 111 | include/seeder.hpp 112 | include/seeder_p.hpp) 113 | endif() 114 | 115 | if(NOT DECENTRALIZED_UPDATE_ENABLED) 116 | message("-- [*] IMPORTANT: Decentralized update feature is DISABLED in this build.") 117 | endif() 118 | 119 | if(BUILD_AS_PLUGIN) 120 | message("-- [*] IMPORTANT: Building as a Qt Plugin.") 121 | add_definitions(-DBUILD_AS_PLUGIN) 122 | list(APPEND source include/qappimageupdateinterface.hpp 123 | include/qappimageupdateinterfaceimpl.hpp 124 | src/qappimageupdateinterfaceimpl.cc) 125 | add_library(QAppImageUpdate SHARED ${source}) 126 | else() 127 | if(BUILD_AS_SHARED_LIB) 128 | add_library(QAppImageUpdate SHARED ${source}) 129 | endif() 130 | 131 | if(NOT BUILD_AS_SHARED_LIB) 132 | add_library(QAppImageUpdate ${source}) 133 | endif() 134 | endif() 135 | 136 | target_link_libraries(QAppImageUpdate PUBLIC Qt5::Core Qt5::Network) 137 | target_include_directories(QAppImageUpdate INTERFACE 138 | $ 139 | $ 140 | $) 141 | target_include_directories(QAppImageUpdate INTERFACE "$" ) 142 | 143 | if(DECENTRALIZED_UPDATE_ENABLED) 144 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/usr/local/share/cmake/Modules") 145 | find_package(LibtorrentRasterbar) 146 | target_link_libraries(QAppImageUpdate PUBLIC LibtorrentRasterbar::torrent-rasterbar) 147 | endif() 148 | 149 | if(NOT NO_GUI) 150 | target_link_libraries(QAppImageUpdate PUBLIC Qt5::Widgets) 151 | endif() 152 | 153 | 154 | # Add pkg-config and install instructions 155 | configure_file( 156 | "${PROJECT_SOURCE_DIR}/other/pkgconfig/QAppImageUpdate.pc.in" 157 | "${PROJECT_BINARY_DIR}/QAppImageUpdate.pc" 158 | @ONLY 159 | ) 160 | 161 | install(FILES 162 | ${PROJECT_BINARY_DIR}/QAppImageUpdate.pc 163 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") 164 | 165 | install(TARGETS 166 | QAppImageUpdate 167 | EXPORT QAppImageUpdateTargets 168 | DESTINATION "${CMAKE_INSTALL_LIBDIR}") 169 | 170 | install(FILES 171 | ${toinstall} 172 | DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/QAppImageUpdate") 173 | 174 | # Add CMake config 175 | set(CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/QAppImageUpdate") 176 | if(NOT NO_GUI) 177 | set(PACKAGE_FIND_DEPENDENCY_QTWIDGETS "find_dependency(Qt5Widgets ${MIN_QT_VERSION})") 178 | endif() 179 | configure_package_config_file( 180 | "${PROJECT_SOURCE_DIR}/other/cmake/QAppImageUpdateConfig.cmake.in" 181 | "${CMAKE_CURRENT_BINARY_DIR}/QAppImageUpdateConfig.cmake" 182 | INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} 183 | ) 184 | 185 | install(FILES 186 | "${CMAKE_CURRENT_BINARY_DIR}/QAppImageUpdateConfig.cmake" 187 | DESTINATION "${CMAKECONFIG_INSTALL_DIR}") 188 | 189 | install(EXPORT QAppImageUpdateTargets 190 | FILE QAppImageUpdateTargets.cmake 191 | DESTINATION "${CMAKECONFIG_INSTALL_DIR}") 192 | --------------------------------------------------------------------------------