[SCM] ktp-kded-integration-module packaging branch, master, updated. debian/15.12.1-2-382-gbd961c2
Maximiliano Curia
maxy at moszumanska.debian.org
Sat May 28 00:15:36 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-kded-module.git;a=commitdiff;h=52a382a
The following commit has been merged in the master branch:
commit 52a382a1511badaf32c3fd94f8aaba1c8c00f771
Author: Alexandr Akulich <akulichalexander at gmail.com>
Date: Mon Jan 27 17:41:06 2014 +0600
Save persistent information on a contact to a database.
REVIEW: 115328
---
CMakeLists.txt | 9 +
contact-cache.cpp | 240 +++++++++++++++++++++
contact-cache.h | 54 +++++
contactnotify.cpp | 4 +-
telepathy-module.cpp | 3 +
tests/CMakeLists.txt | 18 ++
.../contact-cache-main.cpp | 30 +--
7 files changed, 336 insertions(+), 22 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a31245b..2586228 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,9 @@ find_package (KTp REQUIRED)
# set some default settings
include (KDE4Defaults)
+# Add an option for building tests
+option(ENABLE_TESTS "Enable compilation of tests" FALSE)
+
# make some more macros available
include (MacroLibrary)
@@ -32,6 +35,7 @@ include_directories (${KDE4_INCLUDES}
)
set (kded_ktp_integration_module_SRCS
+ contact-cache.cpp
contact-request-handler.cpp
telepathy-kded-module-plugin.cpp
telepathy-module.cpp
@@ -54,6 +58,7 @@ target_link_libraries (kded_ktp_integration_module
${KDE4_KDEUI_LIBS}
${KDE4_KIDLETIME_LIBRARY}
${KDE4_SOLID_LIBS}
+ ${QT_QTSQL_LIBRARIES}
)
install (TARGETS kded_ktp_integration_module
@@ -71,3 +76,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.KTp.K
DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
add_subdirectory(config)
+
+if(ENABLE_TESTS)
+ add_subdirectory(tests)
+endif()
diff --git a/contact-cache.cpp b/contact-cache.cpp
new file mode 100644
index 0000000..73c4d90
--- /dev/null
+++ b/contact-cache.cpp
@@ -0,0 +1,240 @@
+/*
+ Copyright (C) 2014 David Edmundson <kde at davidedmundson.co.uk>
+ Copyright (C) 2014 Alexandr Akulich <akulichalexander at gmail.com>
+
+ This library 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 2.1 of the License, or (at your option) any later version.
+
+ This library 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 this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "contact-cache.h"
+
+#include <KTp/core.h>
+#include <KTp/contact.h>
+
+#include <TelepathyQt/Account>
+#include <TelepathyQt/AccountManager>
+#include <TelepathyQt/AvatarData>
+#include <TelepathyQt/Connection>
+#include <TelepathyQt/ContactManager>
+#include <TelepathyQt/PendingOperation>
+#include <TelepathyQt/PendingReady>
+
+#include <KDebug>
+#include <KGlobal>
+#include <KStandardDirs>
+
+#include <QSqlQuery>
+#include <QSqlDriver>
+#include <QSqlField>
+
+/*
+ * This class waits for a connection to load then saves the pernament
+ * data from all contacts into a database that can be loaded by the kpeople plugin
+ * It will not stay up-to-date, applications should load from the database, then
+ * fetch volatile and up-to-date data from TpQt
+ *
+ * We don't hold a reference to the contact to keep things light
+ */
+
+inline QString formatString(const QSqlQuery &query, const QString &str)
+{
+ QSqlField f(QLatin1String(""), QVariant::String);
+ f.setValue(str);
+ return query.driver()->formatValue(f);
+}
+
+ContactCache::ContactCache(QObject *parent):
+ QObject(parent),
+ m_db(QSqlDatabase::addDatabase(QLatin1String("QSQLITE")))
+{
+ m_db.setDatabaseName(KGlobal::dirs()->locateLocal("data", QLatin1String("ktp/cache.db")));
+ m_db.open();
+
+ if (!m_db.tables().contains(QLatin1String("contacts"))) {
+ QSqlQuery createTables(m_db);
+ createTables.exec(QLatin1String("CREATE TABLE contacts (accountID VARCHAR NOT NULL, contactID VARCHAR NOT NULL, alias VARCHAR, avatarFileName VARCHAR);"));
+ createTables.exec(QLatin1String("CREATE UNIQUE INDEX idIndex ON contacts (accountId, contactId);"));
+ }
+
+ connect(KTp::accountManager()->becomeReady(), SIGNAL(finished(Tp::PendingOperation*)), SLOT(onAccountManagerReady(Tp::PendingOperation*)));
+}
+
+void ContactCache::onAccountManagerReady(Tp::PendingOperation *op)
+{
+ if (!op || op->isError()) {
+ kWarning() << "ContactCache: Failed to initialize AccountManager:" << op->errorName();
+ kWarning() << op->errorMessage();
+
+ return;
+ }
+
+ connect(KTp::accountManager().data(), SIGNAL(newAccount(Tp::AccountPtr)), SLOT(onNewAccount(Tp::AccountPtr)));
+
+ QSqlQuery purgeQuery(m_db);
+ QStringList formattedAccountsIds;
+
+ Q_FOREACH (const Tp::AccountPtr &account, KTp::accountManager()->allAccounts()) {
+ if (!accountIsInteresting(account)) {
+ continue;
+ }
+
+ connectToAccount(account);
+ if (!account->connection().isNull()) {
+ onAccountConnectionChanged(account->connection());
+ }
+
+ formattedAccountsIds.append(formatString(purgeQuery, account->uniqueIdentifier()));
+ }
+
+ if (formattedAccountsIds.isEmpty()) {
+ purgeQuery.prepare(QLatin1String("DELETE * FROM contacts;"));
+ } else {
+ purgeQuery.prepare(QString(QLatin1String("DELETE FROM contacts WHERE accountID not in (%1);")).arg(formattedAccountsIds.join(QLatin1String(","))));
+ }
+ purgeQuery.exec();
+}
+
+void ContactCache::onNewAccount(const Tp::AccountPtr &account)
+{
+ if (!accountIsInteresting(account)) {
+ return;
+ }
+
+ connectToAccount(account);
+ if (!account->connection().isNull()) {
+ onAccountConnectionChanged(account->connection());
+ }
+}
+
+void ContactCache::onAccountRemoved()
+{
+ Tp::Account *account = qobject_cast<Tp::Account*>(sender());
+
+ if (!account) {
+ return;
+ }
+
+ QSqlQuery purgeQuery(m_db);
+ purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
+ purgeQuery.bindValue(0, account->uniqueIdentifier());
+ purgeQuery.exec();
+}
+
+void ContactCache::onContactManagerStateChanged()
+{
+ Tp::ContactManagerPtr contactManager(qobject_cast<Tp::ContactManager*>(sender()));
+ checkContactManagerState(Tp::ContactManagerPtr(contactManager));
+}
+
+void ContactCache::onAccountConnectionChanged(const Tp::ConnectionPtr &connection)
+{
+ if (connection.isNull() || (connection->status() != Tp::ConnectionStatusConnected)) {
+ return;
+ }
+
+ if (connect(connection->contactManager().data(), SIGNAL(stateChanged(Tp::ContactListState)), this, SLOT(onContactManagerStateChanged()), Qt::UniqueConnection)) {
+ /* Check current contactManager state and do sync contact only if it is not performed due to already connected contactManager. */
+ checkContactManagerState(connection->contactManager());
+ }
+}
+
+void ContactCache::onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed)
+{
+ /* Delete both added and removed contacts, because it's faster than accurate comparsion and partial update of exist contacts. */
+ Tp::Contacts toBeRemoved = added;
+ toBeRemoved.unite(removed);
+
+ m_db.transaction();
+ QSqlQuery removeQuery(m_db);
+ removeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountId = ? AND contactId = ?;"));
+ Q_FOREACH (const Tp::ContactPtr &c, toBeRemoved) {
+ const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
+ removeQuery.bindValue(0, contact->accountUniqueIdentifier());
+ removeQuery.bindValue(1, contact->id());
+ removeQuery.exec();
+ }
+
+ QSqlQuery insertQuery(m_db);
+ insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
+ Q_FOREACH (const Tp::ContactPtr &c, added) {
+ if (c->manager()->connection()->protocolName() == QLatin1String("local-xmpp")) {
+ continue;
+ }
+
+ const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
+ insertQuery.bindValue(0, contact->accountUniqueIdentifier());
+ insertQuery.bindValue(1, contact->id());
+ insertQuery.bindValue(2, contact->alias());
+ insertQuery.bindValue(3, contact->avatarData().fileName);
+ insertQuery.exec();
+ }
+
+ m_db.commit();
+}
+
+void ContactCache::connectToAccount(const Tp::AccountPtr &account)
+{
+ connect(account.data(), SIGNAL(removed()), SLOT(onAccountRemoved()));
+ connect(account.data(), SIGNAL(connectionChanged(Tp::ConnectionPtr)), SLOT(onAccountConnectionChanged(Tp::ConnectionPtr)));
+}
+
+bool ContactCache::accountIsInteresting(const Tp::AccountPtr &account) const
+{
+ if (account->protocolName() == QLatin1String("local-xmpp")) {// We don't want to cache local-xmpp contacts
+ return false;
+ }
+
+ /* There may be more filters. */
+
+ return true;
+}
+
+void ContactCache::syncContactsOfAccount(const Tp::AccountPtr &account)
+{
+ m_db.transaction();
+ QSqlQuery purgeQuery(m_db);
+ purgeQuery.prepare(QLatin1String("DELETE FROM contacts WHERE accountID = ?;"));
+ purgeQuery.bindValue(0, account->uniqueIdentifier());
+ purgeQuery.exec();
+
+ QSqlQuery insertQuery(m_db);
+ insertQuery.prepare(QLatin1String("INSERT INTO contacts (accountId, contactId, alias, avatarFileName) VALUES (?, ?, ?, ?);"));
+ Q_FOREACH (const Tp::ContactPtr &c, account->connection()->contactManager()->allKnownContacts()) {
+ const KTp::ContactPtr &contact = KTp::ContactPtr::qObjectCast(c);
+ insertQuery.bindValue(0, contact->accountUniqueIdentifier());
+ insertQuery.bindValue(1, contact->id());
+ insertQuery.bindValue(2, contact->alias());
+ insertQuery.bindValue(3, contact->avatarData().fileName);
+ insertQuery.exec();
+ }
+
+ m_db.commit();
+
+ connect(account->connection()->contactManager().data(),
+ SIGNAL(allKnownContactsChanged(Tp::Contacts,Tp::Contacts,Tp::Channel::GroupMemberChangeDetails)),
+ SLOT(onAllKnownContactsChanged(Tp::Contacts,Tp::Contacts)), Qt::UniqueConnection);
+}
+
+void ContactCache::checkContactManagerState(const Tp::ContactManagerPtr &contactManager)
+{
+ if (contactManager->state() == Tp::ContactListStateSuccess) {
+ const QString accountPath = TP_QT_ACCOUNT_OBJECT_PATH_BASE + QLatin1Char('/') + contactManager->connection()->property("accountUID").toString();
+ Tp::AccountPtr account = KTp::accountManager()->accountForObjectPath(accountPath);
+ if (!account.isNull()) {
+ syncContactsOfAccount(account);
+ } else {
+ kWarning() << "Can't access to account by contactManager";
+ }
+ }
+}
diff --git a/contact-cache.h b/contact-cache.h
new file mode 100644
index 0000000..8fa6fac
--- /dev/null
+++ b/contact-cache.h
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2014 David Edmundson <kde at davidedmundson.co.uk>
+ Copyright (C) 2014 Alexandr Akulich <akulichalexander at gmail.com>
+
+ This library 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 2.1 of the License, or (at your option) any later version.
+
+ This library 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 this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef CONTACTCACHE_H
+#define CONTACTCACHE_H
+
+#include <QObject>
+#include <QSqlDatabase>
+#include <TelepathyQt/Types>
+
+namespace Tp {
+class PendingOperation;
+}
+
+class ContactCache : public QObject
+{
+ Q_OBJECT
+
+public:
+ ContactCache(QObject *parent = 0);
+
+private Q_SLOTS:
+ void onAccountManagerReady(Tp::PendingOperation *op);
+ void onNewAccount(const Tp::AccountPtr &account);
+ void onAccountRemoved();
+ void onContactManagerStateChanged();
+ void onAccountConnectionChanged(const Tp::ConnectionPtr &connection);
+ void onAllKnownContactsChanged(const Tp::Contacts &added, const Tp::Contacts &removed);
+
+private:
+ void connectToAccount(const Tp::AccountPtr &account);
+ bool accountIsInteresting(const Tp::AccountPtr &account) const;
+ void syncContactsOfAccount(const Tp::AccountPtr &account);
+ void checkContactManagerState(const Tp::ContactManagerPtr &contactManager);
+ QSqlDatabase m_db;
+};
+
+#endif // CONTACTCACHE_H
diff --git a/contactnotify.cpp b/contactnotify.cpp
index 314d48a..9f001f4 100644
--- a/contactnotify.cpp
+++ b/contactnotify.cpp
@@ -28,6 +28,7 @@
#include <KAboutData>
#include <KConfigGroup>
+#include <KTp/core.h>
#include <KTp/presence.h>
#include <KTp/global-contact-manager.h>
@@ -42,8 +43,7 @@ ContactNotify::ContactNotify(const Tp::AccountManagerPtr &accountMgr, QObject *p
return;
}
- GlobalContactManager *contactManager = new GlobalContactManager(m_accountManager, this);
-
+ GlobalContactManager *contactManager = KTp::contactManager();
Tp::Presence currentPresence;
Q_FOREACH(const Tp::ContactPtr &contact, contactManager->allKnownContacts()) {
diff --git a/telepathy-module.cpp b/telepathy-module.cpp
index a754283..bf154c6 100644
--- a/telepathy-module.cpp
+++ b/telepathy-module.cpp
@@ -37,6 +37,7 @@
#include "telepathy-kded-module-plugin.h"
#include "contactnotify.h"
#include "screensaveraway.h"
+#include "contact-cache.h"
#include <KConfigGroup>
#include "contact-request-handler.h"
@@ -138,6 +139,8 @@ void TelepathyModule::onAccountManagerReady(Tp::PendingOperation* op)
m_contactHandler = new ContactRequestHandler(m_accountManager, this);
m_contactNotify = new ContactNotify(m_accountManager, this);
+ new ContactCache(this);
+
m_lastUserPresence = m_globalPresence->requestedPresence();
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..7696369
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,18 @@
+
+set(contactcache_test_SRCS
+ ../contact-cache.cpp
+ contact-cache-main.cpp
+)
+
+###
+
+kde4_add_executable(contact-cache
+ ${contactcache_test_SRCS}
+)
+
+target_link_libraries(contact-cache
+ ${QT_QTSQL_LIBRARY}
+ ${KDE4_KDECORE_LIBS}
+ ${TELEPATHY_QT4_LIBRARIES}
+ ${KTP_LIBRARIES}
+)
diff --git a/config/nowplaying-lineedit.h b/tests/contact-cache-main.cpp
similarity index 57%
copy from config/nowplaying-lineedit.h
copy to tests/contact-cache-main.cpp
index 23f2fee..1ffa308 100644
--- a/config/nowplaying-lineedit.h
+++ b/tests/contact-cache-main.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012 Othmane Moustaouda <othmane.moustaouda at gmail.com>
+ Copyright (C) 2014 Alexandr Akulich <akulichalexander at gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -16,28 +16,18 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "contact-cache.h"
-#ifndef NOWPLAYING_LINEEDIT_H
-#define NOWPLAYING_LINEEDIT_H
+#include <QCoreApplication>
-#include <QLineEdit>
+#include <TelepathyQt/Types>
-class NowPlayingLineEdit : public QLineEdit //krazy:exclude=qclasses
+int main(int argc, char *argv[])
{
- Q_OBJECT
+ QCoreApplication app(argc, argv);
+ Tp::registerTypes();
-public:
- NowPlayingLineEdit(QWidget *parent = 0);
- virtual ~NowPlayingLineEdit();
+ ContactCache cache(&app);
- void setLocalizedTagNames(QStringList tagNames);
-
-protected:
- void dropEvent(QDropEvent *event);
- void mousePressEvent(QMouseEvent *event);
-
-private:
- QStringList m_localizedTagNames;
-};
-
-#endif // NOWPLAYING_LINEEDIT_H
+ return app.exec();
+}
--
ktp-kded-integration-module packaging
More information about the pkg-kde-commits
mailing list