[ktp-common-internals/nepomuk-feeder] kpeople/nepomuk-feeder: CCMAIL: kde-telepathy at kde.org

David Edmundson kde at davidedmundson.co.uk
Sun Sep 22 13:52:17 UTC 2013


Git commit 20aad9c312d7e979214a583ce6e514a86f65d0db by David Edmundson, on behalf of Dario Freddi.
Committed on 10/05/2010 at 20:12.
Pushed by davidedmundson into branch 'nepomuk-feeder'.

CCMAIL: kde-telepathy at kde.org

Switch all SPARQL queries to the new Nepomuk::Query framework. This grants a more readable and maintainable code,
some optimizations in the queries for free, and overall a nice improvement.

Please note: this also increases the dependency to KDE 4.5. Also, you need some fixes in trunk since yesterday.

Signed-off-by: Dario Freddi <dario.freddi at collabora.co.uk>

svn path=/trunk/playground/network/telepathy-integration-daemon/; revision=1125152

M  +3    -1    kpeople/nepomuk-feeder/CMakeLists.txt
M  +54   -31   kpeople/nepomuk-feeder/telepathyaccount.cpp
M  +2    -0    kpeople/nepomuk-feeder/telepathyaccount.h
M  +65   -38   kpeople/nepomuk-feeder/telepathycontact.cpp

http://commits.kde.org/telepathy-common-internals/20aad9c312d7e979214a583ce6e514a86f65d0db

diff --git a/kpeople/nepomuk-feeder/CMakeLists.txt b/kpeople/nepomuk-feeder/CMakeLists.txt
index 31cc179..8dcdf4d 100644
--- a/kpeople/nepomuk-feeder/CMakeLists.txt
+++ b/kpeople/nepomuk-feeder/CMakeLists.txt
@@ -6,7 +6,8 @@ set (CMAKE_MODULE_PATH
      ${CMAKE_MODULE_PATH}
 )
 
-find_package (KDE4 REQUIRED)
+set(KDE_MIN_VERSION "4.4.75")
+find_package (KDE4 ${KDE_MIN_VERSION} REQUIRED)
 find_package (Nepomuk REQUIRED)
 find_package (TelepathyQt4 REQUIRED)
 set(SDO_MIN_VERSION "0.3.60")
@@ -108,6 +109,7 @@ target_link_libraries (telepathy-integration-daemon
                        ${KDE4_KDECORE_LIBS}
                        ${TELEPATHY_QT4_LIBRARIES}
                        ${NEPOMUK_LIBRARIES}
+                       ${NEPOMUK_QUERY_LIBRARIES}
                        nie
 )
 
diff --git a/kpeople/nepomuk-feeder/telepathyaccount.cpp b/kpeople/nepomuk-feeder/telepathyaccount.cpp
index a6a084b..4f143cf 100644
--- a/kpeople/nepomuk-feeder/telepathyaccount.cpp
+++ b/kpeople/nepomuk-feeder/telepathyaccount.cpp
@@ -32,13 +32,20 @@
 #include <dataobject.h>
 
 #include <KDebug>
+#include <kdeversion.h>
 
 #include <Nepomuk/ResourceManager>
 #include <Nepomuk/Variant>
 #include <Nepomuk/Resource>
 
-#include <Soprano/Model>
-#include <Soprano/QueryResultIterator>
+#include <Nepomuk/Query/Query>
+#include <Nepomuk/Query/AndTerm>
+#include <Nepomuk/Query/ComparisonTerm>
+#include <Nepomuk/Query/LiteralTerm>
+#include <Nepomuk/Query/ResourceTerm>
+#include <Nepomuk/Query/ResourceTypeTerm>
+#include <Nepomuk/Query/QueryServiceClient>
+#include <Nepomuk/Query/Result>
 
 #include <TelepathyQt4/ContactManager>
 #include <TelepathyQt4/PendingContacts>
@@ -110,19 +117,35 @@ void TelepathyAccount::doNepomukSetup()
     // Get a copy of the "me" PersonContact.
     Nepomuk::PersonContact mePersonContact = m_parent->mePersonContact();
 
