From deeafae6f0371d320756e1e8ae74ff3bc0d2ef54 2018-11-06 17:39:41 From: Vitaly Takmazov Date: 2018-11-06 17:39:41 Subject: [PATCH] libpurple: store last_message_timestamp from skypeweb account into database --- diff --git a/CMakeLists.txt b/CMakeLists.txt index c22afab6e5690a099822d56effe7ec1fe8b11bbf..27eb5fcc6ae80dd680c041c64d687caf245f2630 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.0) project(libtransport) -if(${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0037 OLD) -endif() +cmake_policy(SET CMP0042 NEW) +SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) include(CPack) message(STATUS "Variables to override default places where to find libraries:") message(STATUS "|- cppunit : -DCPPUNIT_INCLUDE_DIR, -DCPPUNIT_LIBRARY") diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 0207b2178a9474dd2245bd12af48e33db35aaf2e..73dacc71c8ba4da23baf0515dc7650196a98b66b 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -192,6 +192,7 @@ static boost::mutex dblock; static std::string OAUTH_TOKEN = "hangouts_oauth_token"; static std::string STEAM_ACCESS_TOKEN = "steammobile_access_token"; static std::string DISCORD_ACCESS_TOKEN = "discord_access_token"; +static std::string LAST_MESSAGE_TIMESTAMP = "skypeweb_last_message_timestamp"; static bool getUserToken(const std::string user, const std::string token_name, std::string &token_value) { @@ -434,6 +435,12 @@ class SpectrumNetworkPlugin : public NetworkPlugin { purple_account_set_string_wrapped(account, "token", token.c_str()); } } + if (protocol == "prpl-skypeweb") { + int ts = 0; + if (getLastMessageTimestamp(user, ts)) { + purple_account_set_int_wrapped(account, "last_message_timestamp", ts); + } + } setDefaultAccountOptions(account); @@ -476,9 +483,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin { purple_account_disconnect_wrapped(account); purple_account_set_enabled_wrapped(account, "spectrum", FALSE); - m_accounts.erase(account); - - purple_accounts_delete_wrapped(account); #ifndef WIN32 #if !defined(__FreeBSD__) && !defined(__APPLE__) malloc_trim(0); @@ -1517,11 +1521,17 @@ static void connection_report_disconnect(PurpleConnection *gc, PurpleConnectionE // purple_timeout_add_seconds_wrapped(10, disconnectMe, d); } +static void connection_disconnected(PurpleConnection *gc) { + PurpleAccount *account = purple_connection_get_account_wrapped(gc); + purple_accounts_delete_wrapped(account); + np->m_accounts.erase(account); +} + static PurpleConnectionUiOps conn_ui_ops = { NULL, NULL, - NULL,//connection_disconnected, + connection_disconnected, NULL, NULL, NULL, @@ -2007,6 +2017,72 @@ static PurpleRoomlistUiOps roomlist_ui_ops = NULL }; +#if PURPLE_MAJOR_VERSION >=2 && PURPLE_MINOR_VERSION >=11 + +static void preferencesIntChanged(PurpleAccount *account, const char *name, int value) { + boost::mutex::scoped_lock lock(dblock); + UserInfo info; + std::string user = np->m_accounts[account]; + LOG4CXX_INFO(logger, "asking for " << user << " settings"); + if(storagebackend->getUser(user, info) == false) { + LOG4CXX_ERROR(logger, "Didn't find entry for " << user << " in the database!"); + return; + } + LOG4CXX_INFO(logger, "storing " << value << "as " << name << " for " << user); + std::string defaultValue = "0"; + int type = TYPE_INT; + storagebackend->getUserSetting((long)info.id, std::string(name), type, defaultValue); + storagebackend->updateUserSetting((long)info.id, std::string(name), stringOf(value)); +}; + +static void preferencesStringChanged(PurpleAccount *account, const char *name, const char *value) { + boost::mutex::scoped_lock lock(dblock); + UserInfo info; + std::string user = np->m_accounts[account]; + LOG4CXX_INFO(logger, "asking for " << user << " settings"); + if(storagebackend->getUser(user, info) == false) { + LOG4CXX_ERROR(logger, "Didn't find entry for " << user << " in the database!"); + return; + } + LOG4CXX_INFO(logger, "storing " << value << "as " << name << " for " << user); + std::string defaultValue = ""; + int type = TYPE_STRING; + storagebackend->getUserSetting((long)info.id, std::string(name), type, defaultValue); + storagebackend->updateUserSetting((long)info.id, std::string(name), std::string(value)); +}; + +static void preferencesBoolChanged(PurpleAccount *account, const char *name, gboolean value) { + boost::mutex::scoped_lock lock(dblock); + UserInfo info; + std::string user = np->m_accounts[account]; + LOG4CXX_INFO(logger, "asking for " << user << " settings"); + if(storagebackend->getUser(user, info) == false) { + LOG4CXX_ERROR(logger, "Didn't find entry for " << user << " in the database!"); + return; + } + LOG4CXX_INFO(logger, "storing " << value << "as " << name << " for " << user); + std::string defaultValue = "false"; + int type = TYPE_BOOLEAN; + storagebackend->getUserSetting((long)info.id, std::string(name), type, defaultValue); + storagebackend->updateUserSetting((long)info.id, std::string(name), stringOf(value)); +}; + +static PurpleAccountPrefsUiOps account_prefs_ui_ops = +{ + preferencesIntChanged, + preferencesStringChanged, + preferencesBoolChanged, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +#endif + static void transport_core_ui_init(void) { purple_blist_set_ui_ops_wrapped(&blistUiOps); @@ -2017,7 +2093,9 @@ static void transport_core_ui_init(void) purple_connections_set_ui_ops_wrapped(&conn_ui_ops); purple_conversations_set_ui_ops_wrapped(&conversation_ui_ops); purple_roomlist_set_ui_ops_wrapped(&roomlist_ui_ops); - +#if PURPLE_MAJOR_VERSION >=2 && PURPLE_MINOR_VERSION >= 11 + purple_account_prefs_set_ui_ops_wrapped(&account_prefs_ui_ops); +#endif // #ifndef WIN32 // purple_dnsquery_set_ui_ops_wrapped(getDNSUiOps()); // #endif @@ -2356,11 +2434,11 @@ int main(int argc, char **argv) { config = SWIFTEN_SHRPTR_NAMESPACE::shared_ptr(cfg); Logging::initBackendLogging(config.get()); - if (CONFIG_STRING(config, "service.protocol") == "prpl-hangouts" || CONFIG_STRING(config, "service.protocol") == "prpl-steam-mobile") { + if (CONFIG_STRING(config, "service.protocol") == "prpl-hangouts" || CONFIG_STRING(config, "service.protocol") == "prpl-steam-mobile" || CONFIG_STRING(config, "service.protocol") == "prpl-skypeweb" || CONFIG_STRING(config, "service.protocol") == "prpl-eionrobb-discord") { storagebackend = StorageBackend::createBackend(config.get(), error); if (storagebackend == NULL) { LOG4CXX_ERROR(logger, "Error creating StorageBackend! " << error); - LOG4CXX_ERROR(logger, "Hangouts and Steam backends need storage backend configured to work! " << error); + LOG4CXX_ERROR(logger, "Selected libpurple protocol need storage backend configured to work! " << error); return NetworkPlugin::StorageBackendNeeded; } else if (!storagebackend->connect()) { diff --git a/backends/libpurple/purple_defs.cpp b/backends/libpurple/purple_defs.cpp index bb58301247ed7ce9d4ed4814a9dd1bd50a72bdce..cfc25c5b873f07ff31f1a99bbbf82d25be4e2bdf 100644 --- a/backends/libpurple/purple_defs.cpp +++ b/backends/libpurple/purple_defs.cpp @@ -28,6 +28,7 @@ purple_account_remove_buddy_wrapped_fnc purple_account_remove_buddy_wrapped = NU purple_account_add_buddy_wrapped_fnc purple_account_add_buddy_wrapped = NULL; purple_account_get_name_for_display_wrapped_fnc purple_account_get_name_for_display_wrapped = NULL; purple_accounts_set_ui_ops_wrapped_fnc purple_accounts_set_ui_ops_wrapped = NULL; +purple_account_prefs_set_ui_ops_wrapped_fnc purple_account_prefs_set_ui_ops_wrapped = NULL; purple_account_option_get_type_wrapped_fnc purple_account_option_get_type_wrapped = NULL; purple_account_option_get_setting_wrapped_fnc purple_account_option_get_setting_wrapped = NULL; purple_blist_node_get_type_wrapped_fnc purple_blist_node_get_type_wrapped = NULL; @@ -259,6 +260,9 @@ bool resolvePurpleFunctions() { purple_accounts_set_ui_ops_wrapped = (purple_accounts_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_accounts_set_ui_ops"); if (!purple_accounts_set_ui_ops_wrapped) return false; + purple_account_prefs_set_ui_ops_wrapped = (purple_account_prefs_set_ui_ops_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_prefs_set_ui_ops"); + if (!purple_account_prefs_set_ui_ops_wrapped) + return false; purple_account_option_get_type_wrapped = (purple_account_option_get_type_wrapped_fnc)GetProcAddress(f_hPurple, "purple_account_option_get_type"); if (!purple_account_option_get_type_wrapped) diff --git a/backends/libpurple/purple_defs.h b/backends/libpurple/purple_defs.h index c138a6a93deb87cc634585b992e84114dab81d00..f34f7f0556e9c4d51be845d32cf8f08be51bbfec 100644 --- a/backends/libpurple/purple_defs.h +++ b/backends/libpurple/purple_defs.h @@ -95,6 +95,9 @@ extern purple_account_get_name_for_display_wrapped_fnc purple_account_get_name_f typedef void (_cdecl * purple_accounts_set_ui_ops_wrapped_fnc)(PurpleAccountUiOps *ops); extern purple_accounts_set_ui_ops_wrapped_fnc purple_accounts_set_ui_ops_wrapped; +typedef void (_cdecl * purple_account_prefs_set_ui_ops_wrapped_fnc)(PurpleAccountPrefUiOps *ops); +extern purple_account_prefs_set_ui_ops_wrapped_fnc purple_account_pref_set_ui_ops_wrapped; + typedef PurplePrefType (_cdecl * purple_account_option_get_type_wrapped_fnc)(const PurpleAccountOption *option); extern purple_account_option_get_type_wrapped_fnc purple_account_option_get_type_wrapped; @@ -508,6 +511,7 @@ extern wpurple_g_io_channel_win32_new_socket_wrapped_fnc wpurple_g_io_channel_wi #define purple_account_add_buddy_wrapped purple_account_add_buddy #define purple_account_get_name_for_display_wrapped purple_account_get_name_for_display #define purple_accounts_set_ui_ops_wrapped purple_accounts_set_ui_ops +#define purple_account_prefs_set_ui_ops_wrapped purple_account_prefs_set_ui_ops #define purple_account_option_get_type_wrapped purple_account_option_get_type #define purple_account_option_get_setting_wrapped purple_account_option_get_setting #define purple_blist_node_get_type_wrapped purple_blist_node_get_type diff --git a/packaging/debian/debian/changelog b/packaging/debian/debian/changelog index 987597c284e40ed6c1c07f076d8530974ad209e0..f65b212eeaf47b45b382a0cc90ec3edf10fe66b5 100644 --- a/packaging/debian/debian/changelog +++ b/packaging/debian/debian/changelog @@ -1,4 +1,4 @@ -spectrum2 (1:1760-89e377b-1) unstable; urgency=low +spectrum2 (1:2267-b80ba70a-1) unstable; urgency=low * Move package to git-buildpackage format * remove the -git suffix from package names diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 169fa393c89e76820cf90c75997b4fc7dd35436a..7f163114d5f3229379c9ef625c75bb19b8c1d6ac 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,4 @@ ADD_SUBDIRECTORY(libtransport) - -add_custom_target(test ${CMAKE_CURRENT_BINARY_DIR}/libtransport/libtransport_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests_output) -add_custom_target(extended_test ${CMAKE_CURRENT_BINARY_DIR}/libtransport/libtransport_test COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/start.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests_output) +add_custom_target(test $ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests_output) +add_custom_target(extended_test $ COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/start.py WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests_output) diff --git a/tests/libtransport/util.cpp b/tests/libtransport/util.cpp index eaf6ebcd7c024c5c14f2f53674a5b2aeab1bc670..cb5229ba65715faa679f78b4fadb216618f5a365 100644 --- a/tests/libtransport/util.cpp +++ b/tests/libtransport/util.cpp @@ -10,15 +10,18 @@ #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" #include "basictest.h" #include "transport/utf8.h" +#include using namespace Transport; +using boost::lexical_cast; class UtilTest : public CPPUNIT_NS :: TestFixture{ CPPUNIT_TEST_SUITE(UtilTest); CPPUNIT_TEST(encryptDecryptPassword); CPPUNIT_TEST(serializeGroups); CPPUNIT_TEST(replaceInvalid); + CPPUNIT_TEST(storeUserSettings); CPPUNIT_TEST_SUITE_END(); public: @@ -66,6 +69,30 @@ class UtilTest : public CPPUNIT_NS :: TestFixture{ utf8::remove_invalid(x.begin(), x.end(), std::back_inserter(a)); CPPUNIT_ASSERT_EQUAL(std::string("testtest"), a); } + + void storeUserSettings() { + std::istringstream ifs("service.server_mode = 1\nservice.jid=localhost\nservice.more_resources=1\nservice.admin_jid=me@localhost\ndatabase.type=sqlite3\ndatabase.database=demo.s3db"); + Config *cfg = new Config(); + cfg->load(ifs); + std::string err = ""; + StorageBackend *storage = StorageBackend::createBackend(cfg, err); + UserInfo res; + res.uin = "123456"; + res.jid = "test@localhost"; + res.password = "secret"; + storage->connect(); + storage->setUser(res); + storage->getUser("test@localhost", res); + int ts = time(NULL); + std::string key = boost::lexical_cast(ts); + int type = TYPE_INT; + storage->getUserSetting(res.id, "test_variable", type, key); + std::string value = ""; + + storage->getUserSetting(res.id, "test_variable", type, value); + unlink("demo.s3db"); + CPPUNIT_ASSERT_EQUAL(ts, boost::lexical_cast(value)); + } };