mirror of
https://github.com/status-im/snorenotify.git
synced 2025-02-10 07:26:22 +00:00
implemented gntp callbacks
This commit is contained in:
parent
d0956594a9
commit
6cdd6504a5
@ -15,7 +15,7 @@ endif(KDE4_FOUND)
|
||||
|
||||
|
||||
find_package( CryptoPP )
|
||||
find_package( Boost COMPONENTS system )
|
||||
find_package( Boost COMPONENTS system thread)
|
||||
|
||||
|
||||
option(WITH_FREEDESKTOP_FRONTEND "Build the freedesktop frontend" OFF)
|
||||
|
@ -22,7 +22,6 @@ Application::Application (const QString &name, const SnoreIcon &icon) :
|
||||
_icon(icon),
|
||||
_initialized ( false )
|
||||
{
|
||||
_alerts.insert ( "",new Alert ( "Default Alert","Default Alert" ) );
|
||||
}
|
||||
|
||||
Application::Application() :
|
||||
|
@ -45,6 +45,9 @@ public:
|
||||
virtual ~Notification_Backend();
|
||||
virtual bool isPrimaryNotificationBackend() =0;
|
||||
|
||||
protected:
|
||||
QHash<uint,Notification> activeNotifications;
|
||||
|
||||
public slots:
|
||||
virtual void registerApplication ( class Application *application ) =0;
|
||||
virtual void unregisterApplication ( class Application *application ) =0;
|
||||
@ -64,6 +67,9 @@ public:
|
||||
virtual ~Notification_Frontend();
|
||||
virtual void actionInvoked (Notification notification )=0;
|
||||
virtual void notificationClosed ( Notification notification )=0;
|
||||
|
||||
protected:
|
||||
QHash<uint,Notification> activeNotifications;
|
||||
};
|
||||
|
||||
|
||||
|
@ -23,9 +23,6 @@
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
QHash<QString,QString> SnoreIcon::hasedImages;
|
||||
|
||||
class SnoreIcon::SnoreIconData
|
||||
{
|
||||
public:
|
||||
@ -65,6 +62,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
QHash<QString,QString> SnoreIcon::hasedImages;
|
||||
|
||||
SnoreIcon::SnoreIcon()
|
||||
{
|
||||
d = QSharedPointer<SnoreIconData>(new SnoreIconData());
|
||||
|
@ -24,8 +24,7 @@
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QTextDocument>
|
||||
|
||||
|
||||
|
||||
static int metaid = qRegisterMetaType<Notification>();
|
||||
|
||||
class Notification::NotificationData
|
||||
{
|
||||
@ -72,7 +71,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
int Notification::DefaultTimeout=10;
|
||||
int Notification::DefaultTimeout = 10;
|
||||
|
||||
QString Notification::toPlainText ( const QString &string )
|
||||
{
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
|
||||
const uint &id() const;
|
||||
void setId(const uint &id);
|
||||
//timeout in seconds
|
||||
const int &timeout() const;
|
||||
//void setActionInvoked ( const Notification::defaultActions &action );
|
||||
void setActionInvoked ( Action *action );
|
||||
@ -100,6 +101,7 @@ private:
|
||||
QSharedPointer<NotificationData> d;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Notification)
|
||||
|
||||
QDataStream & operator<< ( QDataStream & stream, const Notification & noti );
|
||||
QDataStream & operator<< ( QDataStream & stream, const Notification::Action & action);
|
||||
|
@ -32,10 +32,7 @@ public:
|
||||
void CloseNotification( uint id );
|
||||
|
||||
QStringList GetCapabilities();
|
||||
QString GetServerInformation(QString& vendor, QString& version, QString& specVersion);
|
||||
|
||||
private:
|
||||
QHash<uint,Notification> activeNotifications;
|
||||
QString GetServerInformation(QString& vendor, QString& version, QString& specVersion);
|
||||
|
||||
signals:
|
||||
void NotificationClosed( uint id, uint reason );
|
||||
|
@ -6,7 +6,7 @@ if( WITH_GROWL_BACKEND )
|
||||
)
|
||||
|
||||
automoc4_add_library(growl_backend MODULE ${GROWL__SRC} )
|
||||
target_link_libraries(growl_backend snorecore ${QT_QTCORE_LIBRARY} ${CRYPTOPP_LIBRARIES} ${Boost_SYSTEM_LIBRARY} wsock32 ws2_32)
|
||||
target_link_libraries(growl_backend snorecore ${QT_QTCORE_LIBRARY} ${CRYPTOPP_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} wsock32 ws2_32)
|
||||
|
||||
install(TARGETS growl_backend ${PLUGIN_INSTALL_PATH})
|
||||
else(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
|
||||
|
@ -19,9 +19,57 @@
|
||||
#include <cryptopp/modes.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
class gntp {
|
||||
public:
|
||||
typedef void (*gntp_callback)(const int& id,const std::string& reason,const std::string& data) ;
|
||||
private:
|
||||
class callback_reciver{
|
||||
public:
|
||||
boost::asio::ip::tcp::iostream sock;
|
||||
boost::thread *thread;
|
||||
gntp_callback callback;
|
||||
callback_reciver(std::string host,std::string port,gntp_callback callback):
|
||||
sock(host, port),
|
||||
thread(NULL),
|
||||
callback(callback)
|
||||
{}
|
||||
|
||||
~callback_reciver(){
|
||||
if(thread)
|
||||
thread->interrupt();
|
||||
delete thread;
|
||||
sock.close();
|
||||
}
|
||||
|
||||
void wait_for_callback(){
|
||||
std::string line;
|
||||
int id = 0;
|
||||
std::string result;
|
||||
std::string data;
|
||||
while (std::getline(sock, line)) {
|
||||
boost::trim(line);
|
||||
//std::cout << "[" << line << "]" << std::endl;
|
||||
if (line.find("Notification-ID: ") == 0) id = atoi(line.substr(17).c_str());
|
||||
else if(line.find("Notification-Callback-Result: ") == 0) result = line.substr(30);
|
||||
else if(line.find("Notification-Callback-Context: ") == 0) data = line.substr(31);
|
||||
else if(line == "\r")break;
|
||||
}
|
||||
//std::cout << "[id: " << id <<" reason: "<< result << " data: " << data << "]" << std::endl;
|
||||
callback(id,result,data);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void run(){
|
||||
if(!callback)
|
||||
return;
|
||||
thread = new boost::thread( boost::bind(&callback_reciver::wait_for_callback, this) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static inline std::string to_hex(CryptoPP::SecByteBlock& in) {
|
||||
std::string out;
|
||||
CryptoPP::HexEncoder hex( NULL, true, 2, "" );
|
||||
@ -33,113 +81,118 @@ private:
|
||||
static std::string sanitize_text(std::string name) {
|
||||
std::string::size_type n = 0;
|
||||
while((n = name.find("\r\n", n)) != std::string::npos)
|
||||
name.erase(n, 1);
|
||||
name.erase(n, 1);
|
||||
return name;
|
||||
}
|
||||
|
||||
static std::string sanitize_name(std::string name) {
|
||||
std::string::size_type n = 0;
|
||||
while((n = name.find("-", n)) != std::string::npos)
|
||||
name.erase(n, 1);
|
||||
name.erase(n, 1);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
static void recv(boost::asio::ip::tcp::iostream& sock) throw (std::runtime_error) {
|
||||
std::string error;
|
||||
while (1) {
|
||||
std::string line;
|
||||
if (!std::getline(sock, line)) break;
|
||||
std::string line;
|
||||
if (!std::getline(sock, line)) break;
|
||||
|
||||
//std::cout << "[" << line << "]" << std::endl;
|
||||
if (line.find("GNTP/1.0 -ERROR") == 0) error = "unknown error";
|
||||
if (line.find("Error-Description: ") == 0) error = line.substr(19);
|
||||
if (line == "\r") break;
|
||||
//std::cout << "[" << line << "]" << std::endl;
|
||||
if (line.find("GNTP/1.0 -ERROR") == 0) error = "unknown error";
|
||||
if (line.find("Error-Description: ") == 0) error = line.substr(19);
|
||||
if (line == "\r") break;
|
||||
}
|
||||
if (!error.empty()) throw std::range_error(error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
|
||||
boost::asio::ip::tcp::iostream sock(hostname_, port_);
|
||||
if (!sock) throw std::range_error("can't connect to host");
|
||||
callback_reciver * send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
|
||||
callback_reciver *cbr = new callback_reciver(hostname_, port_,callback_);
|
||||
if (!cbr->sock) throw std::range_error("can't connect to host");
|
||||
|
||||
if (!password_.empty()) {
|
||||
// initialize salt and iv
|
||||
CryptoPP::SecByteBlock salt(8);
|
||||
rng.GenerateBlock(salt.begin(), salt.size());
|
||||
// initialize salt and iv
|
||||
CryptoPP::SecByteBlock salt(8);
|
||||
rng.GenerateBlock(salt.begin(), salt.size());
|
||||
|
||||
// get digest of password+salt hex encoded
|
||||
CryptoPP::SecByteBlock passtext(CryptoPP::Weak1::MD5::DIGESTSIZE);
|
||||
CryptoPP::Weak1::MD5 hash;
|
||||
hash.Update((byte*)password_.c_str(), password_.size());
|
||||
hash.Update(salt.begin(), salt.size());
|
||||
hash.Final(passtext);
|
||||
CryptoPP::SecByteBlock digest(CryptoPP::Weak1::MD5::DIGESTSIZE);
|
||||
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
|
||||
// get digest of password+salt hex encoded
|
||||
CryptoPP::SecByteBlock passtext(CryptoPP::Weak1::MD5::DIGESTSIZE);
|
||||
CryptoPP::Weak1::MD5 hash;
|
||||
hash.Update((byte*)password_.c_str(), password_.size());
|
||||
hash.Update(salt.begin(), salt.size());
|
||||
hash.Final(passtext);
|
||||
CryptoPP::SecByteBlock digest(CryptoPP::Weak1::MD5::DIGESTSIZE);
|
||||
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
|
||||
|
||||
sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE "
|
||||
<< " " <<
|
||||
cbr->sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE "
|
||||
<< " " <<
|
||||
sanitize_name(CryptoPP::Weak1::MD5::StaticAlgorithmName())
|
||||
<< ":" << to_hex(digest) << "." << to_hex(salt)
|
||||
<< "\r\n"
|
||||
<< stm.str() << "\r\n\r\n";
|
||||
<< "\r\n"
|
||||
<< stm.str() << "\r\n\r\n";
|
||||
} else {
|
||||
sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE\r\n"
|
||||
<< stm.str() << "\r\n";
|
||||
cbr->sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE\r\n"
|
||||
<< stm.str() << "\r\n";
|
||||
}
|
||||
recv(sock);
|
||||
recv(cbr->sock);
|
||||
return cbr;
|
||||
}
|
||||
|
||||
template<class CIPHER_TYPE, class HASH_TYPE>
|
||||
void send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
|
||||
boost::asio::ip::tcp::iostream sock(hostname_, port_);
|
||||
if (!sock) throw std::range_error("can't connect to host");
|
||||
callback_reciver *send(const char* method, std::stringstream& stm) throw (std::runtime_error) {
|
||||
callback_reciver *cbr = new callback_reciver(hostname_, port_,callback_);
|
||||
if (!cbr->sock) throw std::range_error("can't connect to host");
|
||||
|
||||
if (!password_.empty()) {
|
||||
// initialize salt and iv
|
||||
CryptoPP::SecByteBlock salt(HASH_TYPE::DIGESTSIZE), iv(CIPHER_TYPE::BLOCKSIZE);
|
||||
rng.GenerateBlock(salt.begin(), salt.size());
|
||||
rng.GenerateBlock(iv.begin(), iv.size());
|
||||
// initialize salt and iv
|
||||
CryptoPP::SecByteBlock salt(HASH_TYPE::DIGESTSIZE), iv(CIPHER_TYPE::BLOCKSIZE);
|
||||
rng.GenerateBlock(salt.begin(), salt.size());
|
||||
rng.GenerateBlock(iv.begin(), iv.size());
|
||||
|
||||
// get digest of password+salt hex encoded
|
||||
CryptoPP::SecByteBlock passtext(HASH_TYPE::DIGESTSIZE);
|
||||
HASH_TYPE hash;
|
||||
hash.Update((byte*)password_.c_str(), password_.size());
|
||||
hash.Update(salt.begin(), salt.size());
|
||||
hash.Final(passtext);
|
||||
CryptoPP::SecByteBlock digest(HASH_TYPE::DIGESTSIZE);
|
||||
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
|
||||
// get digest of password+salt hex encoded
|
||||
CryptoPP::SecByteBlock passtext(HASH_TYPE::DIGESTSIZE);
|
||||
HASH_TYPE hash;
|
||||
hash.Update((byte*)password_.c_str(), password_.size());
|
||||
hash.Update(salt.begin(), salt.size());
|
||||
hash.Final(passtext);
|
||||
CryptoPP::SecByteBlock digest(HASH_TYPE::DIGESTSIZE);
|
||||
hash.CalculateDigest(digest.begin(), passtext.begin(), passtext.size());
|
||||
|
||||
class CryptoPP::CBC_Mode<CIPHER_TYPE>::Encryption
|
||||
encryptor(passtext.begin(), iv.size(), iv.begin());
|
||||
class CryptoPP::CBC_Mode<CIPHER_TYPE>::Encryption
|
||||
encryptor(passtext.begin(), iv.size(), iv.begin());
|
||||
|
||||
std::string cipher_text;
|
||||
CryptoPP::StringSource(stm.str(), true,
|
||||
new CryptoPP::StreamTransformationFilter(encryptor,
|
||||
new CryptoPP::StringSink(cipher_text)
|
||||
) // StreamTransformationFilter
|
||||
); // StringSource
|
||||
std::string cipher_text;
|
||||
CryptoPP::StringSource(stm.str(), true,
|
||||
new CryptoPP::StreamTransformationFilter(encryptor,
|
||||
new CryptoPP::StringSink(cipher_text)
|
||||
) // StreamTransformationFilter
|
||||
); // StringSource
|
||||
|
||||
sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " "
|
||||
cbr->sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " "
|
||||
<< sanitize_name(CIPHER_TYPE::StaticAlgorithmName())
|
||||
<< ":" << to_hex(iv)
|
||||
<< " "
|
||||
<< " "
|
||||
<< sanitize_name(HASH_TYPE::StaticAlgorithmName())
|
||||
<< ":" << to_hex(digest) << "." << to_hex(salt)
|
||||
<< "\r\n"
|
||||
<< cipher_text << "\r\n\r\n";
|
||||
<< "\r\n"
|
||||
<< cipher_text << "\r\n\r\n";
|
||||
} else {
|
||||
sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE\r\n"
|
||||
<< stm.str() << "\r\n";
|
||||
cbr->sock << "GNTP/1.0 "
|
||||
<< method
|
||||
<< " NONE\r\n"
|
||||
<< stm.str() << "\r\n";
|
||||
}
|
||||
recv(sock);
|
||||
recv(cbr->sock);
|
||||
return cbr;
|
||||
}
|
||||
|
||||
void make_regist(std::stringstream& stm, const char* name) {
|
||||
@ -149,11 +202,17 @@ private:
|
||||
stm << "\r\n";
|
||||
}
|
||||
|
||||
void make_notify(std::stringstream& stm, const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) {
|
||||
void make_notify(std::stringstream& stm, const char* name, const int id,const char* title, const char* text, const char* icon = NULL, const char* url = NULL,const char *callbackid = NULL) {
|
||||
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
|
||||
stm << "Notification-Name: " << sanitize_text(name) << "\r\n";
|
||||
stm << "Notification-ID: " << id <<"\r\n";
|
||||
if (icon) stm << "Notification-Icon: " << sanitize_text(icon) << "\r\n";
|
||||
if (url) stm << "Notification-Callback-Target: " << sanitize_text(url) << "\r\n";
|
||||
if (url){
|
||||
stm << "Notification-Callback-Target: " << sanitize_text(url) << "\r\n";
|
||||
}else if(callbackid){
|
||||
stm << "Notification-Callback-Context: "<< sanitize_text(callbackid) <<"\r\n";
|
||||
stm << "Notification-Callback-Context-Type: string\r\n";
|
||||
}
|
||||
stm << "Notification-Title: " << sanitize_text(title) << "\r\n";
|
||||
stm << "Notification-Text: " << sanitize_text(text) << "\r\n";
|
||||
stm << "\r\n";
|
||||
@ -165,74 +224,89 @@ private:
|
||||
std::string password_;
|
||||
std::string icon_;
|
||||
CryptoPP::AutoSeededRandomPool rng;
|
||||
gntp_callback callback_;
|
||||
|
||||
public:
|
||||
|
||||
gntp(std::string application = "gntp-send", std::string icon = "" ,std::string password = "",
|
||||
std::string hostname = "localhost", std::string port = "23053") :
|
||||
application_(application),
|
||||
std::string hostname = "localhost", std::string port = "23053") :
|
||||
application_(application),
|
||||
password_(password),
|
||||
hostname_(hostname),
|
||||
port_(port),
|
||||
icon_(icon){ }
|
||||
icon_(icon),
|
||||
callback_(NULL){ }
|
||||
|
||||
|
||||
void set_gntp_callback(gntp_callback callback){
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void regist(const char* name) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Notifications-Count: 1\r\n";
|
||||
stm << "\r\n";
|
||||
make_regist(stm, name);
|
||||
send("REGISTER", stm);
|
||||
callback_reciver *cbr = send("REGISTER", stm);
|
||||
delete cbr;
|
||||
}
|
||||
|
||||
void regist(const std::vector<std::string> names) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Notifications-Count: " << names.size() << "\r\n";
|
||||
stm << "\r\n";
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = names.begin(); it != names.end(); it++) {
|
||||
make_regist(stm, it->c_str());
|
||||
make_regist(stm, it->c_str());
|
||||
}
|
||||
send("REGISTER", stm);
|
||||
callback_reciver *cbr = send("REGISTER", stm);
|
||||
delete cbr;
|
||||
}
|
||||
|
||||
template<class CIPHER_TYPE, class HASH_TYPE>
|
||||
void regist(const char* name) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Notifications-Count: 1\r\n";
|
||||
stm << "\r\n";
|
||||
make_regist(stm, name);
|
||||
send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
|
||||
callback_reciver *cbr = send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
|
||||
delete cbr;
|
||||
}
|
||||
|
||||
template<class CIPHER_TYPE, class HASH_TYPE>
|
||||
void regist(const std::vector<std::string> names) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
stm << "Application-Name: " << sanitize_text(application_) << "\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Application-Icon: " << sanitize_text(icon_) <<"\r\n";
|
||||
stm << "Notifications-Count: " << names.size() << "\r\n";
|
||||
stm << "\r\n";
|
||||
std::vector<std::string>::const_iterator it;
|
||||
for (it = names.begin(); it != names.end(); it++) {
|
||||
make_regist(stm, it->c_str());
|
||||
make_regist(stm, it->c_str());
|
||||
}
|
||||
send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
|
||||
callback_reciver *cbr = send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
|
||||
delete cbr;
|
||||
}
|
||||
|
||||
void notify(const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) throw (std::runtime_error) {
|
||||
void notify(const char* name,const int id, const char* title, const char* text, const char* icon = NULL, const char* url = NULL,const char *callbackid = NULL) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
make_notify(stm, name, title, text, icon, url);
|
||||
send("NOTIFY", stm);
|
||||
make_notify(stm, name, id, title, text, icon, url,callbackid);
|
||||
callback_reciver *cbr = send("NOTIFY", stm);
|
||||
cbr->run();
|
||||
}
|
||||
|
||||
template<class CIPHER_TYPE, class HASH_TYPE>
|
||||
void notify(const char* name, const char* title, const char* text, const char* icon = NULL, const char* url = NULL) throw (std::runtime_error) {
|
||||
void notify(const char* name,const int id, const char* title, const char* text, const char* icon = NULL, const char* url = NULL,const char *callbackid = NULL) throw (std::runtime_error) {
|
||||
std::stringstream stm;
|
||||
make_notify(stm, name, title, text, icon, url);
|
||||
send<CIPHER_TYPE, HASH_TYPE>("NOTIFY", stm);
|
||||
make_notify(stm, name, id, title, text, icon, url,callbackid);
|
||||
callback_reciver *cbr = send<CIPHER_TYPE, HASH_TYPE>("NOTIFY", stm);
|
||||
cbr->run();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,14 +22,17 @@
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
|
||||
Q_EXPORT_PLUGIN2(growl_backend,Growl_Backend)
|
||||
|
||||
Growl_Backend::Growl_Backend(SnoreServer *snore):
|
||||
Growl_Backend *Growl_Backend::instance = NULL;
|
||||
|
||||
Growl_Backend::Growl_Backend(SnoreServer *snore):
|
||||
Notification_Backend("Growl",snore),
|
||||
id(0)
|
||||
_id(0)
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
Growl_Backend::~Growl_Backend(){
|
||||
foreach(Application *a,this->snore()->aplications().values()){
|
||||
@ -42,6 +45,9 @@ Growl_Backend::~Growl_Backend(){
|
||||
void Growl_Backend::registerApplication(Application *application){
|
||||
gntp *growl = new gntp(application->name().toUtf8().constData(),application->icon().localUrl().toUtf8().constData());
|
||||
|
||||
|
||||
gntp::gntp_callback callback(&gntpCallback);
|
||||
growl->set_gntp_callback(callback);
|
||||
std::vector<std::string> alerts;
|
||||
foreach(Alert *a,application->alerts()){
|
||||
alerts.push_back(a->name().toUtf8().constData());
|
||||
@ -66,20 +72,42 @@ int Growl_Backend::notify(Notification notification){
|
||||
gntp *growl = _applications.value(notification.application());
|
||||
if(growl == NULL)
|
||||
return -1;
|
||||
uint id = ++_id;
|
||||
|
||||
//qDebug()<<"Notify Growl:"<<notification.application()<<Notification.toPlainText(notification.title());
|
||||
try{
|
||||
growl->notify(notification.alert().toUtf8().constData(),
|
||||
growl->notify(notification.alert().toUtf8().constData(),id,
|
||||
Notification::toPlainText(notification.title()).toUtf8().constData(),
|
||||
Notification::toPlainText(notification.text()).toUtf8().constData(),
|
||||
notification.icon().localUrl().isEmpty()?NULL:notification.icon().localUrl().toUtf8().constData());
|
||||
notification.icon().localUrl().isEmpty()?NULL:notification.icon().localUrl().toUtf8().constData(),NULL,"1");
|
||||
activeNotifications.insert(id,notification);
|
||||
|
||||
}catch(const std::exception& e){
|
||||
qDebug()<<"Growl:"<<e.what();
|
||||
}
|
||||
return ++id;
|
||||
return id;
|
||||
}
|
||||
|
||||
void Growl_Backend::closeNotification(Notification notification){
|
||||
Q_UNUSED(notification);
|
||||
}
|
||||
|
||||
void Growl_Backend::gntpCallback(const int &id,const std::string &reason,const std::string &data){
|
||||
qDebug()<<"Growl Callback"<<id<<QString(reason.c_str())<<QString(data.c_str());
|
||||
Notification n = instance->activeNotifications.take(id);
|
||||
NotificationEnums::CloseReasons::closeReasons r = NotificationEnums::CloseReasons::NONE;
|
||||
if(reason == "TIMEDOUT")
|
||||
r = NotificationEnums::CloseReasons::TIMED_OUT;
|
||||
else if(reason == "CLOSED")
|
||||
r = NotificationEnums::CloseReasons::DISMISSED;
|
||||
else if(reason == "CLICK"){
|
||||
r = NotificationEnums::CloseReasons::CLOSED;
|
||||
n.setActionInvoked(QString(data.c_str()).toInt());
|
||||
instance->snore()->notificationActionInvoked(n);
|
||||
}
|
||||
instance->snore()->closeNotification(n,r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "growl_backend.moc"
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define GROWL_BACKEND_H
|
||||
#include "core/interface.h"
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
class Growl_Backend:public Notification_Backend
|
||||
{
|
||||
@ -28,9 +28,13 @@ public:
|
||||
Growl_Backend(class SnoreServer *snore=0);
|
||||
~Growl_Backend();
|
||||
bool isPrimaryNotificationBackend(){return true;}
|
||||
static void gntpCallback(const int &id,const std::string &reason,const std::string &data);
|
||||
private:
|
||||
uint id;
|
||||
//a static instance for the static callback methode
|
||||
static Growl_Backend *instance;
|
||||
uint _id;
|
||||
QHash<QString,class gntp*> _applications;
|
||||
|
||||
public slots:
|
||||
void registerApplication(Application *application);
|
||||
void unregisterApplication(class Application *application);
|
||||
@ -39,5 +43,4 @@ public slots:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // GROWL_BACKEND_H
|
||||
|
@ -27,11 +27,11 @@ class Snarl_Backend:public Notification_Backend
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(Notification_Backend)
|
||||
friend class SnarlWidget;
|
||||
public:
|
||||
Snarl_Backend(class SnoreServer *snore=0);
|
||||
~Snarl_Backend();
|
||||
bool isPrimaryNotificationBackend();
|
||||
QHash<uint,Notification> activeNotifications;
|
||||
|
||||
private:
|
||||
SnarlWidget* winIDWidget;
|
||||
|
Loading…
x
Reference in New Issue
Block a user