@ -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 | |||
) | |||
@ -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" | |||
} | |||
} |
@ -0,0 +1,95 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> | |||
SPDX-License-Identifier: GPL-2.0-only | |||
*/ | |||
#include "pepjob.h" | |||
#include "pepplugin_debug.h" | |||
#include <Akonadi/KMime/MessageParts> | |||
#include <AkonadiCore/RelationCreateJob> | |||
#include <AkonadiCore/ItemCreateJob> | |||
#include <AkonadiCore/ItemModifyJob> | |||
#include <AkonadiCore/Relation> | |||
#include <KMime/Message> | |||
#include <QCoreApplication> | |||
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<Akonadi::ItemCreateJob *>(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(); | |||
} |
@ -0,0 +1,41 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> | |||
SPDX-License-Identifier: GPL-2.0-only | |||
*/ | |||
#ifndef CREATENOTEJOB_H | |||
#define CREATENOTEJOB_H | |||
#include <KJob> | |||
#include <AkonadiCore/Item> | |||
#include <AkonadiCore/Collection> | |||
#include <Akonadi/Notes/NoteUtils> | |||
#include <kmime/kmime_message.h> | |||
#include <QObject> | |||
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 |
@ -0,0 +1,31 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2015-2020 Laurent Montel <montel@kde.org> | |||
SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#include "viewerpluginpep.h" | |||
#include "viewerpluginpepinterface.h" | |||
#include <KActionCollection> | |||
#include <KPluginFactory> | |||
using namespace MessageViewer; | |||
K_PLUGIN_CLASS_WITH_JSON(ViewerPluginpEp, "messageviewer_pepplugin.json") | |||
ViewerPluginpEp::ViewerPluginpEp(QObject *parent, const QList<QVariant> &) | |||
: 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" |
@ -0,0 +1,23 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2015-2020 Laurent Montel <montel@kde.org> | |||
SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#ifndef VIEWERPLUGINCREATENOTE_H | |||
#define VIEWERPLUGINCREATENOTE_H | |||
#include <MessageViewer/ViewerPlugin> | |||
#include <QVariant> | |||
namespace MessageViewer { | |||
class ViewerPluginpEp : public MessageViewer::ViewerPlugin | |||
{ | |||
Q_OBJECT | |||
public: | |||
explicit ViewerPluginpEp(QObject *parent = nullptr, const QList<QVariant> & = QList<QVariant>()); | |||
ViewerPluginInterface *createView(QWidget *parent, KActionCollection *ac) override; | |||
Q_REQUIRED_RESULT QString viewerPluginName() const override; | |||
}; | |||
} | |||
#endif // VIEWERPLUGINCREATENOTE_H |
@ -0,0 +1,167 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2015-2020 Laurent Montel <montel@kde.org> | |||
SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#include "viewerpluginpepinterface.h" | |||
#include "pepjob.h" | |||
#include "pepplugin_debug.h" | |||
#include <KLocalizedString> | |||
#include <KActionCollection> | |||
#include <QLayout> | |||
#include <QLabel> | |||
#include <QIcon> | |||
#include <QAction> | |||
#include <QPushButton> | |||
#include <QPainter> | |||
#include <QColor> | |||
#include <QStringLiteral> | |||
#include <QDBusInterface> | |||
#include <QDBusReply> | |||
#include <ItemFetchJob> | |||
#include <ItemFetchScope> | |||
#include <MessageViewer/CSSHelper> | |||
#include <KontactInterface/Core> | |||
#include <KontactInterface/PimUniqueApplication> | |||
#include <AkonadiCore/ServerManager> | |||
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<QAction *> 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<QVariant> 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<KMime::Message::Ptr>()); | |||
} | |||
} | |||
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<KMime::Message::Ptr>()); | |||
} | |||
} | |||
@ -0,0 +1,43 @@ | |||
/* | |||
SPDX-FileCopyrightText: 2015-2020 Laurent Montel <montel@kde.org> | |||
SPDX-License-Identifier: GPL-2.0-or-later | |||
*/ | |||
#ifndef VIEWERPLUGINCREATENOTEINTERFACE_H | |||
#define VIEWERPLUGINCREATENOTEINTERFACE_H | |||
#include <MessageViewer/ViewerPluginInterface> | |||
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<QAction *> 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<QAction *> mAction; | |||
QWidget *mStatusWidget = nullptr; | |||
}; | |||
} | |||
#endif // VIEWERPLUGINCREATENOTEINTERFACE_H |