[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [baloo] src/pim: Implement note indexer
From:       Montel Laurent <montel () kde ! org>
Date:       2014-02-25 12:25:30
Message-ID: E1WIH4k-0006M1-Ia () scm ! kde ! org
[Download RAW message or body]

Git commit ce8ae7a0fdb3f5a5b378d08c4af44181334cf8fc by Montel Laurent.
Committed on 25/02/2014 at 12:25.
Pushed by mlaurent into branch 'master'.

Implement note indexer

M  +2    -1    src/pim/agent/CMakeLists.txt
M  +13   -0    src/pim/agent/agent.cpp
A  +122  -0    src/pim/agent/akonotesindexer.cpp     [License: LGPL]
A  +58   -0    src/pim/agent/akonotesindexer.h     [License: LGPL]
M  +8    -4    src/pim/agent/autotests/indexertest.cpp
M  +29   -0    src/pim/akonadiplugin/searchplugin.cpp
M  +1    -0    src/pim/search/CMakeLists.txt
A  +13   -0    src/pim/search/note/CMakeLists.txt
A  +4    -0    src/pim/search/note/baloo_notesearchstore.desktop
A  +46   -0    src/pim/search/note/notesearchstore.cpp     [License: LGPL]
A  +41   -0    src/pim/search/note/notesearchstore.h     [License: LGPL]

http://commits.kde.org/baloo/ce8ae7a0fdb3f5a5b378d08c4af44181334cf8fc

diff --git a/src/pim/agent/CMakeLists.txt b/src/pim/agent/CMakeLists.txt
index 387a18d..d475001 100644
--- a/src/pim/agent/CMakeLists.txt
+++ b/src/pim/agent/CMakeLists.txt
@@ -11,6 +11,7 @@ set(akonadi_baloo_indexer_SRCS
     agent.cpp
     emailindexer.cpp
     contactindexer.cpp
+    akonotesindexer.cpp
 )
 
 qt4_add_dbus_adaptor(akonadi_baloo_indexer_SRCS org.freedesktop.Akonadi.BalooIndexer.xml \
agent.h BalooIndexingAgent) @@ -32,4 +33,4 @@ install(FILES akonadibalooindexingagent.desktop
         DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents")
 
 add_subdirectory(tests)
-add_subdirectory(autotests)
\ No newline at end of file
+add_subdirectory(autotests)
diff --git a/src/pim/agent/agent.cpp b/src/pim/agent/agent.cpp
index 8481c1c..d760d99 100644
--- a/src/pim/agent/agent.cpp
+++ b/src/pim/agent/agent.cpp
@@ -24,6 +24,7 @@
 
 #include "contactindexer.h"
 #include "emailindexer.h"
+#include "akonotesindexer.h"
 #include "balooindexeradaptor.h"
 
 #include <Akonadi/ItemFetchJob>
@@ -46,6 +47,9 @@ namespace {
     QString emailContactsIndexingPath() {
         return KStandardDirs::locateLocal("data", "baloo/emailContacts/");
     }
+    QString akonotesIndexingPath() {
+        return KStandardDirs::locateLocal("data", "baloo/notes/");
+    }
 }
 
 BalooIndexingAgent::BalooIndexingAgent(const QString& id)
@@ -122,6 +126,15 @@ void BalooIndexingAgent::createIndexers()
         delete indexer;
         kError() << "Failed to create contact indexer:" << \
QString::fromStdString(e.get_msg());  }
+
+    try {
+        indexer = new AkonotesIndexer(akonotesIndexingPath());
+        addIndexer(indexer);
+    }
+    catch (const Xapian::DatabaseError &e) {
+        delete indexer;
+        kError() << "Failed to create akonotes indexer:" << \
QString::fromStdString(e.get_msg()); +    }
 }
 
 void BalooIndexingAgent::addIndexer(AbstractIndexer* indexer)
