File indexing completed on 2024-11-10 04:50:08
0001 /* 0002 SPDX-FileCopyrightText: 2011 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "filtermanager.h" 0008 #include "mailcommon_debug.h" 0009 0010 #include "filteractions/filteractiondict.h" 0011 #include "filterimporterexporter.h" 0012 #include "mailfilteragentinterface.h" 0013 #include <Akonadi/Monitor> 0014 #include <Akonadi/Tag> 0015 #include <Akonadi/TagAttribute> 0016 #include <Akonadi/TagFetchJob> 0017 #include <Akonadi/TagFetchScope> 0018 #include <KConfigGroup> 0019 0020 #include <QTimer> 0021 0022 namespace MailCommon 0023 { 0024 class FilterManager::FilterManagerPrivate 0025 { 0026 public: 0027 FilterManagerPrivate(FilterManager *qq) 0028 : q(qq) 0029 , mMonitor(new Akonadi::Monitor) 0030 { 0031 const auto service = Akonadi::ServerManager::agentServiceName(Akonadi::ServerManager::Agent, QStringLiteral("akonadi_mailfilter_agent")); 0032 mMailFilterAgentInterface = 0033 new org::freedesktop::Akonadi::MailFilterAgent(service, QStringLiteral("/MailFilterAgent"), QDBusConnection::sessionBus(), q); 0034 } 0035 0036 void readConfig(); 0037 void writeConfig(bool withSync = true) const; 0038 void clear(); 0039 0040 QMap<QUrl, QString> mTagList; 0041 static FilterManager *mInstance; 0042 static FilterActionDict *mFilterActionDict; 0043 0044 FilterManager *const q; 0045 OrgFreedesktopAkonadiMailFilterAgentInterface *mMailFilterAgentInterface = nullptr; 0046 QList<MailCommon::MailFilter *> mFilters; 0047 Akonadi::Monitor *const mMonitor; 0048 bool mInitialized = false; 0049 }; 0050 0051 void FilterManager::FilterManagerPrivate::readConfig() 0052 { 0053 KSharedConfig::Ptr config = 0054 KSharedConfig::openConfig(Akonadi::ServerManager::addNamespace(QStringLiteral("akonadi_mailfilter_agent")) + QStringLiteral("rc")); 0055 clear(); 0056 QStringList emptyFilters; 0057 mFilters = FilterImporterExporter::readFiltersFromConfig(config, emptyFilters); 0058 Q_EMIT q->filtersChanged(); 0059 } 0060 0061 void FilterManager::FilterManagerPrivate::writeConfig(bool withSync) const 0062 { 0063 KSharedConfig::Ptr config = 0064 KSharedConfig::openConfig(Akonadi::ServerManager::addNamespace(QStringLiteral("akonadi_mailfilter_agent")) + QStringLiteral("rc")); 0065 0066 // Now, write out the new stuff: 0067 FilterImporterExporter::writeFiltersToConfig(mFilters, config); 0068 KConfigGroup group = config->group("General"); 0069 0070 if (withSync) { 0071 group.sync(); 0072 } 0073 } 0074 0075 void FilterManager::FilterManagerPrivate::clear() 0076 { 0077 qDeleteAll(mFilters); 0078 mFilters.clear(); 0079 } 0080 } 0081 0082 using namespace MailCommon; 0083 0084 FilterManager *FilterManager::FilterManagerPrivate::mInstance = nullptr; 0085 FilterActionDict *FilterManager::FilterManagerPrivate::mFilterActionDict = nullptr; 0086 0087 FilterManager *FilterManager::instance() 0088 { 0089 if (!FilterManager::FilterManagerPrivate::mInstance) { 0090 FilterManager::FilterManagerPrivate::mInstance = new FilterManager; 0091 } 0092 0093 return FilterManager::FilterManagerPrivate::mInstance; 0094 } 0095 0096 FilterActionDict *FilterManager::filterActionDict() 0097 { 0098 if (!FilterManager::FilterManagerPrivate::mFilterActionDict) { 0099 FilterManager::FilterManagerPrivate::mFilterActionDict = new FilterActionDict; 0100 } 0101 0102 return FilterManager::FilterManagerPrivate::mFilterActionDict; 0103 } 0104 0105 FilterManager::FilterManager() 0106 : d(new FilterManagerPrivate(this)) 0107 { 0108 updateTagList(); 0109 0110 d->mMonitor->setObjectName(QLatin1StringView("FilterManagerTagMonitor")); 0111 d->mMonitor->setTypeMonitored(Akonadi::Monitor::Tags); 0112 d->mMonitor->tagFetchScope().fetchAttribute<Akonadi::TagAttribute>(); 0113 connect(d->mMonitor, &Akonadi::Monitor::tagAdded, this, &FilterManager::slotTagAdded); 0114 connect(d->mMonitor, &Akonadi::Monitor::tagRemoved, this, &FilterManager::slotTagRemoved); 0115 connect(d->mMonitor, &Akonadi::Monitor::tagChanged, this, &FilterManager::slotTagChanged); 0116 0117 qDBusRegisterMetaType<QList<qint64>>(); 0118 Akonadi::ServerManager::State state = Akonadi::ServerManager::self()->state(); 0119 if (state == Akonadi::ServerManager::Running) { 0120 QTimer::singleShot(0, this, &FilterManager::slotReadConfig); 0121 } else { 0122 connect(Akonadi::ServerManager::self(), &Akonadi::ServerManager::stateChanged, this, &FilterManager::slotServerStateChanged); 0123 } 0124 } 0125 0126 FilterManager::~FilterManager() 0127 { 0128 cleanup(); 0129 } 0130 0131 void FilterManager::cleanup() 0132 { 0133 d->clear(); 0134 } 0135 0136 void FilterManager::slotServerStateChanged(Akonadi::ServerManager::State state) 0137 { 0138 if (state == Akonadi::ServerManager::Running) { 0139 d->readConfig(); 0140 disconnect(Akonadi::ServerManager::self(), SIGNAL(stateChanged(Akonadi::ServerManager::State))); 0141 } 0142 } 0143 0144 void FilterManager::updateTagList() 0145 { 0146 auto fetchJob = new Akonadi::TagFetchJob(this); 0147 fetchJob->fetchScope().fetchAttribute<Akonadi::TagAttribute>(); 0148 connect(fetchJob, &Akonadi::TagFetchJob::result, this, &FilterManager::slotFinishedTagListing); 0149 } 0150 0151 bool FilterManager::initialized() const 0152 { 0153 return d->mInitialized; 0154 } 0155 0156 void FilterManager::slotReadConfig() 0157 { 0158 d->readConfig(); 0159 d->mInitialized = true; 0160 Q_EMIT loadingFiltersDone(); 0161 } 0162 0163 void FilterManager::slotFinishedTagListing(KJob *job) 0164 { 0165 if (job->error()) { 0166 qCWarning(MAILCOMMON_LOG) << "failed to retrieve tags " << job->errorString(); 0167 } 0168 auto fetchJob = static_cast<Akonadi::TagFetchJob *>(job); 0169 const Akonadi::Tag::List lstTags = fetchJob->tags(); 0170 for (const Akonadi::Tag &tag : lstTags) { 0171 d->mTagList.insert(tag.url(), tag.name()); 0172 } 0173 0174 Q_EMIT tagListingFinished(); 0175 } 0176 0177 void FilterManager::slotTagAdded(const Akonadi::Tag &tag) 0178 { 0179 d->mTagList.insert(tag.url(), tag.name()); 0180 Q_EMIT tagListingFinished(); 0181 } 0182 0183 void FilterManager::slotTagChanged(const Akonadi::Tag &tag) 0184 { 0185 if (d->mTagList.contains(tag.url())) { 0186 d->mTagList.insert(tag.url(), tag.name()); 0187 } 0188 Q_EMIT tagListingFinished(); 0189 } 0190 0191 void FilterManager::slotTagRemoved(const Akonadi::Tag &tag) 0192 { 0193 d->mTagList.remove(tag.url()); 0194 Q_EMIT tagListingFinished(); 0195 } 0196 0197 QMap<QUrl, QString> FilterManager::tagList() const 0198 { 0199 return d->mTagList; 0200 } 0201 0202 bool FilterManager::isValid() const 0203 { 0204 return d->mMailFilterAgentInterface->isValid(); 0205 } 0206 0207 QString FilterManager::createUniqueFilterName(const QString &name) const 0208 { 0209 return d->mMailFilterAgentInterface->createUniqueName(name); 0210 } 0211 0212 void FilterManager::showFilterLogDialog(qlonglong windowId) 0213 { 0214 d->mMailFilterAgentInterface->showFilterLogDialog(windowId); 0215 } 0216 0217 void FilterManager::filter(const Akonadi::Item &item, const QString &identifier, const QString &resourceId) const 0218 { 0219 d->mMailFilterAgentInterface->filter(item.id(), identifier, resourceId); 0220 } 0221 0222 void FilterManager::filter(const Akonadi::Item &item, FilterSet set, bool account, const QString &resourceId) const 0223 { 0224 d->mMailFilterAgentInterface->filterItem(item.id(), static_cast<int>(set), account ? resourceId : QString()); 0225 } 0226 0227 void FilterManager::filter(const Akonadi::Collection &collection, FilterSet set) const 0228 { 0229 filter(Akonadi::Collection::List{collection}, set); 0230 } 0231 0232 void FilterManager::filter(const Akonadi::Collection::List &collections, FilterSet set) const 0233 { 0234 QList<qint64> colIds; 0235 colIds.reserve(collections.size()); 0236 for (const auto &col : collections) { 0237 colIds << col.id(); 0238 } 0239 0240 d->mMailFilterAgentInterface->filterCollections(colIds, static_cast<int>(set)); 0241 } 0242 0243 void FilterManager::filter(const Akonadi::Collection &collection, const QStringList &listFilters) const 0244 { 0245 filter(Akonadi::Collection::List{collection}, listFilters); 0246 } 0247 0248 void FilterManager::filter(const Akonadi::Collection::List &collections, const QStringList &listFilters, FilterSet set) const 0249 { 0250 QList<qint64> colIds; 0251 colIds.reserve(collections.size()); 0252 for (const auto &col : collections) { 0253 colIds << col.id(); 0254 } 0255 0256 d->mMailFilterAgentInterface->applySpecificFiltersOnCollections(colIds, listFilters, static_cast<int>(set)); 0257 } 0258 0259 void FilterManager::filter(const Akonadi::Item::List &messages, FilterManager::FilterSet set) const 0260 { 0261 QList<qint64> itemIds; 0262 0263 itemIds.reserve(messages.size()); 0264 for (const Akonadi::Item &item : messages) { 0265 itemIds << item.id(); 0266 } 0267 0268 d->mMailFilterAgentInterface->filterItems(itemIds, static_cast<int>(set)); 0269 } 0270 0271 void FilterManager::filter(const Akonadi::Item::List &messages, SearchRule::RequiredPart requiredPart, const QStringList &listFilters) const 0272 { 0273 QList<qint64> itemIds; 0274 0275 itemIds.reserve(messages.size()); 0276 for (const Akonadi::Item &item : messages) { 0277 itemIds << item.id(); 0278 } 0279 d->mMailFilterAgentInterface->applySpecificFilters(itemIds, static_cast<int>(requiredPart), listFilters); 0280 } 0281 0282 void FilterManager::setFilters(const QList<MailCommon::MailFilter *> &filters) 0283 { 0284 beginUpdate(); 0285 d->clear(); 0286 d->mFilters = filters; 0287 endUpdate(); 0288 } 0289 0290 QList<MailCommon::MailFilter *> FilterManager::filters() const 0291 { 0292 return d->mFilters; 0293 } 0294 0295 void FilterManager::appendFilters(const QList<MailCommon::MailFilter *> &filters, bool replaceIfNameExists) 0296 { 0297 beginUpdate(); 0298 if (replaceIfNameExists) { 0299 for (const MailCommon::MailFilter *newFilter : filters) { 0300 int numberOfFilters = d->mFilters.count(); 0301 for (int i = 0; i < numberOfFilters; ++i) { 0302 MailCommon::MailFilter *filter = d->mFilters.at(i); 0303 if (newFilter->name() == filter->name()) { 0304 d->mFilters.removeAll(filter); 0305 i = 0; 0306 numberOfFilters = d->mFilters.count(); 0307 } 0308 } 0309 } 0310 } 0311 0312 d->mFilters += filters; 0313 endUpdate(); 0314 } 0315 0316 void FilterManager::removeFilter(MailCommon::MailFilter *filter) 0317 { 0318 beginUpdate(); 0319 d->mFilters.removeAll(filter); 0320 endUpdate(); 0321 } 0322 0323 void FilterManager::beginUpdate() 0324 { 0325 } 0326 0327 void FilterManager::endUpdate() 0328 { 0329 d->writeConfig(true); 0330 d->mMailFilterAgentInterface->reload(); 0331 Q_EMIT filtersChanged(); 0332 } 0333 0334 #include "moc_filtermanager.cpp"