Initial commit

master
David Lanzendörfer 2021-03-13 19:41:58 +00:00
parent cf6060dd9f
commit b824f362fe
8 changed files with 447 additions and 0 deletions

View File

@ -0,0 +1,54 @@
set(pepagent_SRCS
pepagent.cpp
#pepselectjob.cpp
#pepscheduler.cpp
#pepagent_debug.cpp
)
kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/pepagent.kcfg org.kde.Akonadi.pEpAgent.Settings)
qt5_add_dbus_adaptor(pepagent_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Akonadi.pEpAgent.xml pepagent.h pEpAgent
)
ecm_qt_declare_logging_category(pepagent_SRCS HEADER pepagent_debug.h IDENTIFIER PEPAGENT_LOG CATEGORY_NAME org.kde.pim.pepagent
DESCRIPTION "kmail (pepagent)"
OLD_CATEGORY_NAMES log_pepagent
EXPORT KMAIL
)
add_executable(akonadi_pep_agent ${pepagent_SRCS})
target_link_libraries(akonadi_pep_agent
KF5::AkonadiCore
KF5::AkonadiMime
KF5::Mime
KF5::MailTransportAkonadi
KF5::AkonadiAgentBase
KF5::MailTransportAkonadi
KF5::I18n
KF5::Notifications
KF5::GrantleeTheme
Grantlee5::Templates
KF5::MailCommon
Qt5::Core
Qt5::DBus
Qt5::Network
KF5::AkonadiCore
KF5::IMAP
KF5::MailTransport
KF5::KIOWidgets
KF5::Mime
KF5::AkonadiMime
KF5::IdentityManagement
KF5::AkonadiAgentBase
KF5::I18n
KF5::WindowSystem
KF5::PimCommon
KF5::Libkdepim
)
install( TARGETS akonadi_pep_agent ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} )
install( FILES pepagent.desktop DESTINATION "${KDE_INSTALL_DATAROOTDIR}/akonadi/agents" )
install( FILES akonadi_pep_agent.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFY5RCDIR} )

View File

@ -0,0 +1,11 @@
[Global]
IconName=akonadi-pep
Name=p≡p engine agent
Comment=Akonadi adapter to the p≡p engine
[Event/emailsent]
Name=E-mail successfully sent
Action=Popup
IconName=mail-mark-junk
Urgency=Critical

View File

@ -0,0 +1,12 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.Akonadi.Agent.pEpAgent">
<method name="resetIdentity"/>
<method name="decryptMessage" >
<arg direction="in" type="(iiii)" name="message" />
<arg direction="out" type="(iiii)" name="message" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="const KMime::Message::Ptr &amp;"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QpEpMessage"/>
</method>
</interface>
</node>

View File

