|
|
|
@ -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"
|