7#include "filterimporterakonadi.h"
8#include "mailimporterakonadi_debug.h"
9#include <Akonadi/CollectionCreateJob>
10#include <Akonadi/CollectionFetchJob>
11#include <Akonadi/Item>
12#include <Akonadi/ItemCreateJob>
13#include <Akonadi/ItemFetchJob>
14#include <Akonadi/ItemFetchScope>
15#include <Akonadi/MessageFlags>
16#include <Akonadi/MessageParts>
17#include <KLocalizedString>
18#include <MailImporter/FilterInfo>
20#include <QScopedPointer>
23using namespace MailImporter;
30FilterImporterAkonadi::~FilterImporterAkonadi()
34void FilterImporterAkonadi::clear()
36 mMessageFolderMessageIDMap.clear();
37 mMessageFolderCollectionMap.clear();
41Akonadi::MessageStatus FilterImporterAkonadi::convertToAkonadiMessageStatus(
const MailImporter::MessageStatus &
status)
43 Akonadi::MessageStatus akonadiStatus;
50 if (
status.isForwarded()) {
59Akonadi::Collection FilterImporterAkonadi::rootCollection()
const
61 return mRootCollection;
64void FilterImporterAkonadi::setRootCollection(
const Akonadi::Collection &collection)
66 mRootCollection = collection;
69QString FilterImporterAkonadi::topLevelFolder()
const
71 return mRootCollection.
name();
74bool FilterImporterAkonadi::importMessage(
const QString &folderName,
75 const QString &msgPath,
77 const MailImporter::MessageStatus &mailImporterstatus)
79 const Akonadi::MessageStatus
status = convertToAkonadiMessageStatus(mailImporterstatus);
82 Akonadi::Collection mailFolder = parseFolderString(folderName);
88 msgText = f.readAll();
91 qCWarning(MAILIMPORTERAKONADI_LOG) <<
"Failed to read temporary file: " << f.errorString();
94 mInfo->addErrorLogEntry(
i18n(
"Error: failed to read temporary file at %1", msgPath));
100 newMessage->setContent(msgText);
103 if (duplicateCheck) {
105 const KMime::Headers::Base *messageIDHeader = newMessage->messageID(
false);
106 if (messageIDHeader) {
112 if (checkForDuplicates(messageID, mailFolder, folderName)) {
121 addAkonadiMessage(mailFolder, newMessage,
status);
123 mInfo->alert(
i18n(
"<b>Warning:</b> Got a bad message folder, adding to root folder."));
124 addAkonadiMessage(rootCollection(), newMessage,
status);
127 qCWarning(MAILIMPORTERAKONADI_LOG) <<
"Url is not temporary file: " << msgUrl;
132Akonadi::Collection FilterImporterAkonadi::parseFolderString(
const QString &folderParseString)
135 const Akonadi::Collection col = mMessageFolderCollectionMap.value(folderParseString);
143 QString folderBuilder;
144 Akonadi::Collection lastCollection;
147 for (
const QString &folder : folderList) {
149 mMessageFolderCollectionMap[folder] = addSubCollection(rootCollection(), folder);
150 folderBuilder = folder;
151 lastCollection = mMessageFolderCollectionMap[folder];
154 folderBuilder += QLatin1Char(
'/') + folder;
155 mMessageFolderCollectionMap[folderBuilder] = addSubCollection(lastCollection, folder);
156 lastCollection = mMessageFolderCollectionMap[folderBuilder];
160 return lastCollection;
163Akonadi::Collection FilterImporterAkonadi::addSubCollection(
const Akonadi::Collection &baseCollection,
const QString &newCollectionPathName)
167 if (!fetchJob->exec()) {
168 mInfo->alert(
i18n(
"<b>Warning:</b> Could not check that the folder already exists. Reason: %1", fetchJob->errorString()));
169 return Akonadi::Collection();
172 for (
const Akonadi::Collection &subCollection : lstCols) {
173 if (subCollection.name() == newCollectionPathName) {
174 return subCollection;
179 Akonadi::Collection newSubCollection;
181 newSubCollection.
setName(newCollectionPathName);
183 auto job =
new Akonadi::CollectionCreateJob(newSubCollection);
185 mInfo->alert(
i18n(
"<b>Error:</b> Could not create folder. Reason: %1", job->errorString()));
186 return Akonadi::Collection();
189 Akonadi::Collection collection = job->collection();
193bool FilterImporterAkonadi::checkForDuplicates(
const QString &msgID,
const Akonadi::Collection &msgCollection,
const QString &messageFolder)
195 bool folderFound =
false;
198 QMultiMap<QString, QString>::const_iterator
end(mMessageFolderMessageIDMap.constEnd());
199 for (QMultiMap<QString, QString>::const_iterator it = mMessageFolderMessageIDMap.constBegin(); it != end; ++it) {
200 if (it.key() == messageFolder) {
209 Akonadi::ItemFetchJob job(msgCollection);
212 mInfo->addInfoLogEntry(
213 i18n(
"<b>Warning:</b> Could not fetch mail in folder %1. Reason: %2"
214 " You may have duplicate messages.",
219 for (
const Akonadi::Item &messageItem : items) {
220 if (!messageItem.isValid()) {
221 mInfo->addInfoLogEntry(
i18n(
"<b>Warning:</b> Got an invalid message in folder %1.", messageFolder));
227 const KMime::Headers::Base *messageID = message->messageID(
false);
229 if (!messageID->isEmpty()) {
230 mMessageFolderMessageIDMap.insert(messageFolder, messageID->asUnicodeString());
240 QMultiMap<QString, QString>::const_iterator endMsgID(mMessageFolderMessageIDMap.constEnd());
241 for (QMultiMap<QString, QString>::const_iterator it = mMessageFolderMessageIDMap.constBegin(); it != endMsgID; ++it) {
242 if (it.key() == messageFolder && it.value() == msgID) {
248 mMessageFolderMessageIDMap.insert(messageFolder, msgID);
252bool FilterImporterAkonadi::addAkonadiMessage(
const Akonadi::Collection &collection,
const KMime::Message::Ptr &message, Akonadi::MessageStatus
status)
256 item.
setMimeType(QStringLiteral(
"message/rfc822"));
258 if (
status.isOfUnknownStatus()) {
259 KMime::Headers::Base *statusHeaders = message->headerByType(
"X-Status");
261 if (!statusHeaders->
isEmpty()) {
272 QScopedPointer<Akonadi::ItemCreateJob> job(
new Akonadi::ItemCreateJob(item, collection));
273 job->setAutoDelete(
false);
275 mInfo->alert(
i18n(
"<b>Error:</b> Could not add message to folder %1. Reason: %2", collection.
name(), job->errorString()));
281void FilterImporterAkonadi::clearCountDuplicate()
283 mCountDuplicates = 0;
286int FilterImporterAkonadi::countDuplicates()
const
288 return mCountDuplicates;
291bool FilterImporterAkonadi::importMessage(
const KArchiveFile *file,
const QString &folderPath,
int &nbTotal,
int &fileDone)
293 const Akonadi::Collection collection = parseFolderString(folderPath);
295 mInfo->addErrorLogEntry(
i18n(
"Unable to retrieve folder for folder path %1.", folderPath));
300 newMessage->setContent(file->
data());
303 if (mInfo->removeDupMessage()) {
304 KMime::Headers::MessageID *messageId = newMessage->messageID(
false);
308 if (checkForDuplicates(messageIdStr, collection, folderPath)) {
316 const bool result = addAkonadiMessage(collection, newMessage, Akonadi::MessageStatus());
void setParentCollection(const Collection &parent)
void setName(const QString &name)
void setPayload(const T &p)
void setMimeType(const QString &mimeType)
void setFlags(const Flags &flags)
void setRead(bool read=true)
void setForwarded(bool forwarded=true)
void setDeleted(bool deleted=true)
void setReplied(bool replied=true)
virtual QByteArray data() const
QSharedPointer< Message > Ptr
The FilterImporterBase class.
Q_SCRIPTABLE CaptureState status()
QString i18n(const char *text, const TYPE &arg...)
AKONADI_MIME_EXPORT void copyMessageFlags(KMime::Message &from, Akonadi::Item &to)
AKONADI_MIME_EXPORT const char Header[]
const QList< QKeySequence > & end()
bool isEmpty() const const
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QUrl fromLocalFile(const QString &localFile)
bool isEmpty() const const
bool isLocalFile() const const
QString toLocalFile() const const