Improve Ubuntu Touch support (add push notification and clean up)

This commit is contained in:
Michael Zanetti 2019-12-16 14:11:55 +01:00
parent d39cdf94d9
commit 195efeebee
18 changed files with 992 additions and 12 deletions

@ -1 +1 @@
Subproject commit 1e36e430e98ecec6e15ab06f56467567f22f9e8a
Subproject commit d3e03568a9f20ccd4f98f6a183d411a441f49482

View File

@ -1,11 +1,13 @@
{
"template": "qmake",
"kill": "nymea-app",
"build_args": "CONFIG+=click CONFIG+=ubuntu",
"build_args": "CONFIG+=ubports",
"dependencies_target": [
"libavahi-client-dev",
"libavahi-common-dev",
"libqt5charts5-dev",
"qml-module-qtcharts"
"qml-module-qtcharts",
"libconnectivity-qt1-dev",
"libunity-api-dev"
]
}

View File

@ -56,6 +56,8 @@ AWSClient::AWSClient(QObject *parent) : QObject(parent),
QString pushSystem = "GCM";
#elif defined Q_OS_IOS
QString pushSystem = "APNS";
#elif UBPORTS
QString pushSystem = "UBPORTS";
#else
QString pushSystem = "";
#endif
@ -645,7 +647,7 @@ void AWSClient::registerPushNotificationEndpoint(const QString &registrationId,
QJsonDocument jsonDoc = QJsonDocument::fromVariant(payload);
qDebug() << "Registering push notification endpoint";
qDebug() << "Registering push notification endpoint" << qUtf8Printable(QJsonDocument::fromVariant(payload).toJson());
// qDebug() << "POST" << url.toString();
// qDebug() << "HEADERS:";
// foreach (const QByteArray &hdr, request.rawHeaderList()) {

View File

@ -213,7 +213,7 @@ void DeviceManager::getVendorsResponse(const QVariantMap &params)
void DeviceManager::getSupportedDevicesResponse(const QVariantMap &params)
{
qDebug() << "DeviceClass received:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented));
// qDebug() << "DeviceClass received:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson(QJsonDocument::Indented));
if (params.value("params").toMap().keys().contains("deviceClasses")) {
QVariantList deviceClassList = params.value("params").toMap().value("deviceClasses").toList();
foreach (QVariant deviceClassVariant, deviceClassList) {

View File

@ -146,3 +146,8 @@ HEADERS += \
configuration/mqttpolicies.h \
models/devicemodel.h \
system/systemcontroller.h
ubports: {
DEFINES += UBPORTS
}

View File

@ -85,9 +85,17 @@ desktopfile.path = /usr/share/applications/
INSTALLS += desktopfile
}
click: {
ubuntu_files.path += /
ubuntu_files.files += manifest.json nymea-app.apparmor nymea-app.desktop packaging/android/appicon.svg
ubports: {
ubuntu_files.path = /
ubuntu_files.files += \
packaging/ubuntu/click/manifest.json \
packaging/ubuntu/click/nymea-app.apparmor \
packaging/ubuntu/click/nymea-app.desktop \
packaging/ubuntu/click/appicon.svg \
packaging/ubuntu/click/push.json \
packaging/ubuntu/click/push-apparmor.json \
packaging/ubuntu/click/pushexec
INSTALLS += ubuntu_files
}

View File

@ -129,6 +129,17 @@ ios: {
QMAKE_MAC_XCODE_SETTINGS += IOS_ENTITLEMENTS
}
ubports: {
DEFINES += UBPORTS
CONFIG += link_pkgconfig
PKGCONFIG += connectivity-qt1
HEADERS += platformintegration/ubports/pushclient.h
SOURCES += platformintegration/ubports/pushclient.cpp
}
BR=$$BRANDING
!equals(BR, "") {
DEFINES += BRANDING=\\\"$${BR}\\\"

View File

@ -0,0 +1,208 @@
/*
Copyright 2014 Canonical Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License, version 3
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#include "pushclient.h"
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusPendingCall>
#include <QtDBus/QDBusPendingReply>
#include <QTimer>
#define PUSH_SERVICE "com.ubuntu.PushNotifications"
#define POSTAL_SERVICE "com.ubuntu.Postal"
#define PUSH_PATH "/com/ubuntu/PushNotifications"
#define POSTAL_PATH "/com/ubuntu/Postal"
#define PUSH_IFACE "com.ubuntu.PushNotifications"
#define POSTAL_IFACE "com.ubuntu.Postal"
PushClient::PushClient(QObject *parent) :
QObject(parent),
ns(new connectivityqt::Connectivity(QDBusConnection::sessionBus(), this))
{
}
void PushClient::setAppId(const QString &appId) {
if (appId == this->appId || appId.isEmpty())
return;
this->appId = appId;
emit appIdChanged(appId);
if (ns->online()) {
registerApp();
} else {
disconnect(ns.data(), 0, this, 0);
connect(ns.data(), &connectivityqt::Connectivity::onlineUpdated, this, &PushClient::connectionStatusChanged);
}
}
void PushClient::connectionStatusChanged(bool status)
{
if (status) {
disconnect(ns.data(), 0, this, 0);
registerApp();
}
}
void PushClient::registerApp()
{
if (appId.isEmpty())
return;
pkgname = appId.split("_").at(0);
pkgname = pkgname.replace(".","_2e").replace("-","_2d");
QString register_path(PUSH_PATH);
register_path += "/" + pkgname;
QDBusConnection bus = QDBusConnection::sessionBus();
// Register to the push client
QDBusMessage message = QDBusMessage::createMethodCall(PUSH_SERVICE, register_path , PUSH_IFACE, "Register");
message << appId;
QDBusPendingCall pcall = bus.asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::registerFinished);
// Connect to the notification signal
QString postal_path(POSTAL_PATH);
postal_path += "/" + pkgname;
bus.connect(POSTAL_SERVICE, postal_path, POSTAL_IFACE, "Post", "s", this, SLOT(notified(QString)));
}
void PushClient::registerFinished(QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QString> reply = *watcher;
if (reply.isError()) {
status = reply.error().message();
emit statusChanged(status);
// This has to be delayed because the error signal is not connected yet
QTimer::singleShot(200, this, &PushClient::emitError);
}
else {
this->token = reply.value();
// Do an initial fetch
QTimer::singleShot(200, this, &PushClient::getNotifications);
emit tokenChanged(this->token);
}
watcher->deleteLater();
}
QString PushClient::getAppId() {
return appId;
}
QString PushClient::getToken() {
return token;
}
void PushClient::emitError()
{
emit error(status);
}
void PushClient::notified(const QString &)
{
this->getNotifications();
}
void PushClient::getNotifications() {
QDBusConnection bus = QDBusConnection::sessionBus();
QString path(POSTAL_PATH);
path += "/" + pkgname;
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "PopAll");
message << this->appId;
QDBusPendingCall pcall = bus.asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
connect(watcher, &QDBusPendingCallWatcher::finished,this, &PushClient::popAllFinished);
}
void PushClient::popAllFinished(QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<QStringList> reply = *watcher;
if (reply.isError()) {
emit error(reply.error().message());
}
else {
emit notificationsChanged(reply.value());
}
watcher->deleteLater();
}
QStringList PushClient::getPersistent() {
// FIXME: this is blocking, but making it async would change the API
QDBusConnection bus = QDBusConnection::sessionBus();
QString path(POSTAL_PATH);
path += "/" + pkgname;
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "ListPersistent");
message << this->appId;
QDBusMessage reply = bus.call(message);
if (reply.type() == QDBusMessage::ErrorMessage) {
emit error(reply.errorMessage());
}
return reply.arguments()[0].toStringList();
}
void PushClient::clearPersistent(const QStringList &tags) {
QDBusConnection bus = QDBusConnection::sessionBus();
QString path(POSTAL_PATH);
path += "/" + pkgname;
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "ClearPersistent");
message << this->appId;
for (int i = 0; i < tags.size(); ++i) {
message << tags.at(i);
}
QDBusPendingCall pcall = bus.asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::clearPersistentFinished);
}
void PushClient::clearPersistentFinished(QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<void> reply = *watcher;
if (reply.isError()) {
emit error(reply.error().message());
} else {
// FIXME: this is blocking
emit persistentChanged(getPersistent());
}
}
void PushClient::setCount(int count) {
QDBusConnection bus = QDBusConnection::sessionBus();
QString path(POSTAL_PATH);
bool visible = count != 0;
counter = count;
path += "/" + pkgname;
QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "SetCounter");
message << this->appId << count << visible;
QDBusPendingCall pcall = bus.asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &PushClient::setCounterFinished);
}
void PushClient::setCounterFinished(QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<void> reply = *watcher;
if (reply.isError()) {
emit error(reply.error().message());
}
else {
emit countChanged(counter);
}
}
int PushClient::getCount() {
return counter;
}

View File

@ -0,0 +1,82 @@
/*
Copyright 2014 Canonical Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License, version 3
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
*/
#ifndef PUSHCLIENT_H
#define PUSHCLIENT_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <connectivityqt/connectivity.h>
class QDBusPendingCallWatcher;
class PushClient : public QObject
{
Q_OBJECT
public:
explicit PushClient(QObject *parent = 0);
void setAppId(const QString &appid);
QString getStatus() {return this->status;}
QString getAppId();
QString getToken();
QStringList getPersistent();
void setCount(int count);
int getCount();
Q_PROPERTY(QString appId WRITE setAppId READ getAppId NOTIFY appIdChanged)
Q_PROPERTY(QString token READ getToken NOTIFY tokenChanged)
Q_PROPERTY(QStringList notifications MEMBER notifications NOTIFY notificationsChanged)
Q_PROPERTY(QString status READ getStatus NOTIFY statusChanged)
Q_PROPERTY(QStringList persistent READ getPersistent NOTIFY persistentChanged)
Q_PROPERTY(int count READ getCount WRITE setCount NOTIFY countChanged)
signals:
void countChanged(int count);
void notificationsChanged(const QStringList &notifications);
void persistentChanged(const QStringList &tags);
void appIdChanged(const QString &appId);
void error(const QString &error);
void tokenChanged(const QString &token);
void statusChanged(const QString &status);
public slots:
void getNotifications();
void notified(const QString &appId);
void emitError();
void clearPersistent(const QStringList &tags);
private slots:
void registerFinished(QDBusPendingCallWatcher *watcher);
void popAllFinished(QDBusPendingCallWatcher *watcher);
void setCounterFinished(QDBusPendingCallWatcher *watcher);
void clearPersistentFinished(QDBusPendingCallWatcher *watcher);
void connectionStatusChanged(bool status);
private:
void registerApp();
QScopedPointer<connectivityqt::Connectivity> ns;
QString appId;
QString pkgname;
QString token;
QString status;
QStringList notifications;
int counter;
};
#endif // PUSHCLIENT_H

View File

@ -6,13 +6,21 @@
#include <QtAndroid>
#include <QtAndroidExtras>
#include <QAndroidJniObject>
#endif
static PushNotifications *m_client_pointer;
#endif
PushNotifications::PushNotifications(QObject *parent) : QObject(parent)
{
connectClient();
#ifdef UBPORTS
m_pushClient = new PushClient(this);
m_pushClient->setAppId("io.guh.nymeaapp_nymea-app");
connect(m_pushClient, &PushClient::tokenChanged, this, [this](const QString &token) {
m_token = token;
emit tokenChanged();
});
#endif
}
QObject *PushNotifications::pushNotificationsProvider(QQmlEngine *engine, QJSEngine *scriptEngine)

View File

@ -8,6 +8,11 @@
#include "firebase/app.h"
#include "firebase/messaging.h"
#include "firebase/util.h"
#elif UBPORTS
#include "platformintegration/ubports/pushclient.h"
#endif
#ifdef Q_OS_ANDROID
@ -44,6 +49,11 @@ protected:
private:
::firebase::App *m_firebaseApp = nullptr;
::firebase::ModuleInitializer m_firebase_initializer;
#elif UBPORTS
PushClient *m_pushClient = nullptr;
#endif
private:

View File

@ -0,0 +1,610 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="256"
height="256"
id="svg2"
version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="appicon.svg"
inkscape:export-filename="/home/micha/Develop/mea/mea/guh-logo-256x256.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs4">
<linearGradient
id="SVGID_1_"
gradientUnits="userSpaceOnUse"
x1="369.02579"
y1="171.88429"
x2="441.68719"
y2="262.58051">
<stop
offset="0.1296"
style="stop-color:#7CC099"
id="stop46" />
<stop
offset="0.3785"
style="stop-color:#6FB594"
id="stop48" />
<stop
offset="0.835"
style="stop-color:#4E9688"
id="stop50" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop52" />
</linearGradient>
<linearGradient
id="SVGID_2_"
gradientUnits="userSpaceOnUse"
x1="936.13898"
y1="154.45329"
x2="918.56207"
y2="154.45329"
gradientTransform="matrix(0.9669,0.2553,-0.2553,0.9669,-399.6603,-163.1002)">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop61" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop63" />
</linearGradient>
<linearGradient
id="SVGID_3_"
gradientUnits="userSpaceOnUse"
x1="451.01599"
y1="201.9489"
x2="442.73761"
y2="243.37801">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop72" />
<stop
offset="0.2568"
style="stop-color:#78BC98"
id="stop74" />
<stop
offset="0.5165"
style="stop-color:#6CB193"
id="stop76" />
<stop
offset="0.7767"
style="stop-color:#589F8C"
id="stop78" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop80" />
</linearGradient>
<linearGradient
id="SVGID_4_"
gradientUnits="userSpaceOnUse"
x1="457.62369"
y1="234.5722"
x2="457.47629"
y2="234.5722">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop87" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop89" />
</linearGradient>
<linearGradient
id="SVGID_5_"
gradientUnits="userSpaceOnUse"
x1="467.88159"
y1="223.4929"
x2="457.62369"
y2="223.4929">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop96" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop98" />
</linearGradient>
<linearGradient
id="SVGID_6_"
gradientUnits="userSpaceOnUse"
x1="457.47629"
y1="235.823"
x2="452.43719"
y2="235.823">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop105" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop107" />
</linearGradient>
<linearGradient
id="SVGID_7_"
gradientUnits="userSpaceOnUse"
x1="452.19159"
y1="227.27921"
x2="460.47461"
y2="227.27921">
<stop
offset="0"
style="stop-color:#6AA583"
id="stop112" />
<stop
offset="1"
style="stop-color:#4C9E96"
id="stop114" />
</linearGradient>
<linearGradient
id="SVGID_8_"
gradientUnits="userSpaceOnUse"
x1="473.17111"
y1="268.90411"
x2="455.23529"
y2="283.95389"
gradientTransform="matrix(0.9997,0.0227,-0.0227,0.9997,-36.4014,-7.9207)">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop119" />
<stop
offset="1"
style="stop-color:#57BAAE"
id="stop121" />
</linearGradient>
<linearGradient
id="SVGID_9_"
gradientUnits="userSpaceOnUse"
x1="447.13129"
y1="274.66199"
x2="470.95151"
y2="274.66199"
gradientTransform="matrix(0.9997,0.0227,-0.0227,0.9997,-36.4014,-7.9207)">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop126" />
<stop
offset="0.2327"
style="stop-color:#76BA97"
id="stop128" />
<stop
offset="0.5485"
style="stop-color:#65AB90"
id="stop130" />
<stop
offset="0.9106"
style="stop-color:#489186"
id="stop132" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop134" />
</linearGradient>
<linearGradient
id="SVGID_10_"
gradientUnits="userSpaceOnUse"
x1="415.2153"
y1="260.93829"
x2="422.0509"
y2="252.7919">
<stop
offset="0"
style="stop-color:#4C9E96"
id="stop141" />
<stop
offset="0.4859"
style="stop-color:#489790"
id="stop143" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop145" />
</linearGradient>
<linearGradient
id="SVGID_11_"
gradientUnits="userSpaceOnUse"
x1="425.60641"
y1="203.1666"
x2="393.7475"
y2="239.4308">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop152" />
<stop
offset="0.3183"
style="stop-color:#77BF9C"
id="stop154" />
<stop
offset="0.6757"
style="stop-color:#6ABDA3"
id="stop156" />
<stop
offset="1"
style="stop-color:#57BAAE"
id="stop158" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="83.996105"
inkscape:cy="141.02918"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="2792"
inkscape:window-height="1698"
inkscape:window-x="88"
inkscape:window-y="44"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid1085" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-143.41788,-709.27353)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1087"
width="256"
height="256"
x="143.41788"
y="709.27356" />
<g
transform="matrix(1.4440786,0,0,1.4440786,-333.76137,493.00519)"
id="g41">
<g
id="g43">
<linearGradient
id="linearGradient3548"
gradientUnits="userSpaceOnUse"
x1="369.02579"
y1="171.88429"
x2="441.68719"
y2="262.58051">
<stop
offset="0.1296"
style="stop-color:#7CC099"
id="stop3550" />
<stop
offset="0.3785"
style="stop-color:#6FB594"
id="stop3552" />
<stop
offset="0.835"
style="stop-color:#4E9688"
id="stop3554" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop3556" />
</linearGradient>
<path
style="fill:url(#SVGID_1_)"
inkscape:connector-curvature="0"
d="m 433.7,212.6 c -5.9,-10.1 -19,-17.9 -27.5,-21 -8.5,-3.2 -18,-10.1 -18,-10.1 -7.5,-5 -9.7,-9 -13.7,-14 -1.2,2.6 -2.2,5.8 -3,9.6 1.8,3.1 8.7,13.4 28.1,21.5 1.7,0.7 6.9,2.8 7,2.9 l 6.5,2.6 -6.7,-1.9 c -0.2,-0.1 -5.5,-1.6 -7.3,-2.2 -17.3,-6.3 -25,-15.1 -28,-19.9 -0.8,4.9 -1.1,10.6 -0.7,16.5 5.2,4.7 14,11 26.9,15.4 0.9,0.3 3.6,1.3 3.6,1.3 l 3.4,1.2 -3.5,-0.5 c -0.1,0 -3,-0.4 -4,-0.6 -12.1,-2.9 -20.5,-8.4 -26.1,-13.3 0.5,4.3 1.4,8.6 2.8,13 0.3,1 0.7,2.1 1.1,3 4.4,2 9.6,3.9 15.4,5.2 1.1,0.2 4.3,1.1 4.3,1.1 l 3.8,1 -4,-0.2 c -0.1,0 -3.4,-0.2 -4.5,-0.4 -5.1,-0.7 -9.8,-2 -13.9,-3.6 6.6,13.7 18.8,21.4 35.2,27.5 18.7,7 19.4,25 19.4,25 0,0 5.1,-3.8 9.6,-18.4 5.1,-16.2 -0.3,-30.6 -6.2,-40.7 z"
id="path54" />
</g>
<g
id="g56">
<g
id="g58">
<linearGradient
id="linearGradient3561"
gradientUnits="userSpaceOnUse"
x1="936.13898"
y1="154.45329"
x2="918.56207"
y2="154.45329"
gradientTransform="matrix(0.9669,0.2553,-0.2553,0.9669,-399.6603,-163.1002)">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop3563" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop3565" />
</linearGradient>
<path
style="fill:url(#SVGID_2_)"
inkscape:connector-curvature="0"
d="m 458.6,233.8 c 4.9,-3.6 6.9,-7.8 8.5,-12.5 0.7,-2.1 1.3,-5 0.3,-8.1 -0.8,-2.5 -6.5,-6.2 -11.2,-4.7 -5.1,1.7 -6.1,8.1 -6.5,10.9 -0.6,4.3 0.4,10.9 2.8,17.6 -0.1,0 2.1,-0.2 6.1,-3.2 z"
id="path65" />
</g>
<g
id="g67">
<g
id="g69">
<linearGradient
id="linearGradient3570"
gradientUnits="userSpaceOnUse"
x1="451.01599"
y1="201.9489"
x2="442.73761"
y2="243.37801">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop3572" />
<stop
offset="0.2568"
style="stop-color:#78BC98"
id="stop3574" />
<stop
offset="0.5165"
style="stop-color:#6CB193"
id="stop3576" />
<stop
offset="0.7767"
style="stop-color:#589F8C"
id="stop3578" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop3580" />
</linearGradient>
<path
style="fill:url(#SVGID_3_)"
inkscape:connector-curvature="0"
d="m 449.7,219.4 c 0.4,-2.8 1.4,-9.2 6.5,-10.9 4.2,-1.4 9.3,1.5 10.8,3.9 -1.5,-3.9 -5.6,-6.6 -9,-8.3 -4.8,-2.5 -10.8,-2.9 -15.7,-1.7 -4.6,1.1 -7,3.6 -10.9,6.9 0.8,1.1 1.6,2.2 2.2,3.3 4.6,8 9,18.6 8.2,30.6 3,-5 9.7,-6.1 10.6,-6.2 -2.4,-6.6 -3.4,-13.3 -2.7,-17.6 z"
id="path82" />
</g>
<g
id="g84">
<linearGradient
id="linearGradient3584"
gradientUnits="userSpaceOnUse"
x1="457.62369"
y1="234.5722"
x2="457.47629"
y2="234.5722">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop3586" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop3588" />
</linearGradient>
<path
style="fill:url(#SVGID_4_)"
inkscape:connector-curvature="0"
d="m 457.6,234.5 c -0.1,0 -0.1,0.1 -0.1,0.1 0,0 0.1,0 0.1,-0.1 z"
id="path91" />
</g>
<g
id="g93">
<linearGradient
id="linearGradient3592"
gradientUnits="userSpaceOnUse"
x1="467.88159"
y1="223.4929"
x2="457.62369"
y2="223.4929">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop3594" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop3596" />
</linearGradient>
<path
style="fill:url(#SVGID_5_)"
inkscape:connector-curvature="0"
d="m 467.4,213.2 c -0.1,-0.2 -0.2,-0.5 -0.4,-0.8 0.7,1.7 0.8,3.7 0.1,5.9 -1.5,4.9 -1.8,7.1 -6.1,12.9 -1,1.3 -2.2,2.4 -3.4,3.2 0.3,-0.2 0.6,-0.4 1,-0.7 4.9,-3.6 6.9,-7.8 8.5,-12.5 0.7,-2 1.2,-4.9 0.3,-8 z"
id="path100" />
</g>
<g
id="g102">
<linearGradient
id="linearGradient3600"
gradientUnits="userSpaceOnUse"
x1="457.47629"
y1="235.823"
x2="452.43719"
y2="235.823">
<stop
offset="0"
style="stop-color:#DBE6E0"
id="stop3602" />
<stop
offset="1"
style="stop-color:#BCDED3"
id="stop3604" />
</linearGradient>
<path
style="fill:url(#SVGID_6_)"
inkscape:connector-curvature="0"
d="m 452.4,237 c 0,0 0,0 0,0 0,0 1.8,-0.2 5,-2.4 -2.5,1.7 -4.9,2.4 -4.9,2.4 0,0 0,0 -0.1,0 z"
id="path109" />
</g>
</g>
<linearGradient
id="linearGradient3607"
gradientUnits="userSpaceOnUse"
x1="452.19159"
y1="227.27921"
x2="460.47461"
y2="227.27921">
<stop
offset="0"
style="stop-color:#6AA583"
id="stop3609" />
<stop
offset="1"
style="stop-color:#4C9E96"
id="stop3611" />
</linearGradient>
<path
style="fill:url(#SVGID_7_)"
inkscape:connector-curvature="0"
d="m 458.2,217.6 c -1,-0.3 -2,0 -2.8,0.6 -0.2,0.3 -0.3,0.6 -0.4,0.9 -0.4,1.6 0.5,3.3 2.2,3.7 0.7,0.2 1.3,0.1 1.9,-0.1 -0.9,6.9 -5.9,12.4 -6.9,13.5 0.1,0.4 0.2,0.5 0.2,0.7 0.3,0 0.4,-0.1 0.9,-0.2 1.7,-1.9 6.7,-7.9 7,-15.5 0.5,-1.5 -0.5,-3.1 -2.1,-3.6 z"
id="path116" />
</g>
<linearGradient
id="linearGradient3614"
gradientUnits="userSpaceOnUse"
x1="473.17111"
y1="268.90411"
x2="455.23529"
y2="283.95389"
gradientTransform="matrix(0.9997,0.0227,-0.0227,0.9997,-36.4014,-7.9207)">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop3616" />
<stop
offset="1"
style="stop-color:#57BAAE"
id="stop3618" />
</linearGradient>
<path
style="fill:url(#SVGID_8_)"
inkscape:connector-curvature="0"
d="m 405.5,261.4 c 1.5,12.7 7.5,31.7 27.8,47.9 0,0 10.1,-15.4 0.4,-32.5 -9.7,-17.1 -23.8,-22.7 -28.8,-24.5 -0.2,3.6 0.4,6.8 0.6,9.1 z"
id="path123" />
<linearGradient
id="linearGradient3621"
gradientUnits="userSpaceOnUse"
x1="447.13129"
y1="274.66199"
x2="470.95151"
y2="274.66199"
gradientTransform="matrix(0.9997,0.0227,-0.0227,0.9997,-36.4014,-7.9207)">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop3623" />
<stop
offset="0.2327"
style="stop-color:#76BA97"
id="stop3625" />
<stop
offset="0.5485"
style="stop-color:#65AB90"
id="stop3627" />
<stop
offset="0.9106"
style="stop-color:#489186"
id="stop3629" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop3631" />
</linearGradient>
<path
style="fill:url(#SVGID_9_)"
inkscape:connector-curvature="0"
d="m 423.7,272.8 c -5.7,-10 -12.8,-16.8 -18.8,-20.5 -0.1,3.2 0.4,7 0.6,9.1 1.2,10.8 5.8,26.1 19.6,40.4 2.4,-5.5 5.5,-16.8 -1.4,-29 z"
id="path136" />
<g
id="g138">
<linearGradient
id="linearGradient3635"
gradientUnits="userSpaceOnUse"
x1="415.2153"
y1="260.93829"
x2="422.0509"
y2="252.7919">
<stop
offset="0"
style="stop-color:#4C9E96"
id="stop3637" />
<stop
offset="0.4859"
style="stop-color:#489790"
id="stop3639" />
<stop
offset="1"
style="stop-color:#408A83"
id="stop3641" />
</linearGradient>
<path
style="fill:url(#SVGID_10_)"
inkscape:connector-curvature="0"
d="m 411.9,246.7 c -2,-0.8 -4.9,-1.6 -6.8,-2.4 -0.3,2.5 -0.2,5.1 -0.2,8.1 4.4,1.6 16.1,6.2 25.5,19.3 0,-0.1 0,-0.2 0,-0.3 -0.2,-2.3 -1.1,-18.3 -18.5,-24.7 z"
id="path147" />
</g>
<g
id="g149">
<linearGradient
id="linearGradient3645"
gradientUnits="userSpaceOnUse"
x1="425.60641"
y1="203.1666"
x2="393.7475"
y2="239.4308">
<stop
offset="0"
style="stop-color:#7CC099"
id="stop3647" />
<stop
offset="0.3183"
style="stop-color:#77BF9C"
id="stop3649" />
<stop
offset="0.6757"
style="stop-color:#6ABDA3"
id="stop3651" />
<stop
offset="1"
style="stop-color:#57BAAE"
id="stop3653" />
</linearGradient>
<path
style="fill:url(#SVGID_11_)"
inkscape:connector-curvature="0"
d="m 433.7,212.6 c -5.9,-10.1 -19,-17.9 -27.5,-21 -8.5,-3.2 -18,-10.1 -18,-10.1 -2.1,-1.4 -3.8,-2.7 -5.2,-4 -0.4,3.6 -0.6,7.5 -0.4,11.6 4.2,3.2 9.7,6.5 16.9,9.5 1.7,0.7 6.9,2.8 7,2.9 l 6.5,2.6 -6.7,-1.9 c -0.2,-0.1 -5.5,-1.6 -7.3,-2.2 -6.8,-2.5 -12.1,-5.3 -16.2,-8.2 0.4,5 1.3,10.1 2.9,15.2 3.4,1.8 7.2,3.4 11.6,4.9 0.9,0.3 3.6,1.3 3.6,1.3 l 3.4,1.2 -3.5,-0.5 c -0.1,0 -3,-0.4 -4,-0.6 -3.7,-0.9 -7,-2 -10,-3.3 1.9,4.8 4.4,8.8 7.4,12.3 0.1,0 0.1,0 0.1,0 l 3.8,1 -3.2,-0.2 c 6.9,7.7 16.3,13.3 26.3,21.3 13.5,10.8 9.2,27.2 9.2,27.2 0,0 0.8,-0.6 1.5,-1.5 1.8,-2.1 5.1,-7 8.1,-16.9 5,-16.1 -0.4,-30.5 -6.3,-40.6 z"
id="path160" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -7,9 +7,13 @@
"nymea-app": {
"apparmor": "nymea-app.apparmor",
"desktop": "nymea-app.desktop"
},
"push": {
"apparmor": "push-apparmor.json",
"push-helper": "push.json"
}
},
"version": "developer-build",
"version": "0",
"maintainer": "Michael Zanetti <michael.zanetti@nymea.io>",
"framework" : "ubuntu-sdk-15.04.5"
"framework" : "ubuntu-sdk-16.04"
}

View File

@ -0,0 +1,7 @@
{
"template": "ubuntu-push-helper",
"policy_groups": [
"push-notification-client"
],
"policy_version": 16.04
}

View File

@ -0,0 +1,4 @@
{
"exec": "pushexec"
}

19
packaging/ubuntu/click/pushexec Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/python3
import os
import sys
import json
f1, f2 = sys.argv[1:3]
payloadJson = json.load(open(f1))
dir_path = os.path.dirname(os.path.realpath(__file__))
payloadJson["notification"]["card"]["icon"] = dir_path + "/appicon.svg"
payloadJson["notification"]["card"]["actions"] = ["appid://io.guh.nymeaapp/nymea-app/current-user-version"]
#payloadJson["notification"]["emblem-counter"] = {"count": 1, "visible": True }
print(payloadJson)
open(f2, "w").write(json.dumps(payloadJson) + "\n")