use my gntp-send fork instead of gntpp, get ridd of the boost dependencie and the dependencie to cryptopp
This commit is contained in:
parent
28c9c51b5e
commit
e6fce634e4
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "thirdparty/gntp-send"]
|
||||||
|
path = thirdparty/gntp-send
|
||||||
|
url = https://github.com/Snorenotify/gntp-send.git
|
|
@ -52,9 +52,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
find_package( CryptoPP )
|
|
||||||
find_package( Boost COMPONENTS system thread)
|
|
||||||
|
|
||||||
find_package(Doxygen)
|
find_package(Doxygen)
|
||||||
|
|
||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
|
@ -82,6 +79,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(data)
|
add_subdirectory(data)
|
||||||
add_subdirectory(share)
|
add_subdirectory(share)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -1,37 +1,23 @@
|
||||||
if( WITH_GROWL_BACKEND )
|
if( WITH_GROWL_BACKEND )
|
||||||
if(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
|
message( STATUS "Adding libgrowl backend" )
|
||||||
message( STATUS "Found Boost and Cryptopp, adding libgrowl backend" )
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
set( GROWL__SRC
|
|
||||||
growl.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(libsnore_backend_growl MODULE ${GROWL__SRC} )
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(libsnore_backend_growl snorecore ${QT_QTCORE_LIBRARY} ${CRYPTOPP_LIBRARIES} ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY})
|
include_directories(${CMAKE_SOURCE_DIR}/thirdparty/gntp-send/include)
|
||||||
|
|
||||||
if(MINGW)
|
set( GROWL_SRC growlbackend.cpp
|
||||||
#fiexes a multiple defenition error with static boost
|
${CMAKE_SOURCE_DIR}/thirdparty/gntp-send/src/tcp.c
|
||||||
SET_TARGET_PROPERTIES(libsnore_backend_growl PROPERTIES LINK_FLAGS -Wl,--allow-multiple-definition COMPILE_FLAGS
|
${CMAKE_SOURCE_DIR}/thirdparty/gntp-send/src/md5.c
|
||||||
"-Wno-undef -Wno-unused-parameter -Wno-unknown-pragmas -Wno-unused-local-typedefs -Wno-missing-field-initializers -Wno-strict-aliasing -Wno-reorder -Wno-unused-variable -Wno-unused-function" )
|
${CMAKE_SOURCE_DIR}/thirdparty/gntp-send/src/growl.c
|
||||||
endif(MINGW)
|
${CMAKE_SOURCE_DIR}/thirdparty/gntp-send/src/growl.cpp)
|
||||||
|
|
||||||
if(WIN32)
|
add_library(libsnore_backend_growl MODULE ${GROWL_SRC} )
|
||||||
target_link_libraries(libsnore_backend_growl wsock32 ws2_32)
|
target_link_libraries(libsnore_backend_growl snorecore ${QT_QTCORE_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endif(WIN32)
|
set_target_properties(libsnore_backend_growl PROPERTIES COMPILE_FLAGS "-DGROWL_DLL -DGROWL_CPP_DLL" )
|
||||||
|
|
||||||
if(UNIX)
|
if( WIN32 )
|
||||||
target_link_libraries(libsnore_backend_growl pthread)
|
target_link_libraries(libsnore_backend_growl ws2_32 )
|
||||||
endif(UNIX)
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS libsnore_backend_growl ${SNORE_PLUGIN_INSTALL_PATH})
|
||||||
|
|
||||||
install(TARGETS libsnore_backend_growl ${SNORE_PLUGIN_INSTALL_PATH})
|
|
||||||
else(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
|
|
||||||
if(NOT CRYPTOPP_LIBRARIES)
|
|
||||||
message(STATUS "Cant build the growl backend because the dependency Cryptopp is missing")
|
|
||||||
endif(NOT CRYPTOPP_LIBRARIES)
|
|
||||||
if(NOT Boost_SYSTEM_LIBRARY)
|
|
||||||
message(STATUS "Cant build the growl backend because the dependency BOOST_SYSTEM is missing")
|
|
||||||
endif(NOT Boost_SYSTEM_LIBRARY)
|
|
||||||
endif(CRYPTOPP_LIBRARIES AND Boost_SYSTEM_LIBRARY)
|
|
||||||
endif( WITH_GROWL_BACKEND )
|
endif( WITH_GROWL_BACKEND )
|
||||||
|
|
|
@ -1,315 +0,0 @@
|
||||||
#ifndef gntp_h
|
|
||||||
#define gntp_h
|
|
||||||
|
|
||||||
//#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 0
|
|
||||||
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <cryptopp/osrng.h>
|
|
||||||
#include <cryptopp/files.h>
|
|
||||||
#include <cryptopp/hex.h>
|
|
||||||
#include <cryptopp/sha.h>
|
|
||||||
#include <cryptopp/md5.h>
|
|
||||||
#include <cryptopp/des.h>
|
|
||||||
#include <cryptopp/aes.h>
|
|
||||||
#include <cryptopp/filters.h>
|
|
||||||
#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, "" );
|
|
||||||
hex.Attach(new CryptoPP::StringSink(out));
|
|
||||||
hex.PutMessageEnd(in.begin(), in.size());
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
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::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);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
|
|
||||||
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";
|
|
||||||
} else {
|
|
||||||
cbr->sock << "GNTP/1.0 "
|
|
||||||
<< method
|
|
||||||
<< " NONE\r\n"
|
|
||||||
<< stm.str() << "\r\n";
|
|
||||||
}
|
|
||||||
recv(cbr->sock);
|
|
||||||
return cbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class CIPHER_TYPE, class HASH_TYPE>
|
|
||||||
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());
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
|
|
||||||
std::string cipher_text;
|
|
||||||
CryptoPP::StringSource(stm.str(), true,
|
|
||||||
new CryptoPP::StreamTransformationFilter(encryptor,
|
|
||||||
new CryptoPP::StringSink(cipher_text)
|
|
||||||
) // StreamTransformationFilter
|
|
||||||
); // StringSource
|
|
||||||
|
|
||||||
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";
|
|
||||||
} else {
|
|
||||||
cbr->sock << "GNTP/1.0 "
|
|
||||||
<< method
|
|
||||||
<< " NONE\r\n"
|
|
||||||
<< stm.str() << "\r\n";
|
|
||||||
}
|
|
||||||
recv(cbr->sock);
|
|
||||||
return cbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_regist(std::stringstream& stm, const char* name) {
|
|
||||||
stm << "Notification-Name: " << sanitize_text(name) << "\r\n";
|
|
||||||
stm << "Notification-Display-Name: " << sanitize_text(name) << "\r\n";
|
|
||||||
stm << "Notification-Enabled: True\r\n";
|
|
||||||
stm << "\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
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";
|
|
||||||
}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";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string application_;
|
|
||||||
std::string hostname_;
|
|
||||||
std::string port_;
|
|
||||||
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),
|
|
||||||
password_(password),
|
|
||||||
hostname_(hostname),
|
|
||||||
port_(port),
|
|
||||||
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 << "Notifications-Count: 1\r\n";
|
|
||||||
stm << "\r\n";
|
|
||||||
make_regist(stm, name);
|
|
||||||
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 << "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());
|
|
||||||
}
|
|
||||||
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 << "Notifications-Count: 1\r\n";
|
|
||||||
stm << "\r\n";
|
|
||||||
make_regist(stm, name);
|
|
||||||
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 << "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());
|
|
||||||
}
|
|
||||||
callback_reciver *cbr = send<CIPHER_TYPE, HASH_TYPE>("REGISTER", stm);
|
|
||||||
delete cbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
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, 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 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, id, title, text, icon, url,callbackid);
|
|
||||||
callback_reciver *cbr = send<CIPHER_TYPE, HASH_TYPE>("NOTIFY", stm);
|
|
||||||
cbr->run();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// vim:set et:
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*
|
|
||||||
SnoreNotify is a Notification Framework based on Qt
|
|
||||||
Copyright (C) 2013-2014 Patrick von Reth <vonreth@kde.org>
|
|
||||||
|
|
||||||
|
|
||||||
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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "growl.h"
|
|
||||||
#include "gntp.h"
|
|
||||||
|
|
||||||
#include "core/snore.h"
|
|
||||||
#include "core/snore_p.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <QtCore>
|
|
||||||
#include <QTcpSocket>
|
|
||||||
|
|
||||||
using namespace Snore;
|
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN2(libsnore_backend_growl,Growl)
|
|
||||||
|
|
||||||
Growl *Growl::s_instance = NULL;
|
|
||||||
|
|
||||||
Growl::Growl():
|
|
||||||
SnoreBackend("Growl",false,false),
|
|
||||||
m_id(0)
|
|
||||||
{
|
|
||||||
s_instance = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Growl::~Growl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Growl::initialize(SnoreCore *snore)
|
|
||||||
{
|
|
||||||
|
|
||||||
QTcpSocket qsocket;
|
|
||||||
qsocket.connectToHost("localhost", 23053);
|
|
||||||
if(qsocket.waitForConnected(100))
|
|
||||||
{
|
|
||||||
qsocket.write(QString("GNTP/1.0\r\n").toUtf8());
|
|
||||||
if(qsocket.waitForReadyRead(100))
|
|
||||||
{
|
|
||||||
snoreDebug( SNORE_DEBUG ) << QString::fromUtf8(qsocket.readAll());
|
|
||||||
return SnoreBackend::initialize(snore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
snoreDebug( SNORE_DEBUG ) << "Growl is not running";
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Growl::slotRegisterApplication(const Application &application)
|
|
||||||
{
|
|
||||||
gntp *growl = new gntp(application.name().toUtf8().constData(),application.icon().localUrl().toUtf8().constData());
|
|
||||||
|
|
||||||
gntp::gntp_callback callback(&Growl::gntpCallback);
|
|
||||||
growl->set_gntp_callback(callback);
|
|
||||||
|
|
||||||
// snoreDebug( SNORE_DEBUG ) << application.name().toUtf8().constData();
|
|
||||||
std::vector<std::string> alerts;
|
|
||||||
foreach(const Alert &a,application.alerts())
|
|
||||||
{
|
|
||||||
snoreDebug( SNORE_DEBUG ) << a.name().toUtf8().constData();
|
|
||||||
alerts.push_back(a.name().toUtf8().constData());
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
growl->regist(alerts);
|
|
||||||
}catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
snoreDebug( SNORE_WARNING ) << e.what();
|
|
||||||
}
|
|
||||||
m_applications.insert(application.name(),growl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Growl::slotDeregisterApplication(const Application &application)
|
|
||||||
{
|
|
||||||
gntp *growl = m_applications.take(application.name());
|
|
||||||
if(growl == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete growl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Growl::slotNotify(Notification notification)
|
|
||||||
{
|
|
||||||
gntp *growl = m_applications.value(notification.application().name());
|
|
||||||
QString alert = notification.alert().name();
|
|
||||||
snoreDebug( SNORE_DEBUG ) << "Notify Growl:" <<notification.application() << alert << Snore::toPlainText(notification.title());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
growl->notify(alert.toUtf8().constData(),notification.id(),
|
|
||||||
Snore::toPlainText(notification.title()).toUtf8().constData(),
|
|
||||||
Snore::toPlainText(notification.text()).toUtf8().constData(),
|
|
||||||
notification.icon().localUrl().isEmpty()?NULL:notification.icon().localUrl().toUtf8().constData(),NULL,"1");
|
|
||||||
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
snoreDebug( SNORE_WARNING ) << e.what();
|
|
||||||
}
|
|
||||||
startTimeout(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Growl::gntpCallback(const int &id,const std::string &reason,const std::string &data)
|
|
||||||
{
|
|
||||||
// snoreDebug( SNORE_DEBUG ) << id << QString(reason.c_str()) << QString(data.c_str());
|
|
||||||
Notification n = s_instance->snore()->getActiveNotificationByID(id);
|
|
||||||
Notification::CloseReasons r = Notification::NONE;
|
|
||||||
if(reason == "TIMEDOUT")
|
|
||||||
{
|
|
||||||
r = Notification::TIMED_OUT;
|
|
||||||
}
|
|
||||||
else if(reason == "CLOSED")
|
|
||||||
{
|
|
||||||
r = Notification::DISMISSED;
|
|
||||||
}
|
|
||||||
else if(reason == "CLICK")
|
|
||||||
{
|
|
||||||
r = Notification::CLOSED;
|
|
||||||
s_instance->snore()->d()->notificationActionInvoked(n);
|
|
||||||
}
|
|
||||||
s_instance->closeNotification(n,r);
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
SnoreNotify is a Notification Framework based on Qt
|
||||||
|
Copyright (C) 2013-2014 Patrick von Reth <vonreth@kde.org>
|
||||||
|
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "growlbackend.h"
|
||||||
|
|
||||||
|
#include "core/snore.h"
|
||||||
|
#include "core/snore_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
using namespace Snore;
|
||||||
|
|
||||||
|
Q_EXPORT_PLUGIN2(libsnore_backend_growl,GrowlBackend)
|
||||||
|
|
||||||
|
GrowlBackend *GrowlBackend::s_instance = NULL;
|
||||||
|
|
||||||
|
GrowlBackend::GrowlBackend():
|
||||||
|
SnoreBackend("Growl",false,false),
|
||||||
|
m_id(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GrowlBackend::~GrowlBackend()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrowlBackend::initialize(SnoreCore *snore)
|
||||||
|
{
|
||||||
|
|
||||||
|
QTcpSocket qsocket;
|
||||||
|
qsocket.connectToHost("localhost", 23053);
|
||||||
|
if(qsocket.waitForConnected(100))
|
||||||
|
{
|
||||||
|
qsocket.write(QString("GNTP/1.0\r\n").toUtf8());
|
||||||
|
if(qsocket.waitForReadyRead(100))
|
||||||
|
{
|
||||||
|
snoreDebug( SNORE_DEBUG ) << QString::fromUtf8(qsocket.readAll());
|
||||||
|
s_instance = this;
|
||||||
|
Growl::setCallback((GROWL_CALLBACK)&GrowlBackend::gntpCallback);
|
||||||
|
return SnoreBackend::initialize(snore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snoreDebug( SNORE_DEBUG ) << "Growl is not running";
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GrowlBackend::deinitialize()
|
||||||
|
{
|
||||||
|
s_instance = NULL;
|
||||||
|
return SnoreBackend::deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrowlBackend::slotRegisterApplication(const Application &application)
|
||||||
|
{
|
||||||
|
// snoreDebug( SNORE_DEBUG ) << application.name().toUtf8().constData();
|
||||||
|
std::vector<std::string> alerts;
|
||||||
|
foreach(const Alert &a,application.alerts())
|
||||||
|
{
|
||||||
|
snoreDebug( SNORE_DEBUG ) << a.name().toUtf8().constData();
|
||||||
|
alerts.push_back(a.name().toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
||||||
|
Growl *growl = new Growl(GROWL_TCP, "", application.name().toUtf8().constData());
|
||||||
|
growl->Register(alerts,application.icon().localUrl().toUtf8().constData());
|
||||||
|
|
||||||
|
m_applications.insert(application.name(),growl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrowlBackend::slotDeregisterApplication(const Application &application)
|
||||||
|
{
|
||||||
|
Growl *growl = m_applications.take(application.name());
|
||||||
|
if(growl == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete growl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrowlBackend::slotNotify(Notification notification)
|
||||||
|
{
|
||||||
|
Growl *growl = m_applications.value(notification.application().name());
|
||||||
|
QString alert = notification.alert().name();
|
||||||
|
snoreDebug( SNORE_DEBUG ) << "Notify Growl:" <<notification.application() << alert << Snore::toPlainText(notification.title());
|
||||||
|
|
||||||
|
GrowlNotificationData data(growl, alert.toUtf8().constData(),notification.id(),
|
||||||
|
Snore::toPlainText(notification.title()).toUtf8().constData(),
|
||||||
|
Snore::toPlainText(notification.text()).toUtf8().constData());
|
||||||
|
|
||||||
|
if(notification.icon().isValid())
|
||||||
|
{
|
||||||
|
data.setIcon(notification.icon().localUrl().toUtf8().constData());
|
||||||
|
}
|
||||||
|
data.setCallbackData("1");
|
||||||
|
growl->Notify(data);
|
||||||
|
|
||||||
|
|
||||||
|
startTimeout(notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrowlBackend::gntpCallback(growl_callback_data *data)
|
||||||
|
{
|
||||||
|
if(s_instance)
|
||||||
|
{
|
||||||
|
snoreDebug( SNORE_DEBUG ) << data->id << QString(data->reason) << QString(data->data);
|
||||||
|
Notification n = s_instance->snore()->getActiveNotificationByID(data->id);
|
||||||
|
Notification::CloseReasons r = Notification::NONE;
|
||||||
|
std::string reason(data->reason);
|
||||||
|
if(reason == "TIMEDOUT")
|
||||||
|
{
|
||||||
|
r = Notification::TIMED_OUT;
|
||||||
|
}
|
||||||
|
else if(reason == "CLOSED")
|
||||||
|
{
|
||||||
|
r = Notification::DISMISSED;
|
||||||
|
}
|
||||||
|
else if(reason == "CLICK")
|
||||||
|
{
|
||||||
|
r = Notification::CLOSED;
|
||||||
|
s_instance->snore()->d()->notificationActionInvoked(n);
|
||||||
|
}
|
||||||
|
s_instance->closeNotification(n,r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,26 +21,28 @@
|
||||||
#define GROWL_BACKEND_H
|
#define GROWL_BACKEND_H
|
||||||
#include "core/plugins/snorebackend.h"
|
#include "core/plugins/snorebackend.h"
|
||||||
|
|
||||||
|
#include <gntp/growl.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Growl:public Snore::SnoreBackend
|
class GrowlBackend:public Snore::SnoreBackend
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_INTERFACES(Snore::SnoreBackend)
|
Q_INTERFACES(Snore::SnoreBackend)
|
||||||
Q_PLUGIN_METADATA(IID "org.Snore.NotificationBackend/1.0")
|
Q_PLUGIN_METADATA(IID "org.Snore.NotificationBackend/1.0")
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Growl();
|
GrowlBackend();
|
||||||
~Growl();
|
~GrowlBackend();
|
||||||
virtual bool initialize(Snore::SnoreCore *snore);
|
virtual bool initialize(Snore::SnoreCore *snore);
|
||||||
|
virtual bool deinitialize();
|
||||||
|
|
||||||
static void gntpCallback(const int &id,const std::string &reason,const std::string &data);
|
static void gntpCallback(growl_callback_data *data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//a static instance for the static callback methode
|
//a static instance for the static callback methode
|
||||||
static Growl *s_instance;
|
static GrowlBackend *s_instance;
|
||||||
uint m_id;
|
uint m_id;
|
||||||
QHash<QString,class gntp*> m_applications;
|
QHash<QString,Growl*> m_applications;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void slotRegisterApplication(const Snore::Application &application);
|
void slotRegisterApplication(const Snore::Application &application);
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 81b30b5ec6f0cf61650e8f371a487f2f07af52d1
|
Loading…
Reference in New Issue