playground/network/telepathy-integration-daemon

Dario Freddi drf at kde.org
Mon May 10 22:12:11 CEST 2010


SVN commit 1125152 by dafre:

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>

 M  +3 -1      CMakeLists.txt  
 M  +44 -21    telepathyaccount.cpp  
 M  +2 -0      telepathyaccount.h  
 M  +45 -18    telepathycontact.cpp  


--- trunk/playground/network/telepathy-integration-daemon/CMakeLists.txt #1125151:1125152
@@ -6,7 +6,8 @@
      ${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 @@
                        ${KDE4_KDECORE_LIBS}
                        ${TELEPATHY_QT4_LIBRARIES}
                        ${NEPOMUK_LIBRARIES}
+                       ${NEPOMUK_QUERY_LIBRARIES}
                        nie
 )
 
--- trunk/playground/network/telepathy-integration-daemon/telepathyaccount.cpp #1125151:1125152
@@ -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 @@
     // 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,11 +159,6 @@
                      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;
@@ -154,12 +172,13 @@
 
                 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 @@
                                       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 @@
         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 @@
     }
 }
 
+TelepathyAccountMonitor* TelepathyAccount::monitor()
+{
+    return m_parent;
+}
 
+
 #include "telepathyaccount.moc"
 
--- trunk/playground/network/telepathy-integration-daemon/telepathyaccount.h #1125151:1125152
@@ -53,6 +53,8 @@
     explicit TelepathyAccount(const QString &path, TelepathyAccountMonitor *parent = 0);
     ~TelepathyAccount();
 
+    TelepathyAccountMonitor *monitor();
+
 private Q_SLOTS:
     void onAccountReady(Tp::PendingOperation *op);
     void onHaveConnectionChanged(bool haveConnection);
--- trunk/playground/network/telepathy-integration-daemon/telepathycontact.cpp #1125151:1125152
@@ -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 @@
 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()));
+    QList< Nepomuk::Query::Result > results;
+    {
+        using namespace Nepomuk::Query;
 
-    Soprano::Model *model = Nepomuk::ResourceManager::instance()->mainModel();
+        // Get the person contact owning this IMAccount
+        ComparisonTerm pcterm(Nepomuk::Vocabulary::NCO::hasIMAccount(),
+                              ResourceTypeTerm(Nepomuk::Vocabulary::NCO::PersonContact()));
+        pcterm.setVariableName("person");
+        pcterm.setInverted(true);
 
-    Soprano::QueryResultIterator it = model->executeQuery(query, Soprano::Query::QueryLanguageSparql);
+        // 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,10 +169,6 @@
                      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;
@@ -162,7 +190,6 @@
 
                 break;
         }
-    }
 
     // If the contactIMAccountResource is still empty, create a new IMAccount and PersonContact.
     if (m_contactIMAccountResource.uri().isEmpty()) {


More information about the KDE-Telepathy mailing list