-    // Query Nepomuk for all IMAccounts that the "me" PersonContact has.
-    QString query = QString("select distinct ?a where { %1 %2 ?a . ?a a %3 }")
-                            .arg(Soprano::Node::resourceToN3(mePersonContact.resourceUri()))
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::hasIMAccount()))
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::IMAccount()));
+    // Query Nepomuk for IMAccount that the "me" PersonContact has with a specific path
+    QList< Nepomuk::Query::Result > results;
+    {
+        using namespace Nepomuk::Query;
 
-    Soprano::Model *model = Nepomuk::ResourceManager::instance()->mainModel();
+        // Match the account
+        ComparisonTerm accountTerm(Nepomuk::Vocabulary::NCO::hasIMAccount(), ResourceTerm(mePersonContact));
+        accountTerm.setInverted(true);
 
-    Soprano::QueryResultIterator it = model->executeQuery(query, Soprano::Query::QueryLanguageSparql);
+        // Match the ID
+        ComparisonTerm pathTerm(Nepomuk::Vocabulary::Telepathy::accountIdentifier(),
+                                LiteralTerm(m_path), Nepomuk::Query::ComparisonTerm::Equal);
+
+        Query query(AndTerm(accountTerm, pathTerm,
+                            ResourceTypeTerm(Nepomuk::Vocabulary::NCO::IMAccount())));
+
+        bool queryResult = true;
+        results = QueryServiceClient::syncQuery(query, &queryResult);
+
+        if (!queryResult) {
+            // TODO: Maybe an error notification here?
+        }
+    }
+    // TODO: Maybe check if there is more than one result, and throw an error?
+    kDebug() << results.size();
 
     // Iterate over all the IMAccounts found.
-    while(it.next()) {
-        Nepomuk::IMAccount foundImAccount(it.binding("a").uri());
+    foreach (const Nepomuk::Query::Result &result, results) {
+        Nepomuk::IMAccount foundImAccount(result.resource());
         kDebug() << this << ": Found IM Account: " << foundImAccount.uri();
 
         // See if the Account has the same Telepathy Account Identifier as the account this
@@ -136,30 +159,26 @@ void TelepathyAccount::doNepomukSetup()
                      continue;
         }
 
-        // Exactly one identifier found. Check if it matches the one we are looking for.
-        QString accountIdentifier = accountIdentifiers.first();
-        kDebug() << this << ": Account Identifier:" << accountIdentifier;
-
-        if (accountIdentifier == m_path) {
-            kDebug() << this << ": Found the corresponding IMAccount in Nepomuk.";
-                // It matches, so set our member variable to it and stop looping.
-                m_accountResource = foundImAccount;
-
-                // Sync any properties that have changed on the AM behind our back.
-                if (m_accountResource.property(Nepomuk::Vocabulary::NCO::imNickname()) != m_account->nickname()) {
-                    onNicknameChanged(m_account->nickname());
-                }
-                onCurrentPresenceChanged(m_account->currentPresence()); // We can always assume this one needs syncing.
-                // FIXME: Can Protocol and account properties change?
+        kDebug() << this << ": Found the corresponding IMAccount in Nepomuk.";
+        // It matches, so set our member variable to it and stop looping.
+        m_accountResource = foundImAccount;
 
-                break;
+        // Sync any properties that have changed on the AM behind our back.
+        if (m_accountResource.property(Nepomuk::Vocabulary::NCO::imNickname()) != m_account->nickname()) {
+            onNicknameChanged(m_account->nickname());
         }
+        onCurrentPresenceChanged(m_account->currentPresence()); // We can always assume this one needs syncing.
+        // FIXME: Can Protocol and account properties change?
+
+        break;
     }
 
     // If the accountResource is still empty, create a new IMAccount.
     if (m_accountResource.uri().isEmpty()) {
         kDebug() << this << ": Could not find corresponding IMAccount in Nepomuk. Creating a new one.";
 
+        m_accountResource.addProperty(Nepomuk::Vocabulary::Telepathy::accountIdentifier(),
+                                      m_path);
         m_accountResource.addProperty(Nepomuk::Vocabulary::NCO::imAccountType(),
                                       m_account->protocol());
         // FIXME: Some IM Accounts don't have an ID as such, e.g. Link-Local-XMPP.
@@ -173,8 +192,7 @@ void TelepathyAccount::doNepomukSetup()
                                       m_account->currentPresence().statusMessage);
         m_accountResource.addProperty(Nepomuk::Vocabulary::Telepathy::statusType(),
                                       m_account->currentPresence().type);
-        m_accountResource.addProperty(Nepomuk::Vocabulary::Telepathy::accountIdentifier(),
-                                      m_path);
+        kDebug() << m_accountResource.uri();
 
         Nepomuk::InformationElement photo;
         photo.setPlainTextContents(QStringList() << m_account->avatar().avatarData.toBase64());
@@ -183,8 +201,8 @@ void TelepathyAccount::doNepomukSetup()
         m_accountResource.addProperty(Nepomuk::Vocabulary::NCO::photo(),
                                       dataObject);
 
-        mePersonContact.addProperty(Nepomuk::Vocabulary::NCO::hasIMAccount(),
-                                     m_accountResource);
+        mePersonContact.addIMAccount(m_accountResource);
+        kDebug() << mePersonContact.iMAccounts();
     }
 
     // Check if the account already has a connection, and