diff --git a/src/pim/agent/akonotesindexer.cpp b/src/pim/agent/akonotesindexer.cpp
new file mode 100644
index 0000000..c3e73a7
--- /dev/null
+++ b/src/pim/agent/akonotesindexer.cpp
@@ -0,0 +1,122 @@
+/*
+ * This file is part of the KDE Baloo Project
+ * Copyright (C) 2014 Laurent Montel <montel@kde.org>
+ *
+ * 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) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "akonotesindexer.h"
+
+
+AkonotesIndexer::AkonotesIndexer(const QString& path)
+    : AbstractIndexer()
+{
+    m_db = new Xapian::WritableDatabase(path.toStdString(), Xapian::DB_CREATE_OR_OPEN);
+}
+
+AkonotesIndexer::~AkonotesIndexer()
+{
+    m_db->commit();
+    delete m_db;
+}
+
+QStringList AkonotesIndexer::mimeTypes() const
+{
+    return QStringList() << QString::fromLatin1( "text/x-vnd.akonadi.note" );
+}
+
+void AkonotesIndexer::index(const Akonadi::Item &item)
+{
+    KMime::Message::Ptr msg;
+    try {
+        msg = item.payload<KMime::Message::Ptr>();
+    } catch (const Akonadi::PayloadException&) {
+        return;
+    }
+    m_doc = new Xapian::Document();
+    m_termGen = new Xapian::TermGenerator();
+    m_termGen->set_document(*m_doc);
+    m_termGen->set_database(*m_db);
+
+    process(msg);
+
+    Akonadi::Entity::Id colId = item.parentCollection().id();
+    QByteArray term = 'C' + QByteArray::number(colId);
+    m_doc->add_boolean_term(term.data());
+
+    m_db->replace_document(item.id(), *m_doc);
+
+    delete m_doc;
+    delete m_termGen;
+
+    m_doc = 0;
+    m_termGen = 0;
+}
+
+void AkonotesIndexer::process(const KMime::Message::Ptr &msg)
+{
+    //
+    // Process Headers
+    // (Give the subject a higher priority)
+    KMime::Headers::Subject* subject = msg->subject(false);
+    if (subject) {
+        std::string str(subject->asUnicodeString().toUtf8().constData());
+        kDebug() << "Indexing" << str.c_str();
+        m_termGen->index_text_without_positions(str, 1, "S");
+        m_termGen->index_text_without_positions(str, 100);
+        m_doc->set_data(str);
+    }
+
+    KMime::Content* mainBody = msg->mainBodyPart("text/plain");
+    const std::string text(mainBody->decodedText().toUtf8().constData());
+    m_termGen->index_text_without_positions(text);
+    m_termGen->index_text_without_positions(text, 1, "BO");
+}
+
+void AkonotesIndexer::commit()
+{
+    m_db->commit();
+}
+
+void AkonotesIndexer::remove(const Akonadi::Item &item)
+{
+    try {
+        m_db->delete_document(item.id());
+    }
+    catch (const Xapian::DocNotFoundError&) {
+        return;
+    }
+}
+
+void AkonotesIndexer::remove(const Akonadi::Collection& collection)
+{
+    try {
+        Xapian::Query query('C'+ QString::number(collection.id()).toStdString());
+        Xapian::Enquire enquire(*m_db);
+        enquire.set_query(query);
+
+        Xapian::MSet mset = enquire.get_mset(0, m_db->get_doccount());
+        for (Xapian::MSetIterator it = mset.begin(); it != mset.end(); it++) {
+            qint64 id = *it;
+            remove(Akonadi::Item(id));
+        }
+    }
+    catch (const Xapian::DocNotFoundError&) {
+        return;
+    }
+}
diff --git a/src/pim/agent/akonotesindexer.h b/src/pim/agent/akonotesindexer.h
new file mode 100644
index 0000000..d90301c
--- /dev/null
+++ b/src/pim/agent/akonotesindexer.h
@@ -0,0 +1,58 @@
+/*
+ * This file is part of the KDE Baloo Project
+ * Copyright (C) 2014 Laurent Montel <montel@kde.org>
+ *
+ * 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) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef AKONOTESINDEXER_H
+#define AKONOTESINDEXER_H
+
+#include "abstractindexer.h"
+
+#include <KMime/Message>
+#include <Akonadi/Collection>
+#include <Akonadi/Item>
+
+#include <xapian.h>
+
+class AkonotesIndexer : public AbstractIndexer
+{
+public:
+    /**
+     * You must provide the path where the indexed information
+     * should be stored
+     */
+    AkonotesIndexer(const QString& path);
+    ~AkonotesIndexer();
+
+    QStringList mimeTypes() const;
+
+    void index(const Akonadi::Item &item);
+    void commit();
+
+    void remove(const Akonadi::Item &item);
+    void remove(const Akonadi::Collection &collection);
+private:
+    void process(const KMime::Message::Ptr &msg);
+    Xapian::WritableDatabase *m_db;
+    Xapian::Document *m_doc;
+    Xapian::TermGenerator *m_termGen;
+};
+
+#endif // AKONOTESINDEXER_H
diff --git a/src/pim/agent/autotests/indexertest.cpp b/src/pim/agent/autotests/indexertest.cpp
index 1d64c80..6e0d4db 100644
--- a/src/pim/agent/autotests/indexertest.cpp
+++ b/src/pim/agent/autotests/indexertest.cpp
@@ -31,8 +31,8 @@
 #include <../pim/search/contact/contactsearchstore.h>
 #include <query.h>
 
