diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 58d71daa..86a6f201 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -614,11 +614,13 @@ class SpectrumNetworkPlugin : public NetworkPlugin { return; } - LOG4CXX_INFO(logger, "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'"); - if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL){ + + if (purple_accounts_find(name.c_str(), protocol.c_str()) != NULL) { + LOG4CXX_INFO(logger, "Using previously created account with name '" << name.c_str() << "' and protocol '" << protocol << "'"); account = purple_accounts_find(name.c_str(), protocol.c_str()); } else { + LOG4CXX_INFO(logger, "Creating account with name '" << name.c_str() << "' and protocol '" << protocol << "'"); account = purple_account_new(name.c_str(), protocol.c_str()); purple_accounts_add(account); } @@ -1088,6 +1090,8 @@ static void buddyListNewNode(PurpleBlistNode *node) { PurpleBuddy *buddy = (PurpleBuddy *) node; PurpleAccount *account = purple_buddy_get_account(buddy); + LOG4CXX_INFO(logger, "Buddy updated " << np->m_accounts[account] << " " << purple_buddy_get_name(buddy) << " " << getAlias(buddy)); + // Status pbnetwork::StatusType status = pbnetwork::STATUS_NONE; std::string message; diff --git a/include/Swiften/Server/ServerStanzaChannel.cpp b/include/Swiften/Server/ServerStanzaChannel.cpp index bb3fbf6e..9597cc1c 100644 --- a/include/Swiften/Server/ServerStanzaChannel.cpp +++ b/include/Swiften/Server/ServerStanzaChannel.cpp @@ -32,11 +32,13 @@ void ServerStanzaChannel::addSession(boost::shared_ptr sessions[session->getRemoteJID().toBare().toString()].push_back(session); session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); + session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); } void ServerStanzaChannel::removeSession(boost::shared_ptr session) { session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session)); session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session)); + session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session)); std::list > &lst = sessions[session->getRemoteJID().toBare().toString()]; lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end()); } @@ -53,6 +55,15 @@ void ServerStanzaChannel::sendPresence(boost::shared_ptr presence) { send(presence); } +void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr &session) { + if (safeByteArrayToString(data).find("") != std::string::npos) { + Swift::Presence::ref presence = Swift::Presence::create(); + presence->setFrom(session->getRemoteJID()); + presence->setType(Swift::Presence::Unavailable); + onPresenceReceived(presence); + } +} + void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr element, bool last) { std::vector > candidateSessions; for (std::list >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) { diff --git a/include/Swiften/Server/ServerStanzaChannel.h b/include/Swiften/Server/ServerStanzaChannel.h index 69158eea..99c857be 100644 --- a/include/Swiften/Server/ServerStanzaChannel.h +++ b/include/Swiften/Server/ServerStanzaChannel.h @@ -41,6 +41,7 @@ namespace Swift { void send(boost::shared_ptr stanza); void handleSessionFinished(const boost::optional&, const boost::shared_ptr &session); void handleElement(boost::shared_ptr element, const boost::shared_ptr &session); + void handleDataRead(const SafeByteArray &data, const boost::shared_ptr &session); void handleSessionInitialized(); private: diff --git a/include/transport/pqxxbackend.h b/include/transport/pqxxbackend.h index 21d54339..e13c6b03 100644 --- a/include/transport/pqxxbackend.h +++ b/include/transport/pqxxbackend.h @@ -97,6 +97,7 @@ class PQXXBackend : public StorageBackend private: bool exec(const std::string &query, bool show_error = true); + bool exec(pqxx::work &txn, const std::string &query, bool show_error = true); Config *m_config; std::string m_prefix; diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index ea8f33d6..c57573ea 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -396,7 +396,7 @@ int main(int argc, char **argv) #endif if (CONFIG_STRING(&config, "database.type") != "mysql" && CONFIG_STRING(&config, "database.type") != "sqlite3" - && CONFIG_STRING(&config, "database.type") != "pqxx") { + && CONFIG_STRING(&config, "database.type") != "pqxx" && CONFIG_STRING(&config, "database.type") != "none") { std::cerr << "Unknown storage backend " << CONFIG_STRING(&config, "database.type") << "\n"; return -2; } diff --git a/src/pqxxbackend.cpp b/src/pqxxbackend.cpp index 426b8eb9..af0efd36 100644 --- a/src/pqxxbackend.cpp +++ b/src/pqxxbackend.cpp @@ -79,7 +79,7 @@ bool PQXXBackend::createDatabase() { ");"); exec("CREATE TYPE Subscription AS ENUM ('to','from','both','ask','none');"); - exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "buddies (" + exec("CREATE TABLE " + m_prefix + "buddies (" "id SERIAL," "user_id integer NOT NULL," "uin varchar(255) NOT NULL," @@ -91,7 +91,7 @@ bool PQXXBackend::createDatabase() { "UNIQUE (user_id,uin)" ");"); - exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "users (" + exec("CREATE TABLE " + m_prefix + "users (" "id SERIAL," "jid varchar(255) NOT NULL," "uin varchar(4095) NOT NULL," @@ -105,7 +105,7 @@ bool PQXXBackend::createDatabase() { "UNIQUE (jid)" ");"); - exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "users_settings (" + exec("CREATE TABLE " + m_prefix + "users_settings (" "user_id integer NOT NULL," "var varchar(50) NOT NULL," "type smallint NOT NULL," @@ -113,7 +113,7 @@ bool PQXXBackend::createDatabase() { "PRIMARY KEY (user_id,var)" ");"); - exec("CREATE TABLE IF NOT EXISTS " + m_prefix + "db_version (" + exec("CREATE TABLE " + m_prefix + "db_version (" "ver integer NOT NULL default '1'," "UNIQUE (ver)" ");"); @@ -126,6 +126,10 @@ bool PQXXBackend::createDatabase() { bool PQXXBackend::exec(const std::string &query, bool show_error) { pqxx::work txn(*m_conn); + return exec(txn, query, show_error); +} + +bool PQXXBackend::exec(pqxx::work &txn, const std::string &query, bool show_error) { try { txn.exec(query); txn.commit(); @@ -139,48 +143,72 @@ bool PQXXBackend::exec(const std::string &query, bool show_error) { } void PQXXBackend::setUser(const UserInfo &user) { -// std::string encrypted = user.password; -// if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) { -// encrypted = Util::encryptPassword(encrypted, CONFIG_STRING(m_config, "database.encryption_key")); -// } -// *m_setUser << user.jid << user.uin << encrypted << user.language << user.encoding << user.vip << user.uin << encrypted; -// EXEC(m_setUser, setUser(user)); + std::string encrypted = user.password; + if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) { + encrypted = Util::encryptPassword(encrypted, CONFIG_STRING(m_config, "database.encryption_key")); + } + pqxx::work txn(*m_conn); + exec(txn, "UPDATE " + m_prefix + "users SET uin=" + txn.quote(user.uin) + ", password=" + txn.quote(encrypted) + ";" + "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES " + "(" + txn.quote(user.jid) + "," + + txn.quote(user.uin) + "," + + txn.quote(encrypted) + "," + + txn.quote(user.language) + "," + + txn.quote(user.encoding) + "," + + "NOW()," + + txn.quote(user.vip) +")"); } bool PQXXBackend::getUser(const std::string &barejid, UserInfo &user) { -// *m_getUser << barejid; -// EXEC(m_getUser, getUser(barejid, user)); -// if (!exec_ok) -// return false; + try { + pqxx::work txn(*m_conn); - int ret = false; -// while (m_getUser->fetch() == 0) { -// ret = true; -// *m_getUser >> user.id >> user.jid >> user.uin >> user.password >> user.encoding >> user.language >> user.vip; + pqxx::result r = txn.exec("SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=" + + txn.quote(barejid)); -// if (!CONFIG_STRING(m_config, "database.encryption_key").empty()) { -// user.password = Util::decryptPassword(user.password, CONFIG_STRING(m_config, "database.encryption_key")); -// } -// } + if (r.size() == 0) { + return false; + } - return ret; + user.id = r[0][0].as(); + user.jid = r[0][1].as(); + user.uin = r[0][2].as(); + user.password = r[0][3].as(); + user.encoding = r[0][4].as(); + user.language = r[0][5].as(); + user.vip = r[0][6].as(); + } + catch (std::exception& e) { + LOG4CXX_ERROR(logger, e.what()); + return false; + } + + return true; } void PQXXBackend::setUserOnline(long id, bool online) { -// *m_setUserOnline << online << id; -// EXEC(m_setUserOnline, setUserOnline(id, online)); + try { + pqxx::work txn(*m_conn); + exec(txn, "UPDATE " + m_prefix + "users SET online=" + txn.quote(online) + ", last_login=NOW() WHERE id=" + txn.quote(id)); + } + catch (std::exception& e) { + LOG4CXX_ERROR(logger, e.what()); + } } bool PQXXBackend::getOnlineUsers(std::vector &users) { -// EXEC(m_getOnlineUsers, getOnlineUsers(users)); -// if (!exec_ok) -// return false; + try { + pqxx::work txn(*m_conn); + pqxx::result r = txn.exec("SELECT jid FROM " + m_prefix + "users WHERE online=1"); -// std::string jid; -// while (m_getOnlineUsers->fetch() == 0) { -// *m_getOnlineUsers >> jid; -// users.push_back(jid); -// } + for (pqxx::result::const_iterator it = r.begin(); it != r.end(); it++) { + users.push_back((*it)[0].as()); + } + } + catch (std::exception& e) { + LOG4CXX_ERROR(logger, e.what()); + return false; + } return true; }