@@ -446,6 +464,11 @@ void TelepathyAccount::onAllKnownContactsChanged(const Tp::Contacts& added, cons
     }
 }
 
+TelepathyAccountMonitor* TelepathyAccount::monitor()
+{
+    return m_parent;
+}
+
 
 #include "telepathyaccount.moc"
 
diff --git a/kpeople/nepomuk-feeder/telepathyaccount.h b/kpeople/nepomuk-feeder/telepathyaccount.h
index 9e331b6..3b12df6 100644
--- a/kpeople/nepomuk-feeder/telepathyaccount.h
+++ b/kpeople/nepomuk-feeder/telepathyaccount.h
@@ -53,6 +53,8 @@ public:
     explicit TelepathyAccount(const QString &path, TelepathyAccountMonitor *parent = 0);
     ~TelepathyAccount();
 
+    TelepathyAccountMonitor *monitor();
+
 private Q_SLOTS:
     void onAccountReady(Tp::PendingOperation *op);
     void onHaveConnectionChanged(bool haveConnection);
diff --git a/kpeople/nepomuk-feeder/telepathycontact.cpp b/kpeople/nepomuk-feeder/telepathycontact.cpp
index ed52e11..909fecb 100644
--- a/kpeople/nepomuk-feeder/telepathycontact.cpp
+++ b/kpeople/nepomuk-feeder/telepathycontact.cpp
@@ -36,8 +36,16 @@
 #include <Nepomuk/ResourceManager>
 #include <Nepomuk/Variant>
 
-#include <Soprano/Model>
-#include <Soprano/QueryResultIterator>
+#include <Nepomuk/Query/Query>
+#include <Nepomuk/Query/QueryServiceClient>
+#include <Nepomuk/Query/AndTerm>
+#include <Nepomuk/Query/ComparisonTerm>
+#include <Nepomuk/Query/LiteralTerm>
+#include <Nepomuk/Query/NegationTerm>
+#include <Nepomuk/Query/ResourceTerm>
+#include <Nepomuk/Query/ResourceTypeTerm>
+#include <Nepomuk/Query/Result>
+#include "telepathyaccountmonitor.h"
 
 TelepathyContact::TelepathyContact(Tp::ContactPtr contact,
                                    Tp::ConnectionPtr connection,
@@ -111,21 +119,45 @@ TelepathyContact::~TelepathyContact()
 void TelepathyContact::doNepomukSetup()
 {
     // Query Nepomuk for all IM accounts that isBuddyOf the accountResource
-    QString query = QString("select distinct ?a ?b where { ?a %1 %2 . ?a a %3 . ?b %4 ?a . ?b a %5}")
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::Telepathy::isBuddyOf()))
-                            .arg(Soprano::Node::resourceToN3(m_accountResource.uri()))
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::IMAccount()))
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::hasIMAccount()))
-                            .arg(Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NCO::PersonContact()));
-
-    Soprano::Model *model = Nepomuk::ResourceManager::instance()->mainModel();
-
-    Soprano::QueryResultIterator it = model->executeQuery(query, Soprano::Query::QueryLanguageSparql);
+    QList< Nepomuk::Query::Result > results;
+    {
+        using namespace Nepomuk::Query;
+
+        // Get the person contact owning this IMAccount
+        ComparisonTerm pcterm(Nepomuk::Vocabulary::NCO::hasIMAccount(),
+                              ResourceTypeTerm(Nepomuk::Vocabulary::NCO::PersonContact()));
+        pcterm.setVariableName("person");
+        pcterm.setInverted(true);
+
+        // Get a copy of the "me" PersonContact.
+        Nepomuk::PersonContact mePersonContact = m_parent->monitor()->mePersonContact();
+        // Special case: if we're buddy of an account we do own, we want to create a new resource for that.
+        // This avoids race conditions and a lot of bad things.
+        ComparisonTerm accountTerm(Nepomuk::Vocabulary::NCO::hasIMAccount(), ResourceTerm(mePersonContact));
+        accountTerm.setInverted(true);
+
+        // And the ID has to match
+        ComparisonTerm idTerm(Nepomuk::Vocabulary::NCO::imID(),
+                              LiteralTerm(m_contact->id()), Nepomuk::Query::ComparisonTerm::Equal);
+
+        Query query(AndTerm(pcterm, idTerm, NegationTerm::negateTerm(accountTerm),
+                            ResourceTypeTerm(Nepomuk::Vocabulary::NCO::IMAccount())));
+
+        bool queryResult = true;
+        results = QueryServiceClient::syncQuery(query, &queryResult);
+
+        if (!queryResult) {
+            // TODO: Maybe an error notification here?
+        }
+    }
+    // TODO: Maybe check if there is more than one result, and throw an error?
+    kDebug() << "Querying contact " << m_contact->id() << m_accountResource.accountIdentifiers().first()
+             << ": found " << results.count();
 
     // Iterate over all the IMAccounts found.