@ -0,0 +1,338 @@
/*
SPDX-FileCopyrightText: 2008 Ingo Klöcker <kloecker@kde.org>
SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "pepagent.h"
#include "pepagent_debug.h"
#include "pepagentadaptor.h"
#include "qpepmessage.h" // A hack to ram this shit throug QDbus
#include <Akonadi/KMime/Pop3ResourceAttribute>
#include <AkonadiCore/ServerManager>
#include <AkonadiCore/CollectionFetchJob>
#include <AkonadiCore/CollectionFetchScope>
#include <AkonadiCore/AgentManager>
#include <AkonadiCore/AttributeFactory>
#include <AkonadiCore/Monitor>
#include <AkonadiCore/Session>
#include <AkonadiCore/ItemFetchScope>
#include <AkonadiCore/ChangeRecorder>
#include <AkonadiAgentBase/ResourceBase>
#include <AkonadiCore/EntityDisplayAttribute>
#include <MailCommon/MailKernel>
#include <KI18n/KLocalizedString>
#include <GrantleeTheme/GrantleeKi18nLocalizer>
using namespace Akonadi;
pEpAgent::pEpAgent(const QString &id)
: ResourceBase(id)
{
Q_D(pEpAgent);
new PEpAgentAdaptor(this);
//d->scheduler = new pEpScheduler(this);
const QString service = Akonadi::ServerManager::self()->agentServiceName(Akonadi::ServerManager::Agent, QStringLiteral("pEpAgent"));
QDBusConnection::sessionBus().registerService(service);
qDebug() << __FUNCTION__ << "Registered as " << service;
Akonadi::AttributeFactory::registerAttribute<Akonadi::Pop3ResourceAttribute>();
//mTheKernel = new DummyKernel(this);
//CommonKernel->registerKernelIf(mMailFilterKernel); //register KernelIf early, it is used by the Filter classes
//CommonKernel->registerSettingsIf(mMailFilterKernel); //SettingsIf is used in FolderTreeWidget
/*m_filterManager = new FilterManager(this);
connect(m_filterManager, &FilterManager::percent, this, &pEpAgent::emitProgress);
connect(m_filterManager, &FilterManager::progressMessage, this, &pEpAgent::emitProgressMessage);*/
auto *collectionMonitor = new Akonadi::Monitor(this);
collectionMonitor->setObjectName(QStringLiteral("pEpCollectionMonitor"));
collectionMonitor->fetchCollection(true);
collectionMonitor->ignoreSession(Akonadi::Session::defaultSession());
collectionMonitor->collectionFetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::All);
collectionMonitor->setMimeTypeMonitored(KMime::Message::mimeType());
connect(collectionMonitor, &Akonadi::Monitor::collectionAdded, this, &pEpAgent::mailCollectionAdded);
connect(collectionMonitor, qOverload<const Akonadi::Collection &>(&Akonadi::Monitor::collectionChanged), this, &pEpAgent::mailCollectionChanged);
connect(collectionMonitor, &Akonadi::Monitor::collectionRemoved, this, &pEpAgent::mailCollectionRemoved);
connect(Akonadi::AgentManager::self(), &Akonadi::AgentManager::instanceRemoved, this, &pEpAgent::slotInstanceRemoved);
QTimer::singleShot(0, this, &pEpAgent::initializeCollections);
qDBusRegisterMetaType<QList<qint64> >();
QDBusConnection::sessionBus().registerObject(QStringLiteral("/pEpAgent"), this, QDBusConnection::ExportAdaptors);
/*
//Enabled or not filterlogdialog
KSharedConfig::Ptr config = KSharedConfig::openConfig();
if (config->hasGroup("FilterLog")) {
KConfigGroup group(config, "FilterLog");
if (group.readEntry("Enabled", false)) {
KNotification *notify = new KNotification(QStringLiteral("mailfilterlogenabled"));
notify->setComponentName(QApplication::applicationDisplayName());
notify->setIconName(QStringLiteral("view-filter"));
notify->setText(i18nc("Notification when the filter log was enabled", "Mail Filter Log Enabled"));
notify->sendEvent();
}
}
changeRecorder()->itemFetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent);
changeRecorder()->itemFetchScope().setCacheOnly(true);
changeRecorder()->fetchCollection(true);
changeRecorder()->setChangeRecordingEnabled(false);
*/
mProgressCounter = 0;
mProgressTimer = new QTimer(this);
//connect(mProgressTimer, &QTimer::timeout, this, [this]() {
// emitProgress();
//});
auto *itemMonitor = new Akonadi::Monitor(this);
itemMonitor->setObjectName(QStringLiteral("pEpItemMonitor"));
itemMonitor->itemFetchScope().setFetchRemoteIdentification(true);
itemMonitor->itemFetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent);
connect(itemMonitor, &Akonadi::Monitor::itemChanged, this, &pEpAgent::slotItemChanged);
//new pEpSelectJob(identifier());
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
}
//pEpAgent::~pEpAgent()
//{}
void pEpAgent::initializeCollections()
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob(Akonadi::Collection::root(),
Akonadi::CollectionFetchJob::Recursive,
this);
job->fetchScope(); //.setContentMimeTypes({ QStringLiteral("multipart/encrypted") });
connect(job, &Akonadi::CollectionFetchJob::result, this, &pEpAgent::initialCollectionFetchingDone);
}
void pEpAgent::emitProgress(int p)
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
if (p == 0) {
mProgressTimer->stop();
Q_EMIT status(AgentBase::Idle, QString());
}
mProgressCounter = p;
Q_EMIT percent(p);
}
void pEpAgent::emitProgressMessage(const QString &message)
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
Q_EMIT status(AgentBase::Running, message);
if (status() == AgentBase::Idle) {
// If still idle after aborting, clear 'aborted' status.
Q_EMIT status(AgentBase::Idle, i18n("Ready to dispatch messages."));
}
}
void pEpAgent::itemsReceiviedForFiltering(const Akonadi::Item::List &items)
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
if (items.isEmpty()) {
qCDebug(PEPAGENT_LOG) << "pEpAgent::itemsReceiviedForFiltering items is empty!";
return;
}
Akonadi::Item item = items.first();
if (!item.hasPayload()) {
qCDebug(PEPAGENT_LOG) << "pEpAgent::itemsReceiviedForFiltering item has no payload!";
return;
}
/*Akonadi::MessageStatus status;
status.setStatusFromFlags(item.flags());
if (status.isRead() || status.isSpam() || status.isIgnored()) {
return;
}*/
QString resource = sender()->property("resource").toString();
const Akonadi::Pop3ResourceAttribute *pop3ResourceAttribute = item.attribute<Akonadi::Pop3ResourceAttribute>();
if (pop3ResourceAttribute) {
resource = pop3ResourceAttribute->pop3AccountName();
}
emitProgressMessage(i18n("Filtering in %1", Akonadi::AgentManager::self()->instance(resource).name()));
/*if (!m_filterManager->process(item, m_filterManager->requiredPart(resource), FilterManager::Inbound, true, resource)) {
qCWarning(PEPAGENT_LOG) << "Impossible to process mails";
}*/
emitProgress(++mProgressCounter);
mProgressTimer->start(1000);
}
void pEpAgent::clearMessage()
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
//Q_EMIT status(AgentBase::Idle, QString("p≡p engine ready"));
}
void pEpAgent::emitStatusReady()
{
if (status() == AgentBase::Idle) {
// If still idle after aborting, clear 'aborted' status.
Q_EMIT status(AgentBase::Idle, i18n("p≡p engine ready"));
}
}
bool pEpAgent::isFilterableCollection(const Akonadi::Collection &collection) const
{
// TODO: Do this smarter
if(QStringLiteral("INBOX")==collection.name()) {
qDebug() << __FUNCTION__ << "Found an INBOX folder";
return true;
}
if(QStringLiteral("inbox")==collection.name()) {
qDebug() << __FUNCTION__ << "Found an INBOX folder";
return true;
}
qDebug() << __FUNCTION__ << "Not yet supported folder name: " << collection.name();
return false;
}
void pEpAgent::initialCollectionFetchingDone(KJob *job)
{
qDebug() << __FUNCTION__ << " Test";
if (job->error()) {
qDebug() << job->errorString();
return;
}
const auto fetchJob = qobject_cast<Akonadi::CollectionFetchJob *>(job);
const auto pop3ResourceMap = MailCommon::Kernel::pop3ResourceTargetCollection();
const auto lstCols = fetchJob->collections();
for (const Akonadi::Collection &collection : lstCols) { // All the folders of all the accounts
if(isFilterableCollection(collection)) {
changeRecorder()->setCollectionMonitored(collection, true);
}
}
Q_EMIT status(AgentBase::Idle, i18n("Ready"));
Q_EMIT percent(100);
QTimer::singleShot(2000, this, &pEpAgent::clearMessage);
}
void pEpAgent::slotItemChanged(const Akonadi::Item &item)
{
qCDebug(PEPAGENT_LOG) << __FUNCTION__ << " Test";
qDebug() << __FUNCTION__ << " Test";
/*if (item.remoteId().isEmpty()) {
return;
}
// now we have the remoteId
itemMonitor->setItemMonitored(item, false);
filterItem(item, item.parentCollection());*/
}
void pEpAgent::mailCollectionRemoved(const Akonadi::Collection &collection)
{
changeRecorder()->setCollectionMonitored(collection, false);
}
void pEpAgent::mailCollectionChanged(const Akonadi::Collection &collection)
{
changeRecorder()->setCollectionMonitored(collection, isFilterableCollection(collection));
}
void pEpAgent::mailCollectionAdded(const Akonadi::Collection &collection, const Akonadi::Collection &)
{
if (isFilterableCollection(collection)) {
changeRecorder()->setCollectionMonitored(collection, true);
}
}
void pEpAgent::slotInstanceRemoved(const Akonadi::AgentInstance &instance)
{
//m_filterManager->agentRemoved(instance.identifier());
}
void pEpAgent::itemAdded(const Akonadi::Item &item, const Akonadi::Collection &collection)
{
/* The monitor mimetype filter would override the collection filter, therefor we have to check
* for the mimetype of the item here.
*/
/*if (item.mimeType() != KMime::Message::mimeType()) {
qCDebug(MAILFILTERAGENT_LOG) << "MailFilterAgent::itemAdded called for a non-message item!";
return;
}
if (item.remoteId().isEmpty()) {
itemMonitor->setItemMonitored(item);
} else {
filterItem(item, collection);
}*/
}
void pEpAgent::configure(WId windowId)
{
qDebug() << __FUNCTION__ << "Test";
}
void pEpAgent::retrieveCollections()
{
qDebug() << __FUNCTION__ << "Test";
Akonadi::Collection::List collections;
Akonadi::Collection topLevel;
topLevel.setName(identifier());
topLevel.setRemoteId(identifier());
topLevel.setParentCollection(Akonadi::Collection::root());
topLevel.setContentMimeTypes({Akonadi::Collection::mimeType()});
topLevel.setRights(Akonadi::Collection::ReadOnly);
auto topLevelDisplayAttr = topLevel.attribute<Akonadi::EntityDisplayAttribute>(Akonadi::Collection::AddIfMissing);
topLevelDisplayAttr->setDisplayName(i18n("p≡p Engine"));
topLevelDisplayAttr->setActiveIconName(QStringLiteral("akonadi-pep"));
collections.push_back(topLevel);
collectionsRetrieved(std::move(collections));
}
void pEpAgent::resetIdentity()
{
qDebug() << __FUNCTION__ << "Test";
}
pEpMessage pEpAgent::decryptMessage(const KMime::Message::Ptr &value){
qDebug() << __FUNCTION__ << "Test";
return m;
}
AKONADI_RESOURCE_MAIN(pEpAgent)
#include "moc_pepagent.cpp"

View File

@ -0,0 +1,10 @@
[Desktop Entry]
Name=p≡p engine agent
Comment=Akonadi adapter to the p≡p engine
Type=AkonadiResource
Exec=akonadi_pep_agent
Icon=akonadi-pep
X-Akonadi-MimeTypes=message/rfc822
X-Akonadi-Capabilities=Resource,Unique,Autostart
X-Akonadi-Identifier=akonadi_pep_agent

View File

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:kcfg="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
<kcfgfile name="pepagentrc"/>
<group name="General">
<entry name="Outbox" type="LongLong">
<label>Outbox collection id</label>
<default>-1</default>
</entry>
<entry name="SentMail" type="LongLong">
<label>Sent Mail collection id</label>
<default>-1</default>
</entry>
</group>
</kcfg>

View File

@ -0,0 +1,4 @@
class pEpAgentPrivate;
//: public Akonadi::AgentBasePrivate
//{
//};