-Q_DECLARE_METATYPE(QSet<qint64>);
-Q_DECLARE_METATYPE(QList<qint64>);
+Q_DECLARE_METATYPE(QSet<qint64>)
+Q_DECLARE_METATYPE(QList<qint64>)
 
 class IndexerTest : public QObject
 {
@@ -41,6 +41,7 @@ private:
     QString emailDir;
     QString emailContactsDir;
     QString contactsDir;
+    QString notesDir;
 
     bool removeDir(const QString & dirName)
     {
@@ -70,6 +71,7 @@ private Q_SLOTS:
         emailDir = QDir::tempPath() + "/searchplugintest/baloo/email/";
         emailContactsDir = QDir::tempPath() + "/searchplugintest/baloo/emailcontacts/";
         contactsDir = QDir::tempPath() + "/searchplugintest/baloo/contacts/";
+        notesDir = QDir::tempPath() + "/searchplugintest/baloo/notes/";
 
         QDir dir;
         removeDir(emailDir);
@@ -78,10 +80,13 @@ private Q_SLOTS:
         QVERIFY(dir.mkpath(emailContactsDir));
         removeDir(contactsDir);
         QVERIFY(dir.mkpath(contactsDir));
+        removeDir(notesDir);
+        QVERIFY(dir.mkpath(notesDir));
 
         kDebug() << "indexing sample data";
         kDebug() << emailDir;
         kDebug() << emailContactsDir;
+        kDebug() << notesDir;
 
 //         EmailIndexer emailIndexer(emailDir, emailContactsDir);
 //         ContactIndexer contactIndexer(contactsDir);
@@ -114,7 +119,7 @@ private Q_SLOTS:
         return resultSet;
     }
 
-    void testRemoveByCollection() {
+    void testEmailRemoveByCollection() {
         EmailIndexer emailIndexer(emailDir, emailContactsDir);
         {
             KMime::Message::Ptr msg(new KMime::Message);
@@ -144,7 +149,6 @@ private Q_SLOTS:
         emailIndexer.commit();
         QCOMPARE(getAllItems(), QSet<qint64>() << 1);
     }
-
 };
 
 QTEST_MAIN(IndexerTest)
diff --git a/src/pim/akonadiplugin/searchplugin.cpp b/src/pim/akonadiplugin/searchplugin.cpp
index 69500aa..b8f225c 100644
--- a/src/pim/akonadiplugin/searchplugin.cpp
+++ b/src/pim/akonadiplugin/searchplugin.cpp
@@ -179,6 +179,32 @@ Baloo::Term recursiveEmailTermMapping(const Akonadi::SearchTerm &term)
     return Baloo::Term();
 }
 
+Baloo::Term recursiveNoteTermMapping(const Akonadi::SearchTerm &term)
+{
+    if (!term.subTerms().isEmpty()) {
+        Baloo::Term t(mapRelation(term.relation()));
+        Q_FOREACH (const Akonadi::SearchTerm &subterm, term.subTerms()) {
+            const Baloo::Term newTerm = recursiveNoteTermMapping(subterm);
+            if (newTerm.isValid()) {
+                t.addSubTerm(newTerm);
+            }
+        }
+        return t;
+    } else {
+        kDebug() << term.key() << term.value();
+        const Akonadi::EmailSearchTerm::EmailSearchField field = \
Akonadi::EmailSearchTerm::fromKey(term.key()); +        switch (field) {
+        case Akonadi::EmailSearchTerm::Subject:
+            return getTerm(term, "subject");
+        case Akonadi::EmailSearchTerm::Body:
+            return getTerm(term, "body");
+        default:
+            kWarning() << "unknown term " << term.key();
+        }
+    }
+    return Baloo::Term();
+}
+
 Baloo::Term recursiveContactTermMapping(const Akonadi::SearchTerm &term)
 {
     if (!term.subTerms().isEmpty()) {
@@ -233,6 +259,9 @@ QSet<qint64> SearchPlugin::search(const QString &akonadiQuery, const \
QList<qint6  } else if (mimeTypes.contains("text/directory")) {
         query.setType("Contact");
         t = recursiveContactTermMapping(term);
+    } else if (mimeTypes.contains(QLatin1String("text/x-vnd.akonadi.note"))) {
+        query.setType("Note");
+        t = recursiveNoteTermMapping(term);
     } else if (mimeTypes.contains("...")) {
         query.setType("ContactGroups");
         //TODO contactgroup queries
diff --git a/src/pim/search/CMakeLists.txt b/src/pim/search/CMakeLists.txt
index fe5013f..6dafdc0 100644
--- a/src/pim/search/CMakeLists.txt
+++ b/src/pim/search/CMakeLists.txt
@@ -1,2 +1,3 @@
 add_subdirectory(email)
 add_subdirectory(contact)
+add_subdirectory(note)
diff --git a/src/pim/search/note/CMakeLists.txt b/src/pim/search/note/CMakeLists.txt
new file mode 100644
index 0000000..9437952
--- /dev/null
+++ b/src/pim/search/note/CMakeLists.txt
@@ -0,0 +1,13 @@
+kde4_add_plugin(baloo_notesearchstore notesearchstore.cpp ../pimsearchstore.cpp)
+
+target_link_libraries(baloo_notesearchstore
+    ${QT_QTCORE_LIBRARY}
+    ${KDE4_KDECORE_LIBRARY}
+    ${XAPIAN_LIBRARIES}
+    baloocore
+    baloopim
+    balooxapian
+)
+
+install(FILES baloo_notesearchstore.desktop DESTINATION ${SERVICES_INSTALL_DIR})
+install(TARGETS baloo_notesearchstore DESTINATION ${PLUGIN_INSTALL_DIR})
diff --git a/src/pim/search/note/baloo_notesearchstore.desktop \
b/src/pim/search/note/baloo_notesearchstore.desktop new file mode 100644
index 0000000..c11e28e
--- /dev/null
+++ b/src/pim/search/note/baloo_notesearchstore.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Service
+X-KDE-ServiceTypes=BalooSearchStore
+X-KDE-Library=baloo_notesearchstore
diff --git a/src/pim/search/note/notesearchstore.cpp b/src/pim/search/note/notesearchstore.cpp
new file mode 100644
index 0000000..e0af291
--- /dev/null
+++ b/src/pim/search/note/notesearchstore.cpp
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the KDE Baloo Project
+ * Copyright (C) 2014 Laurent Montel <montel@kde.org>
+ *
+ * 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) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "notesearchstore.h"
+
+#include <KStandardDirs>
+#include <KDebug>
+
+using namespace Baloo;
+
+NoteSearchStore::NoteSearchStore(QObject* parent)
+    : PIMSearchStore(parent)
+{
+    m_prefix.insert("subject", "S");
+    m_prefix.insert("collection", "C");
+    m_prefix.insert("body", "BO");
+
+    const QString path = KStandardDirs::locateLocal("data", "baloo/notes/");
+    setDbPath(path);
+}
+
+QStringList NoteSearchStore::types()
+{
+    return QStringList() << "Akonadi" << "Note";
+}
+
+BALOO_EXPORT_SEARCHSTORE(Baloo::NoteSearchStore, "baloo_notesearchstore")
diff --git a/src/pim/search/note/notesearchstore.h b/src/pim/search/note/notesearchstore.h
new file mode 100644
index 0000000..725f694
--- /dev/null
+++ b/src/pim/search/note/notesearchstore.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the KDE Baloo Project
+ * Copyright (C) 2014 Laurent Montel <montel@kde.org>
+ *
+ * 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) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef BALOO_PIM_NOTES_SEARCHSTORE_H
+#define BALOO_PIM_NOTES_SEARCHSTORE_H
+
+#include "../pimsearchstore.h"
+
+namespace Baloo {
+
+class NoteSearchStore : public PIMSearchStore
+{
+    Q_OBJECT
+    Q_INTERFACES(Baloo::SearchStore)
+public:
+    NoteSearchStore(QObject* parent = 0);
+
+    virtual QStringList types();
+};
+
+}
+#endif // BALOO_PIM_NOTES_SEARCHSTORE_H


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic