commit cf6060dd9f883a848877e8fe7453d74bf1f0999f Author: David Lanzendörfer Date: Sat Mar 13 19:41:32 2021 +0000 Initial commit diff --git a/messageviewerplugin/CMakeLists.txt b/messageviewerplugin/CMakeLists.txt new file mode 100644 index 0000000..241713b --- /dev/null +++ b/messageviewerplugin/CMakeLists.txt @@ -0,0 +1,26 @@ +set(messageviewer_pepplugin_SRCS + viewerpluginpep.cpp + viewerpluginpepinterface.cpp + pepjob.cpp +) + +ecm_qt_declare_logging_category(messageviewer_pepplugin_SRCS HEADER pepplugin_debug.h IDENTIFIER CREATENOTEPLUGIN_LOG CATEGORY_NAME org.kde.pim.pepplugin + DESCRIPTION "kdepim-addons (the p≡p plugin)" + OLD_CATEGORY_NAMES log_pepplugin + EXPORT KDEPIMADDONS +) + +kcoreaddons_add_plugin(messageviewer_pepplugin JSON messageviewer_pepplugin.json SOURCES + ${messageviewer_pepplugin_SRCS} INSTALL_NAMESPACE messageviewer/viewerplugin +) + +target_link_libraries(messageviewer_pepplugin + KF5::MessageViewer + KF5::XmlGui + KF5::CalendarCore + KF5::AkonadiNotes + KF5::IncidenceEditor + KF5::AkonadiWidgets + KF5::KontactInterface +) + diff --git a/messageviewerplugin/messageviewer_pepplugin.json b/messageviewerplugin/messageviewer_pepplugin.json new file mode 100644 index 0000000..5b43ff7 --- /dev/null +++ b/messageviewerplugin/messageviewer_pepplugin.json @@ -0,0 +1,14 @@ +{ + "KPlugin": { + "Description": "This plugin provides the p≡p interface (Pretty Easy Privacy)", + "EnabledByDefault": "true", + "Id": "messageviewerpepplugin", + "Name": "The p≡p plugin", + "ServiceTypes": [ + "MessageViewer/ViewerPlugin", + "MessageViewer/ViewerCommonPlugin", + "MessageViewerConfigureSettingsPlugin/Plugin" + ], + "Version": "2.0" + } +} diff --git a/messageviewerplugin/pepjob.cpp b/messageviewerplugin/pepjob.cpp new file mode 100644 index 0000000..59a2015 --- /dev/null +++ b/messageviewerplugin/pepjob.cpp @@ -0,0 +1,95 @@ +/* + SPDX-FileCopyrightText: 2014 Sandro Knauß + + SPDX-License-Identifier: GPL-2.0-only +*/ + +#include "pepjob.h" +#include "pepplugin_debug.h" +#include +#include +#include +#include +#include + +#include +#include + +using namespace MessageViewer; + +CreateNoteJob::CreateNoteJob(const KMime::Message::Ptr ¬ePtr, const Akonadi::Collection &collection, const Akonadi::Item &item, QObject *parent) + : KJob(parent) + , mItem(item) + , mCollection(collection) + , mNote(notePtr) +{ +} + +CreateNoteJob::~CreateNoteJob() +{ +} + +void CreateNoteJob::start() +{ + mNote.setFrom(QCoreApplication::applicationName() + QLatin1Char(' ') + QCoreApplication::applicationVersion()); + mNote.setLastModifiedDate(QDateTime::currentDateTimeUtc()); + if (!mItem.relations().isEmpty()) { + Akonadi::Relation relation; + const auto relations = mItem.relations(); + for (const Akonadi::Relation &r : relations) { + // assuming that GENERIC relations to emails are notes is a pretty horrific hack imo - aseigo + if (r.type() == Akonadi::Relation::GENERIC && r.right().mimeType() == Akonadi::NoteUtils::noteMimeType()) { + relation = r; + break; + } + } + + if (relation.isValid()) { + Akonadi::Item item = relation.right(); + item.setMimeType(Akonadi::NoteUtils::noteMimeType()); + item.setPayload(mNote.message()); + auto *modifyJob = new Akonadi::ItemModifyJob(item); + connect(modifyJob, &Akonadi::ItemModifyJob::result, this, &CreateNoteJob::noteUpdated); + return; + } + } + + Akonadi::Item newNoteItem; + newNoteItem.setMimeType(Akonadi::NoteUtils::noteMimeType()); + newNoteItem.setPayload(mNote.message()); + auto *createJob = new Akonadi::ItemCreateJob(newNoteItem, mCollection); + connect(createJob, &Akonadi::ItemCreateJob::result, this, &CreateNoteJob::noteCreated); +} + +void CreateNoteJob::noteCreated(KJob *job) +{ + if (job->error()) { + qCWarning(CREATENOTEPLUGIN_LOG) << "Error during create new Note " << job->errorString(); + setError(job->error()); + setErrorText(job->errorText()); + emitResult(); + } else { + auto *createJob = static_cast(job); + Akonadi::Relation relation(Akonadi::Relation::GENERIC, mItem, createJob->item()); + auto *rJob = new Akonadi::RelationCreateJob(relation); + connect(rJob, &Akonadi::RelationCreateJob::result, this, &CreateNoteJob::relationCreated); + } +} + +void CreateNoteJob::noteUpdated(KJob *job) +{ + if (job->error()) { + setError(job->error()); + setErrorText(job->errorText()); + } + + emitResult(); +} + +void CreateNoteJob::relationCreated(KJob *job) +{ + if (job->error()) { + qCDebug(CREATENOTEPLUGIN_LOG) << "Error during create new Note " << job->errorString(); + } + emitResult(); +} diff --git a/messageviewerplugin/pepjob.h b/messageviewerplugin/pepjob.h new file mode 100644 index 0000000..8fac790 --- /dev/null +++ b/messageviewerplugin/pepjob.h @@ -0,0 +1,41 @@ +/* + SPDX-FileCopyrightText: 2014 Sandro Knauß + + SPDX-License-Identifier: GPL-2.0-only +*/ + +#ifndef CREATENOTEJOB_H +#define CREATENOTEJOB_H + +#include +#include +#include +#include + +#include + +#include + +namespace MessageViewer { +class CreateNoteJob : public KJob +{ + Q_OBJECT +public: + explicit CreateNoteJob(const KMime::Message::Ptr ¬ePtr, const Akonadi::Collection &collection, const Akonadi::Item &item, QObject *parent = nullptr); + ~CreateNoteJob() override; + + void start() override; + +private Q_SLOTS: + void noteCreated(KJob *job); + void noteUpdated(KJob *job); + void relationCreated(KJob *job); + +private: + const Akonadi::Item mItem; + const Akonadi::Collection mCollection; + Akonadi::NoteUtils::NoteMessageWrapper mNote; +}; +} + +#endif diff --git a/messageviewerplugin/viewerpluginpep.cpp b/messageviewerplugin/viewerpluginpep.cpp new file mode 100644 index 0000000..f4b9989 --- /dev/null +++ b/messageviewerplugin/viewerpluginpep.cpp @@ -0,0 +1,31 @@ +/* + SPDX-FileCopyrightText: 2015-2020 Laurent Montel + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "viewerpluginpep.h" +#include "viewerpluginpepinterface.h" +#include +#include + +using namespace MessageViewer; +K_PLUGIN_CLASS_WITH_JSON(ViewerPluginpEp, "messageviewer_pepplugin.json") + +ViewerPluginpEp::ViewerPluginpEp(QObject *parent, const QList &) + : MessageViewer::ViewerPlugin(parent) +{ +} + +ViewerPluginInterface *ViewerPluginpEp::createView(QWidget *parent, KActionCollection *ac) +{ + MessageViewer::ViewerPluginInterface *view = new MessageViewer::pEpViewerInterface(ac, parent); + return view; +} + +QString ViewerPluginpEp::viewerPluginName() const +{ + return QStringLiteral("foo/bar"); +} + +#include "viewerpluginpep.moc" diff --git a/messageviewerplugin/viewerpluginpep.h b/messageviewerplugin/viewerpluginpep.h new file mode 100644 index 0000000..1e90bee --- /dev/null +++ b/messageviewerplugin/viewerpluginpep.h @@ -0,0 +1,23 @@ +/* + SPDX-FileCopyrightText: 2015-2020 Laurent Montel + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef VIEWERPLUGINCREATENOTE_H +#define VIEWERPLUGINCREATENOTE_H + +#include +#include +namespace MessageViewer { +class ViewerPluginpEp : public MessageViewer::ViewerPlugin +{ + Q_OBJECT +public: + explicit ViewerPluginpEp(QObject *parent = nullptr, const QList & = QList()); + + ViewerPluginInterface *createView(QWidget *parent, KActionCollection *ac) override; + Q_REQUIRED_RESULT QString viewerPluginName() const override; +}; +} +#endif // VIEWERPLUGINCREATENOTE_H diff --git a/messageviewerplugin/viewerpluginpepinterface.cpp b/messageviewerplugin/viewerpluginpepinterface.cpp new file mode 100644 index 0000000..ea730b6 --- /dev/null +++ b/messageviewerplugin/viewerpluginpepinterface.cpp @@ -0,0 +1,167 @@ +/* + SPDX-FileCopyrightText: 2015-2020 Laurent Montel + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#include "viewerpluginpepinterface.h" +#include "pepjob.h" +#include "pepplugin_debug.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +using namespace MessageViewer; + +pEpViewerInterface::pEpViewerInterface(KActionCollection *ac, QWidget *parent) + : ViewerPluginInterface(parent) +{ + QDBusInterface *pEpAgent = nullptr; + mStatusWidget = new QWidget(parent); + mStatusWidget->setFixedHeight(20); + parent->layout()->addWidget(mStatusWidget); + + const QString service = Akonadi::ServerManager::self()->agentServiceName(Akonadi::ServerManager::Agent, QStringLiteral("pEpAgent")); + qDebug() << service; + //qDebug() << QDBusConnection::sessionBus().objectRegisteredAt(service); + + pEpAgent = new QDBusInterface( + service, + QStringLiteral("/pEpAgent"), + QStringLiteral("org.freedesktop.Akonadi.Agent.pEpAgent"), + QDBusConnection::sessionBus() + ); + + if (pEpAgent->isValid()) { + m_pEpAgent = pEpAgent; + //qDebug() << m_pEpAgent->call(QStringLiteral("decryptMessage"), QVariant::fromValue(42)); + qDebug() << m_pEpAgent->call(QStringLiteral("resetIdentity")); + } else { + qDebug() << __FUNCTION__ << ": Could not connect to the pEp agent (" << pEpAgent->lastError().message() << ")"; + } + /*korgIface.call(QStringLiteral("showEventView")); + korgIface.call(QStringLiteral("showDate"), date);*/ + //} else { + // qDebug() << __FUNCTION__ << "Could not activate pEp agent"; + //} +} + + +pEpViewerInterface::~pEpViewerInterface() +{ + qDebug() << __FUNCTION__; +} + +void pEpViewerInterface::setText(const QString &text) +{ + qDebug() << __FUNCTION__; + //if(mTestWidget) mTestWidget->setText(text); + //Q_UNUSED(text); + //Nothing +} + +QList pEpViewerInterface::actions() const +{ + qDebug() << __FUNCTION__; + return mAction; +} + +bool pEpViewerInterface::isApEpMessage(KMime::Content *content) +{ + if(!content) + return false; + + if(content->attachments().size()) { + qDebug() << __FUNCTION__ << "Has attachments"; + for(KMime::Content *c : content->attachments()) { + //if(isApEpMessage(c)) return true; + isApEpMessage(c); + } + } else { + //qDebug() << content->decodedContent(); + } + + qDebug() << __FUNCTION__ << "Not a pEp message"; + //qDebug() << content->contentType()->name(); + + return false; +} + +void pEpViewerInterface::setMessage(const KMime::Message::Ptr &value) +{ + QByteArray type; + QDBusReply reply; + QVariant testload = QVariant(QStringLiteral("test")); + if(value) { + mMessage = value; + if(!m_pEpAgent) { qDebug() << "DBus not connected"; return; } // We're not connected to the agent + type = mMessage->contentType()->mimeType(); + if(type==QByteArray("multipart/mixed")) { + qDebug() << "Multipart detected"; + } else if(type==QByteArray("multipart/encrypted")) { + qDebug() << "Encrypted message detected"; + //reply = m_pEpAgent->call(QStringLiteral("decryptMessage"), mMessage); + reply = m_pEpAgent->call(QStringLiteral("decryptMessage"), testload); + qDebug() << reply; + } else { + qDebug() << type; + } + //value->mainBodyPart()->assemble(); + //if(isApEpMessage(value->mainBodyPart())) qDebug() << "pEp message detected"; + //else qDebug() << "Not a pEp message"; + } +} + +void pEpViewerInterface::closePlugin() +{ + qDebug() << __FUNCTION__; +} + +void pEpViewerInterface::showWidget() +{ + qDebug() << __FUNCTION__; +} + +void pEpViewerInterface::setMessageItem(const Akonadi::Item &item) +{ + mMessageItem = item; + if(item.hasPayload()) { + setMessage(item.payload()); + } +} + +ViewerPluginInterface::SpecificFeatureTypes pEpViewerInterface::featureTypes() const +{ + qDebug() << __FUNCTION__; + return ViewerPluginInterface::NeedMessage; +} + +void pEpViewerInterface::updateAction(const Akonadi::Item &item) +{ + qDebug() << __FUNCTION__; + mMessageItem = item; + if(item.hasPayload()) { + setMessage(item.payload()); + } +} + diff --git a/messageviewerplugin/viewerpluginpepinterface.h b/messageviewerplugin/viewerpluginpepinterface.h new file mode 100644 index 0000000..ac59bd5 --- /dev/null +++ b/messageviewerplugin/viewerpluginpepinterface.h @@ -0,0 +1,43 @@ +/* + SPDX-FileCopyrightText: 2015-2020 Laurent Montel + + SPDX-License-Identifier: GPL-2.0-or-later +*/ + +#ifndef VIEWERPLUGINCREATENOTEINTERFACE_H +#define VIEWERPLUGINCREATENOTEINTERFACE_H + +#include +class KActionCollection; +class QLabel; +class QDBusInterface; + +namespace MessageViewer { +class pEpViewerInterface : public ViewerPluginInterface +{ + Q_OBJECT +public: + explicit pEpViewerInterface(KActionCollection *ac, QWidget *parent = nullptr); + ~pEpViewerInterface() override; + + void setText(const QString &text) override; + Q_REQUIRED_RESULT QList actions() const override; + void setMessage(const KMime::Message::Ptr &value) override; + void closePlugin() override; + void showWidget() override; + void setMessageItem(const Akonadi::Item &item) override; + void updateAction(const Akonadi::Item &item) override; + Q_REQUIRED_RESULT ViewerPluginInterface::SpecificFeatureTypes featureTypes() const override; + //Q_REQUIRED_RESULT MessageViewer::ViewerPluginInterface *createView(QWidget *parent, KActionCollection *ac); + +private: + QDBusInterface *m_pEpAgent = nullptr; + bool isApEpMessage(KMime::Content *c); + + KMime::Message::Ptr mMessage; + Akonadi::Item mMessageItem; + QList mAction; + QWidget *mStatusWidget = nullptr; +}; +} +#endif // VIEWERPLUGINCREATENOTEINTERFACE_H