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: [email protected] 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 <[email protected]> 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. _______________________________________________ KDE-Telepathy mailing list [email protected] https://mail.kde.org/mailman/listinfo/kde-telepathy
