diff --git a/src/libsnore/notification/icon_p.cpp b/src/libsnore/notification/icon_p.cpp index 5d904dc..2122cf1 100644 --- a/src/libsnore/notification/icon_p.cpp +++ b/src/libsnore/notification/icon_p.cpp @@ -49,9 +49,9 @@ IconData::IconData(const QString &url): QNetworkAccessManager *manager = new QNetworkAccessManager(); QNetworkRequest request(m_url); QNetworkReply *reply = manager->get(request); - QObject::connect(reply, &QNetworkReply::downloadProgress, [&](qint64 bytesReceived, qint64 bytesTotal) { - snoreDebug(SNORE_DEBUG) << "Downloading:" << m_localUrl << bytesReceived / double(bytesTotal) * 100.0 << "%"; - }); +// QObject::connect(reply, &QNetworkReply::downloadProgress, [&](qint64 bytesReceived, qint64 bytesTotal) { +// snoreDebug(SNORE_DEBUG) << "Downloading:" << m_localUrl << bytesReceived / double(bytesTotal) * 100.0 << "%"; +// }); QObject::connect(reply, static_cast(&QNetworkReply::error), [ &, reply, manager](QNetworkReply::NetworkError code) { snoreDebug(SNORE_WARNING) << "Error:" << code; diff --git a/src/libsnore/plugins/snorefrontend.cpp b/src/libsnore/plugins/snorefrontend.cpp index bdb46d0..be7a574 100644 --- a/src/libsnore/plugins/snorefrontend.cpp +++ b/src/libsnore/plugins/snorefrontend.cpp @@ -45,3 +45,13 @@ bool SnoreFrontend::deinitialize() } return false; } + +void SnoreFrontend::slotActionInvoked(Notification) +{ + +} + +void SnoreFrontend::slotNotificationClosed(Notification) +{ + +} diff --git a/src/libsnore/plugins/snorefrontend.h b/src/libsnore/plugins/snorefrontend.h index 5d300b1..0f176f7 100644 --- a/src/libsnore/plugins/snorefrontend.h +++ b/src/libsnore/plugins/snorefrontend.h @@ -38,8 +38,8 @@ public: virtual bool deinitialize() override; public slots: - virtual void slotActionInvoked(Snore::Notification notification) = 0; - virtual void slotNotificationClosed(Snore::Notification notification) = 0; + virtual void slotActionInvoked(Snore::Notification notification); + virtual void slotNotificationClosed(Snore::Notification notification); }; } diff --git a/src/plugins/frontends/CMakeLists.txt b/src/plugins/frontends/CMakeLists.txt index e49df42..2235575 100644 --- a/src/plugins/frontends/CMakeLists.txt +++ b/src/plugins/frontends/CMakeLists.txt @@ -1,5 +1,6 @@ if(WITH_FRONTENDS) add_subdirectory(freedesktop) add_subdirectory(snarlnetwork) + add_subdirectory(pushover) #add_subdirectory(snp3) endif() diff --git a/src/plugins/frontends/pushover/CMakeLists.txt b/src/plugins/frontends/pushover/CMakeLists.txt new file mode 100644 index 0000000..f701e4a --- /dev/null +++ b/src/plugins/frontends/pushover/CMakeLists.txt @@ -0,0 +1,9 @@ +find_package(Qt5WebSockets REQUIRED) + +set( PUSHOVER_FRONTEND_SRC + pushover_frontend.cpp + ) + +add_library(libsnore_frontend_pushover MODULE ${PUSHOVER_FRONTEND_SRC} ) +target_link_libraries(libsnore_frontend_pushover Snore::Libsnore Qt5::WebSockets ) + diff --git a/src/plugins/frontends/pushover/plugin.json b/src/plugins/frontends/pushover/plugin.json new file mode 100644 index 0000000..5c9a046 --- /dev/null +++ b/src/plugins/frontends/pushover/plugin.json @@ -0,0 +1 @@ +{ "type" : "frontend", "name" : "Pushover Frontend" } \ No newline at end of file diff --git a/src/plugins/frontends/pushover/pushover_frontend.cpp b/src/plugins/frontends/pushover/pushover_frontend.cpp new file mode 100644 index 0000000..baf17f4 --- /dev/null +++ b/src/plugins/frontends/pushover/pushover_frontend.cpp @@ -0,0 +1,172 @@ +/* + SnoreNotify is a Notification Framework based on Qt + Copyright (C) 2013-2014 Patrick von Reth + + SnoreNotify is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SnoreNotify 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 SnoreNotify. If not, see . +*/ + +#include "pushover_frontend.h" + +#include "libsnore/snore.h" +#include "libsnore/version.h" +#include "libsnore/notification/notification_p.h" + + +#include +#include +#include +#include +#include +#include +#include + +using namespace Snore; + +bool PushoverFrontend::initialize() +{ + setDefaultValue("Secret", "", LOCAL_SETTING); + setDefaultValue("Device", "", LOCAL_SETTING); + + if(device().isEmpty() || secret().isEmpty()) + { + return false; + } + m_socket = new QWebSocket("", QWebSocketProtocol::VersionLatest, this); + + connect(m_socket, &QWebSocket::binaryMessageReceived, [&](const QByteArray &msg){ + qDebug() << "bin message" << msg; + char c = msg.at(0); + switch(c){ + case '#': + snoreDebug(SNORE_DEBUG) << "still alive"; + break; + case '!': + getMessages(); + break; + case 'R': + // TODO: implement + snoreDebug(SNORE_DEBUG) << "need to reconnect"; + break; + case 'E': + snoreDebug(SNORE_DEBUG) << "Connection Error"; + m_socket->close(); + m_socket->deleteLater(); + break; + } + }); + connect(m_socket, &QWebSocket::disconnected, [](){ + qDebug() << "disconnected"; + }); + connect(m_socket, static_cast(&QWebSocket::error), [&](QAbstractSocket::SocketError error){ + qDebug() << error << m_socket->errorString(); + }); + connect(m_socket, &QWebSocket::connected, [&](){ + qDebug() << "connect" << m_socket->sendBinaryMessage(QString("login:%1:%2\n").arg(device(), secret()).toUtf8().constData()); + + // TODO: how to delay until snore is initialized? + getMessages(); + }); + m_socket->open(QUrl("wss://client.pushover.net/push")); + return SnoreFrontend::initialize(); + +} + +bool PushoverFrontend::deinitialize() +{ + if (SnoreFrontend::deinitialize()) { + m_socket->close(); + m_socket->deleteLater(); + return true; + } + return false; +} + +QString PushoverFrontend::secret() +{ + return value("Secret", LOCAL_SETTING).toString(); +} + +QString PushoverFrontend::device() +{ + return value("Device", LOCAL_SETTING).toString(); +} + +void PushoverFrontend::getMessages() +{ + QNetworkRequest request(QUrl(QString("https://api.pushover.net/1/messages.json?" + "secret=%1&device_id=%2").arg(secret(), device()))); + QNetworkReply *reply = m_manager.get(request); + + + connect(reply, &QNetworkReply::finished, [reply,this]() { + snoreDebug(SNORE_DEBUG) << reply->error(); + QByteArray input = reply->readAll(); + reply->close(); + reply->deleteLater(); + + qDebug() << input; + + QJsonObject message = QJsonDocument::fromJson(input).object(); + + int latestID = -1; + if(message.value("status").toInt() == 1){ + QJsonArray notifications = message.value("messages").toArray(); + for( const QJsonValue &v : notifications) { + QJsonObject notification = v.toObject(); + + latestID = notification.value("id").toInt(); + + QString appName = notification.value("app").toString(); + Application app = SnoreCore::instance().aplications().value(appName); + + if (!app.isValid()){ + Icon icon(QString("https://api.pushover.net/icons/%1.png").arg(notification.value("icon").toString())); + app = Application(appName, icon); + app.addAlert(Alert("Default", icon)); + if(notification.value("html").toInt() == 1) { + app.hints().setValue("use-markup", QVariant::fromValue(true)) ; + } + SnoreCore::instance().registerApplication(app); + } + + + Notification n(app, *app.alerts().begin(), notification.value("title").toString(), notification.value("message").toString(), + app.icon(), Notification::defaultTimeout(), static_cast(notification.value("priority").toInt())); + SnoreCore::instance().broadcastNotification(n); + } + if(latestID != -1){ + deleteMessages(latestID); + } + } + }); + +} + +void PushoverFrontend::deleteMessages(int latestMessageId) +{ + + QNetworkRequest request(QUrl(QString("https://api.pushover.net/1/devices/%1/update_highest_message.json").arg(device()))); + + request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); + QNetworkReply *reply = m_manager.post(request, QString("secret=%1&message=%2").arg(secret(), QString::number(latestMessageId)).toUtf8().constData()); + + + connect(reply, &QNetworkReply::finished, [reply]() { + snoreDebug(SNORE_DEBUG) << reply->error(); + snoreDebug(SNORE_DEBUG) << reply->readAll(); + reply->close(); + reply->deleteLater(); + }); +} + diff --git a/src/plugins/frontends/pushover/pushover_frontend.h b/src/plugins/frontends/pushover/pushover_frontend.h new file mode 100644 index 0000000..4f71afa --- /dev/null +++ b/src/plugins/frontends/pushover/pushover_frontend.h @@ -0,0 +1,52 @@ +/* + SnoreNotify is a Notification Framework based on Qt + Copyright (C) 2013-2014 Patrick von Reth + + SnoreNotify is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + SnoreNotify 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 SnoreNotify. If not, see . +*/ + +#ifndef PUSHOVER_FRONTEND_H +#define PUSHOVER_FRONTEND_H +#include "libsnore/plugins/snorefrontend.h" +#include "libsnore/application.h" + +#include + +class QWebSocket; + +class PushoverFrontend : public Snore::SnoreFrontend +{ + Q_OBJECT + Q_INTERFACES(Snore::SnoreFrontend) + Q_PLUGIN_METADATA(IID "org.Snore.NotificationFrontend/1.0" FILE "plugin.json") +public: + PushoverFrontend() = default; + ~PushoverFrontend() = default; + bool initialize() override; + bool deinitialize() override; + + +private: + QNetworkAccessManager m_manager; + QWebSocket *m_socket; + + QString secret(); + QString device(); + + void getMessages(); + void deleteMessages(int latestMessageId); + +}; + +#endif//PUSHOVER_FRONTEND_H