-    while(it.next()) {
-        Nepomuk::IMAccount foundImAccount(it.binding("a").uri());
-        Nepomuk::IMAccount foundPersonContact(it.binding("b").uri());
+    foreach (const Nepomuk::Query::Result &result, results) {
+        Nepomuk::IMAccount foundImAccount(result.resource());
+        Nepomuk::IMAccount foundPersonContact(result.additionalBinding("person").uri());
 
         // Check that the IM account only has one ID.
         QStringList accountIDs = foundImAccount.imIDs();
@@ -137,31 +169,26 @@ void TelepathyContact::doNepomukSetup()
                      continue;
         }
 
-        // Exactly one ID found. Check if it matches the one we are looking for.
-        QString accountID = accountIDs.first();
-
-        if (accountID == m_contact->id()) {
-                // It matches, so set our member variables to found resources and stop looping.
-                m_contactIMAccountResource = foundImAccount;
-                m_contactPersonContactResource = foundPersonContact;
+        // It matches, so set our member variables to found resources and stop looping.
+        m_contactIMAccountResource = foundImAccount;
+        m_contactPersonContactResource = foundPersonContact;
 
-                // Sync any properties that may have changed since last time we were online.
-                if (m_contactIMAccountResource.property(Nepomuk::Vocabulary::NCO::imNickname())
-                    != m_contact->alias()) {
-                    onAliasChanged(m_contact->alias());
-                }
-                onPresenceChanged(m_contact->presenceStatus(),
-                                  m_contact->presenceType(),
-                                  m_contact->presenceMessage()); // We can always assume this one needs syncing.
-                // Call onAddedToGroup for all the groups this contact is in. (it will ignore ones
-                // where Nepomuk already knows the contact is in this group.
-                foreach (const QString &group, m_contact->groups()) {
-                    onAddedToGroup(group);
-                }
-                // FIXME: What other properties do we need to sync?
-
-                break;
+        // Sync any properties that may have changed since last time we were online.
+        if (m_contactIMAccountResource.property(Nepomuk::Vocabulary::NCO::imNickname())
+            != m_contact->alias()) {
+            onAliasChanged(m_contact->alias());
         }
+        onPresenceChanged(m_contact->presenceStatus(),
+                            m_contact->presenceType(),
+                            m_contact->presenceMessage()); // We can always assume this one needs syncing.
+        // Call onAddedToGroup for all the groups this contact is in. (it will ignore ones
+        // where Nepomuk already knows the contact is in this group.
+        foreach (const QString &group, m_contact->groups()) {
+            onAddedToGroup(group);
+        }
+        // FIXME: What other properties do we need to sync?
+
+        break;
     }
 
     // If the contactIMAccountResource is still empty, create a new IMAccount and PersonContact.



More information about the KDE-Telepathy mailing list