Skip to content

Commit a04e07a

Browse files
committed
Finalize plugin interface; Add to documentation.
1 parent 6fa32c1 commit a04e07a

14 files changed

+369
-8539
lines changed

docs/AddingAppImageUpdaterBridge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
id: AddingAppImageUpdaterBridge
33
title: Add AppImage Updater Bridge to your Project
4-
sidebar_label: Add AppImage Updater Bridge to your Project.
4+
sidebar_label: Adding to your Project.
55
---
66

77
AppImage Updater Bridge can compiled with both *QMake* and *CMake* , I recommend you to use *QMake* if you are

docs/ClassAppImageDeltaRevisioner.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Eventhough all methods are reentrant , This class does not use **mutex** thanks
6363
| void | [updateAvailable(bool, QJsonObject)](#void-updateavailablebool-qjsonobject) |
6464
| void | [statusChanged(short)](#void-statuschangedshort) |
6565
| void | [error(short)](#void-errorshort) |
66-
| void | [progress(int, qint64, qint64, double, QString)](#void-progressint-percentage-qint64-bytesreceived-qint64-bytestotal-double-speed-qstring-speedunits) |
66+
| void | [progress(int, qint64, qint64, double, QString)](#void-progressint-percentage--qint64-bytesreceived--qint64-bytestotal--double-speed--qstring-speedunits) |
6767
| void | [logger(QString, QString)](#void-loggerqstring-qstring) |
6868

6969

@@ -310,11 +310,13 @@ The updater's progress is emitted through this unified signal.
310310

311311
**Where** ,
312312

313-
'percentage' is the percentage finished revising the latest AppImage.
314-
'bytesReceived' is the received bytes of the latest AppImage.
315-
'bytesTotal' is the total bytes of the latest AppImage.
316-
'speed' is the transfer speed value.
317-
'speedUnits' is the transfer speed unit(e.g. KiB/s , etc... ) for 'speed'.
313+
| Variable | Description |
314+
|----------------|------------------------------------------------------------------|
315+
| percentage | % Finished revising the latest AppImage. |
316+
| bytesReceived | The received bytes of the latest AppImage. |
317+
| bytesTotal | The total bytes of the latest AppImage. |
318+
| speed | The transfer speed value. |
319+
| speedUnit | The transfer speed unit(e.g. KiB/s , etc... ) for **speed**. |
318320

319321

320322
### void logger(QString , QString)

docs/PluginInterface.md

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
---
2+
id: PluginInterface
3+
title: AppImage Updater Bridge Plugin Interface
4+
sidebar_label: Qt Plugin Interface
5+
---
6+
7+
A plugin interface is a specification of public slots and signals that can be used to access
8+
the functionality of the plugin itself. The interface is not bound to any specific programming
9+
language and easily translates to any Qt bindings and programming language.
10+
11+
All slots are [reentrant](https://doc.qt.io/qt-5/threads-reentrancy.html) and thread safe.
12+
13+
Please refer the C++ documentation for info on how the slots act.
14+
15+
> IMPORTANT: You have to start your Qt event loop for AppImageUpdaterBridge to function.
16+
17+
### A note on Data Types
18+
19+
Since plugins are not C++ specific, The data types are vaguely defined.
20+
In dynamic languages like python, you can just use native data types. (i.e) For QString, you can use str or QString from your Qt binding itself.
21+
22+
I'm not sure about other Qt bindings, So help is much welcomed.
23+
24+
## Slots
25+
26+
| Name | Description |
27+
|------|------------------------------------|
28+
| [start()](#start) | Starts the update. |
29+
| [cancel()](#cancel) | Cancels current update process. |
30+
| [setAppImage(QString)](#setappimage-qstring) | Assume the given string as path to AppImage to update. |
31+
| [setShowLog(bool)](#setshowlogbool) | If the given boolean is true then prints log. |
32+
| [setOutputDirectory(QString)](#setoutputdirectory-qstring) | Set the output directory as given string. |
33+
| [setProxy(QNetworkProxy)](#setproxyconst-qnetworkproxy-https-docqtio-qt-5-qnetworkproxyhtml) | Use proxy as given in QNetworkProxy object. |
34+
| [checkForUpdate()](#checkforupdate) | Checks for new update. |
35+
| [clear()](#clear) | Clears internal cache and stores. |
36+
37+
## Signals
38+
39+
| Name | Description |
40+
|------|---------------|
41+
| [started()](#started) | Emitted when the update is actually started. |
42+
| [canceled()](#canceled) | Emitted when the update is canceled. |
43+
| [finished(QJsonObject , QString)](#finishedqjsonobject-qstring) | Emitted when update finishes. |
44+
| [updateAvailable(bool, QJsonObject)](#updateavailablebool-qjsonobject) | Emitted when checkForUpdate() is called. |
45+
| [error(short)](#errorshort) | Emitted when some error occurs. |
46+
| [progress(int, qint64, qint64, double, QString)](#progressint-percentage--qint64-bytesreceived--qint64-bytestotal--double-speed--qstring-speedunits) | Emitted on progress of update. See here for more information. |
47+
| [logger(QString, QString)](#loggerqstring-qstring) | See here for more information. |
48+
49+
50+
## Documentation
51+
52+
### start()
53+
<p align="right"> <b>[SLOT]</b> </p>
54+
55+
Starts the updater.
56+
Emits **started()** signal when starts.
57+
58+
59+
> Minor Note: You don't have to worry about anything if you called checkForUpdate or getAppImageEmbededInformation
60+
slots before start , Don't worry about overheads too , Since when you call checkForUpdate slot , The information
61+
is cached and when start slot is called again , it will be faster than normal.
62+
63+
> Important Note: You should also call clear and set the settings again if you want to clear the cache.
64+
65+
### cancel()
66+
<p align="right"> <b>[SLOT]</b> </p>
67+
68+
Cancels the update.
69+
Emits **canceled()** signal when cancel was successfull.
70+
71+
72+
### setAppImage(QString)
73+
<p align="right"> <b>[SLOT]</b> </p>
74+
75+
Sets the AppImage Path as the given **QString**.
76+
77+
78+
### setShowLog(bool)
79+
<p align="right"> <b>[SLOT]</b> </p>
80+
81+
Turns on and off the log printer.
82+
83+
> Note: logger signal will be emitted all the time if the library is compiled with LOGGING_DISABLED undefined,
84+
setShowLog will not affect this activity at all, But setShowLog will print these log messages
85+
if set to true.
86+
87+
### setOutputDirectory(QString)
88+
<p align="right"> <b>[SLOT]</b> </p>
89+
90+
Writes the new version of the AppImage to the given Output directory , Assuming the given QString a directory path.
91+
The default is the old version AppImage's directory.
92+
93+
94+
### setProxy([QNetworkProxy](https://doc.qt.io/qt-5/qnetworkproxy.html))
95+
<p align="right"> <b>[SLOT]</b> </p>
96+
97+
Sets the given [QNetworkProxy](https://doc.qt.io/qt-5/qnetworkproxy.html) as the proxy
98+
99+
### checkForUpdate()
100+
<p align="right"> <b>[SLOT]</b> </p>
101+
102+
Checks update for the current operating AppImage.
103+
emits **updateAvailable(bool , QJsonObject)** , Where the *bool* will be **true** if the AppImage
104+
needs update. The QJsonObject in the signal will have the details of the current operating
105+
AppImage.
106+
107+
108+
### clear()
109+
<p align="right"> <b>[SLOT]</b> </p>
110+
111+
Clears all internal **cache** and stores.
112+
113+
114+
### started()
115+
<p align="right"> <b>[SIGNAL]</b> </p>
116+
117+
Emitted when the updater is started successfully.
118+
119+
### canceled()
120+
<p align="right"> <b>[SIGNAL]</b> </p>
121+
122+
Emitted when the update is canceled successfully.
123+
124+
### finished(QJsonObject , QString)
125+
<p align="right"> <b>[SIGNAL]</b> </p>
126+
127+
Emitted when the update is finished successfully. The given *QJsonObject* has the details of the new version
128+
of the AppImage and the given *QString* has the absolute path to the old versioin of the AppImage.
129+
130+
The *QJsonObject* will follow the folloing format with respect to json ,
131+
132+
{
133+
"AbsolutePath" : "Absolute path of the new version of the AppImage" ,
134+
"Sha1Hash" : "Sha1 hash of the new version of the AppImage"
135+
}
136+
137+
> Note: If the absolute path of the new version of the AppImage is same as the old version then
138+
it could mean that there were no updates needed , You can however listen to the *updateAvailable*
139+
signal to know the exact state of updates. You should call *checkForUpdate* and then call *start*
140+
if updates were really available.
141+
142+
143+
### updateAvailable(bool , QJsonObject)
144+
<p align="right"> <b>[SIGNAL]</b> </p>
145+
146+
Emitted when *[checkForUpdate()](#checkforupdate)* is called.
147+
The given *bool* states if the operating AppImage needs update and the *QJsonObject* gives the details of
148+
the current operating AppImage.
149+
150+
The *QJsonObject* will follow the following format with respect to json ,
151+
152+
{
153+
"AbsolutePath" : "The absolute path of the current operating AppImage" ,
154+
"Sha1Hash" : "The Sha1 hash of the current operating AppImage" ,
155+
"RemoteSha1Hash" : "The Sha1 hash of the lastest AppImage" ,
156+
"ReleaseNotes" : "Release notes if available"
157+
}
158+
159+
### error(short)
160+
<p align="right"> <b>[SIGNAL]</b> </p>
161+
162+
Emitted when the updater is errored. The given short integer is the error code.
163+
See [error codes](AppImageUpdaterBridgeErrorCodes.html).
164+
165+
166+
### progress(int percentage , qint64 bytesReceived , qint64 bytesTotal , double speed , QString speedUnits)
167+
<p align="right"> <b>[SIGNAL]</b> </p>
168+
169+
The updater's progress is emitted through this unified signal.
170+
171+
**Where** ,
172+
173+
| Variable | Description |
174+
|----------------|------------------------------------------------------------------|
175+
| percentage | % Finished revising the latest AppImage. |
176+
| bytesReceived | The received bytes of the latest AppImage. |
177+
| bytesTotal | The total bytes of the latest AppImage. |
178+
| speed | The transfer speed value. |
179+
| speedUnit | The transfer speed unit(e.g. KiB/s , etc... ) for **speed**. |
180+
181+
### logger(QString , QString)
182+
<p align="right"> <b>[SIGNAL]</b> </p>
183+
184+
Emitted when the updater issues a log message with the *first QString* as the log message and
185+
the *second QString* as the path to the respective AppImage.
186+

docs/PyQt5PluginExample.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
id: PyQt5PluginExample
3+
title: Using AppImage Updater Bridge Plugin in PyQt5
4+
sidebar_label: Using Plugin in PyQt5
5+
---
6+
7+
This guide Demonstrates how to use the *AppImageUpdaterBridge* 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 'libAppImageUpdaterBridge'.
12+
13+
14+
## Building the Plugin
15+
16+
```
17+
$ git clone https://github.com/antony-jr/AppImageUpdaterBridge
18+
$ cd AppImageUpdaterBridge
19+
$ mkdir build
20+
$ cd build
21+
$ cmake -DBUILD_AS_PLUGIN ..
22+
$ make -j$(nproc)
23+
$ export PLUGIN_PATH=$(pwd)/libAppImageUpdaterBridge.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('libAppImageUpdaterBridge')
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, old_appimge_path):
61+
print(info)
62+
app.quit()
63+
64+
def handleError(code):
65+
print("A error occured, error code: {}".format(code))
66+
app.quit()
67+
68+
def handleUpdate(avail):
69+
if avail:
70+
print("A new version of the AppImage is available.")
71+
print("Updating now... ")
72+
obj.start()
73+
else:
74+
print("You have the latest AppImage!")
75+
app.quit()
76+
77+
obj.updateAvailable.connect(handleUpdate)
78+
obj.finished.connect(handleFinish)
79+
obj.error.connect(handleError)
80+
81+
obj.setAppImage(appimage_path)
82+
83+
print("Checking for Update... ")
84+
obj.checkForUpdate()
85+
sys.exit(app.exec_())
86+
```
87+
88+
## Execution
89+
90+
```
91+
$ chmod +x Update.py
92+
$ ./Update.py some.AppImage
93+
```
94+
95+
See the examples directory in the source tree for more examples.

docs/UsingPlugin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ AppImage Updater Bridge can compiled as a **Qt Plugin**. When it is built as a Q
88

99
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.
1010

11-
You can see the plugin interface here.
11+
You can see the plugin interface [here](PluginInterface.html).
1212

1313
To read more about Qt plugins, Please refer the official documentation.
1414

examples/PyQt5Update/Update.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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('libAppImageUpdaterBridge')
17+
if not loader.load():
18+
try:
19+
plugin_path = os.eviron['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 handleFinish(info, old_appimge_path):
33+
print(info)
34+
app.quit()
35+
36+
def handleError(code):
37+
print("A error occured, error code: {}".format(code))
38+
app.quit()
39+
40+
def handleUpdate(avail):
41+
if avail:
42+
print("A new version of the AppImage is available.")
43+
print("Updating now... ")
44+
obj.start()
45+
else:
46+
print("You have the latest AppImage!")
47+
app.quit()
48+
49+
obj.updateAvailable.connect(handleUpdate)
50+
obj.finished.connect(handleFinish)
51+
obj.error.connect(handleError)
52+
53+
obj.setAppImage(appimage_path)
54+
55+
print("Checking for Update... ")
56+
obj.checkForUpdate()
57+
sys.exit(app.exec_())

include/appimageupdaterbridge_p.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ namespace AppImageUpdaterBridge {
1717
void start();
1818
void cancel();
1919
void setAppImage(const QString&);
20-
//void setAppImage(QFile*);
2120
void setShowLog(bool);
2221
void setOutputDirectory(const QString&);
2322
void setProxy(const QNetworkProxy&);

0 commit comments

Comments
 (0)