[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