File indexing completed on 2024-12-22 05:05:26
0001 /* 0002 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "exportmailjobinterface.h" 0008 #include "importexportmailutil.h" 0009 0010 #include <MailCommon/FilterImporterExporter> 0011 0012 #include <MailTransport/TransportManager> 0013 0014 #include <KLocalizedString> 0015 #include <KZip> 0016 #include <QTemporaryFile> 0017 0018 #include "pimdataexportcore_debug.h" 0019 #include "resourceconverterimpl.h" 0020 #include <KMime/Message> 0021 #include <QDir> 0022 #include <QFile> 0023 #include <QRegularExpression> 0024 #include <QStandardPaths> 0025 #include <QTimer> 0026 0027 #include <KIdentityManagementCore/Identity> 0028 0029 ExportMailJobInterface::ExportMailJobInterface(QObject *parent, Utils::StoredTypes typeSelected, ArchiveStorage *archiveStorage, int numberOfStep) 0030 : AbstractImportExportJob(parent, archiveStorage, typeSelected, numberOfStep) 0031 { 0032 } 0033 0034 ExportMailJobInterface::~ExportMailJobInterface() = default; 0035 0036 bool ExportMailJobInterface::checkBackupType(Utils::StoredType type) const 0037 { 0038 return mTypeSelected & type; 0039 } 0040 0041 void ExportMailJobInterface::start() 0042 { 0043 Q_EMIT title(i18n("Start export KMail settings...")); 0044 createProgressDialog(i18n("Export KMail settings")); 0045 if (checkBackupType(Utils::Identity)) { 0046 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupIdentity); 0047 } else if (checkBackupType(Utils::MailTransport)) { 0048 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMailTransport); 0049 } else if (checkBackupType(Utils::Config)) { 0050 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupConfig); 0051 } else if (checkBackupType(Utils::Mails)) { 0052 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMails); 0053 } else if (checkBackupType(Utils::Resources)) { 0054 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources); 0055 } else { 0056 Q_EMIT jobFinished(); 0057 } 0058 } 0059 0060 void ExportMailJobInterface::slotCheckBackupIdentity() 0061 { 0062 if (checkBackupType(Utils::Identity)) { 0063 backupIdentity(); 0064 increaseProgressDialog(); 0065 if (wasCanceled()) { 0066 Q_EMIT jobFinished(); 0067 return; 0068 } 0069 } 0070 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMailTransport); 0071 } 0072 0073 void ExportMailJobInterface::slotCheckBackupMailTransport() 0074 { 0075 if (checkBackupType(Utils::MailTransport)) { 0076 backupTransports(); 0077 increaseProgressDialog(); 0078 if (wasCanceled()) { 0079 Q_EMIT jobFinished(); 0080 return; 0081 } 0082 } 0083 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupConfig); 0084 } 0085 0086 void ExportMailJobInterface::slotCheckBackupConfig() 0087 { 0088 if (checkBackupType(Utils::Config)) { 0089 backupConfig(); 0090 increaseProgressDialog(); 0091 if (wasCanceled()) { 0092 Q_EMIT jobFinished(); 0093 return; 0094 } 0095 } 0096 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMails); 0097 } 0098 0099 void ExportMailJobInterface::slotCheckBackupMails() 0100 { 0101 mAkonadiInstanceInfo = listOfResource(); 0102 if (checkBackupType(Utils::Mails)) { 0103 increaseProgressDialog(); 0104 backupFolderAttributes(); 0105 return; 0106 } 0107 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources); 0108 } 0109 0110 void ExportMailJobInterface::backupFolderAttributes() 0111 { 0112 setProgressDialogLabel(i18n("Backing up Folder Attributes...")); 0113 connect(this, &ExportMailJobInterface::exportAttributeDone, this, [this]() { 0114 setProgressDialogLabel(i18n("Backing up Mails...")); 0115 emitInfo(i18n("Start export resource...")); 0116 QTimer::singleShot(0, this, &ExportMailJobInterface::slotWriteNextArchiveResource); 0117 }); 0118 exportFolderAttributes(); 0119 } 0120 0121 void ExportMailJobInterface::backupTransports() 0122 { 0123 setProgressDialogLabel(i18n("Backing up transports...")); 0124 0125 const QString mailtransportsStr(QStringLiteral("mailtransports")); 0126 const QString maitransportsrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + mailtransportsStr; 0127 if (!QFileInfo::exists(maitransportsrc)) { 0128 emitInfo(i18n("Transports backup done.")); 0129 } else { 0130 KSharedConfigPtr mailtransportsConfig = KSharedConfig::openConfig(mailtransportsStr); 0131 0132 QTemporaryFile tmp; 0133 tmp.open(); 0134 KConfig *config = mailtransportsConfig->copyTo(tmp.fileName()); 0135 0136 config->sync(); 0137 const bool fileAdded = archive()->addLocalFile(tmp.fileName(), Utils::transportsPath() + QStringLiteral("mailtransports")); 0138 delete config; 0139 if (fileAdded) { 0140 emitInfo(i18n("Transports backup done.")); 0141 } else { 0142 emitError(i18n("Transport file cannot be added to backup file.")); 0143 } 0144 } 0145 } 0146 0147 void ExportMailJobInterface::slotCheckBackupResources() 0148 { 0149 if (checkBackupType(Utils::Resources)) { 0150 backupResources(); 0151 increaseProgressDialog(); 0152 if (wasCanceled()) { 0153 Q_EMIT jobFinished(); 0154 return; 0155 } 0156 } 0157 Q_EMIT jobFinished(); 0158 } 0159 0160 QString ExportMailJobInterface::applicationName() const 0161 { 0162 return QStringLiteral("[KMail]"); 0163 } 0164 0165 void ExportMailJobInterface::backupConfig() 0166 { 0167 setProgressDialogLabel(i18n("Backing up config...")); 0168 0169 exportFilters(); 0170 0171 backupUiRcFile(QStringLiteral("sieveeditorui.rc"), QStringLiteral("sieveeditor")); 0172 backupUiRcFile(QStringLiteral("kmreadermainwin.rc"), QStringLiteral("kmail2")); 0173 backupUiRcFile(QStringLiteral("kmcomposerui.rc"), QStringLiteral("kmail2")); 0174 backupUiRcFile(QStringLiteral("kmmainwin.rc"), QStringLiteral("kmail2")); 0175 backupUiRcFile(QStringLiteral("kmail_part.rc"), QStringLiteral("kmail2")); 0176 backupUiRcFile(QStringLiteral("kontactsummary_part.rc"), QStringLiteral("kontactsummary")); 0177 backupUiRcFile(QStringLiteral("kontactui.rc"), QStringLiteral("kontact")); 0178 backupUiRcFile(QStringLiteral("kleopatra.rc"), QStringLiteral("kleopatra")); 0179 backupUiRcFile(QStringLiteral("headerthemeeditorui.rc"), QStringLiteral("headerthemeeditor")); 0180 backupUiRcFile(QStringLiteral("contactthemeeditorui.rc"), QStringLiteral("contactthemeeditor")); 0181 backupUiRcFile(QStringLiteral("contactprintthemeeditorui.rc"), QStringLiteral("contactprintthemeeditor")); 0182 backupUiRcFile(QStringLiteral("kwatchgnupgui.rc"), QStringLiteral("kwatchgnupg")); 0183 backupUiRcFile(QStringLiteral("akonadiconsoleui.rc"), QStringLiteral("akonadiconsole")); 0184 0185 backupConfigFile(QStringLiteral("kabldaprc")); 0186 backupConfigFile(QStringLiteral("kmailsnippetrc")); 0187 backupConfigFile(QStringLiteral("sievetemplaterc")); 0188 backupConfigFile(QStringLiteral("customtemplatesrc")); 0189 backupConfigFile(QStringLiteral("kontactrc")); 0190 backupConfigFile(QStringLiteral("kontact_summaryrc")); 0191 backupConfigFile(QStringLiteral("storageservicerc")); 0192 backupConfigFile(QStringLiteral("kpimbalooblacklist")); 0193 backupConfigFile(QStringLiteral("kleopatrarc")); 0194 backupConfigFile(QStringLiteral("sieveeditorrc")); 0195 backupConfigFile(QStringLiteral("kwatchgnupgrc")); 0196 backupConfigFile(QStringLiteral("pimpluginsrc")); 0197 backupConfigFile(QStringLiteral("texttospeechrc")); 0198 backupConfigFile(QStringLiteral("kleopatracertificateselectiondialogrc")); 0199 backupConfigFile(QStringLiteral("dkimsettingsrc")); 0200 backupConfigFile(QStringLiteral("confirmbeforedeletingrc")); 0201 0202 // Notify file config 0203 backupConfigFile(QStringLiteral("akonadi_mailfilter_agent.notifyrc")); 0204 backupConfigFile(QStringLiteral("akonadi_sendlater_agent.notifyrc")); 0205 backupConfigFile(QStringLiteral("akonadi_archivemail_agent.notifyrc")); 0206 backupConfigFile(QStringLiteral("kmail2.notifyrc")); 0207 backupConfigFile(QStringLiteral("akonadi_newmailnotifier_agent.notifyrc")); 0208 backupConfigFile(QStringLiteral("akonadi_maildispatcher_agent.notifyrc")); 0209 backupConfigFile(QStringLiteral("akonadi_followupreminder_agent.notifyrc")); 0210 backupConfigFile(QStringLiteral("messagevieweradblockrc")); 0211 backupConfigFile(QStringLiteral("messageviewer.notifyrc")); 0212 backupConfigFile(QStringLiteral("akonadi_newmailnotifier_agentrc")); 0213 0214 const QString folderMailArchiveStr(QStringLiteral("foldermailarchiverc")); 0215 const QString folderMailArchiverc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + folderMailArchiveStr; 0216 if (QFileInfo::exists(folderMailArchiverc)) { 0217 KSharedConfigPtr archivemailrc = KSharedConfig::openConfig(folderMailArchiveStr); 0218 0219 QTemporaryFile tmp; 0220 tmp.open(); 0221 0222 KConfig *archiveConfig = archivemailrc->copyTo(tmp.fileName()); 0223 const QStringList archiveList = archiveConfig->groupList().filter(QRegularExpression(QStringLiteral("FolderArchiveAccount"))); 0224 0225 for (const QString &str : archiveList) { 0226 KConfigGroup oldGroup = archiveConfig->group(str); 0227 const qint64 id = oldGroup.readEntry("topLevelCollectionId", -1); 0228 if (id != -1) { 0229 const QString realPath = convertToFullCollectionPath(id); 0230 if (!realPath.isEmpty()) { 0231 oldGroup.writeEntry(QStringLiteral("topLevelCollectionId"), realPath); 0232 } 0233 } 0234 } 0235 archiveConfig->sync(); 0236 0237 backupFile(tmp.fileName(), Utils::configsPath(), folderMailArchiveStr); 0238 delete archiveConfig; 0239 } 0240 const QString unifiedMailBoxStr(QStringLiteral("akonadi_unifiedmailbox_agentrc")); 0241 const QString unifiedMailBoxrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + unifiedMailBoxStr; 0242 if (QFileInfo::exists(unifiedMailBoxrc)) { 0243 KSharedConfigPtr mboxrc = KSharedConfig::openConfig(unifiedMailBoxrc); 0244 0245 QTemporaryFile tmp; 0246 tmp.open(); 0247 0248 KConfig *archiveConfig = mboxrc->copyTo(tmp.fileName()); 0249 auto group = archiveConfig->group(QStringLiteral("UnifiedMailboxes")); 0250 const auto boxGroups = group.groupList(); 0251 for (const auto &str : boxGroups) { 0252 KConfigGroup oldGroup = group.group(str); 0253 0254 const qint64 id = oldGroup.readEntry("collectionId", -1); 0255 if (id != -1) { 0256 const QString realPath = convertToFullCollectionPath(id); 0257 if (!realPath.isEmpty()) { 0258 oldGroup.writeEntry(QStringLiteral("collectionId"), realPath); 0259 } 0260 } 0261 const QString sourceKey(QStringLiteral("sources")); 0262 convertCollectionListToRealPath(oldGroup, sourceKey); 0263 } 0264 archiveConfig->sync(); 0265 0266 backupFile(tmp.fileName(), Utils::configsPath(), unifiedMailBoxStr); 0267 delete archiveConfig; 0268 } 0269 0270 const QString archiveMailAgentConfigurationStr(QStringLiteral("akonadi_archivemail_agentrc")); 0271 const QString archiveMailAgentconfigurationrc = 0272 QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + archiveMailAgentConfigurationStr; 0273 if (QFileInfo::exists(archiveMailAgentconfigurationrc)) { 0274 KSharedConfigPtr archivemailrc = KSharedConfig::openConfig(archiveMailAgentConfigurationStr); 0275 0276 QTemporaryFile tmp; 0277 tmp.open(); 0278 0279 KConfig *archiveConfig = archivemailrc->copyTo(tmp.fileName()); 0280 const QStringList archiveList = archiveConfig->groupList().filter(QRegularExpression(QStringLiteral("ArchiveMailCollection \\d+"))); 0281 const QString archiveGroupPattern = QStringLiteral("ArchiveMailCollection "); 0282 0283 for (const QString &str : archiveList) { 0284 bool found = false; 0285 const int collectionId = QStringView(str).right(str.length() - archiveGroupPattern.length()).toInt(&found); 0286 if (found) { 0287 KConfigGroup oldGroup = archiveConfig->group(str); 0288 const QString realPath = convertToFullCollectionPath(collectionId); 0289 if (!realPath.isEmpty()) { 0290 const QString collectionPath(archiveGroupPattern + realPath); 0291 KConfigGroup newGroup(archiveConfig, collectionPath); 0292 oldGroup.copyTo(&newGroup); 0293 newGroup.writeEntry(QStringLiteral("saveCollectionId"), realPath); 0294 } 0295 oldGroup.deleteGroup(); 0296 } 0297 } 0298 archiveConfig->sync(); 0299 0300 backupFile(tmp.fileName(), Utils::configsPath(), archiveMailAgentConfigurationStr); 0301 delete archiveConfig; 0302 } 0303 0304 const QString templatesconfigurationrcStr(QStringLiteral("templatesconfigurationrc")); 0305 const QString templatesconfigurationrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + templatesconfigurationrcStr; 0306 if (QFileInfo::exists(templatesconfigurationrc)) { 0307 KSharedConfigPtr templaterc = KSharedConfig::openConfig(templatesconfigurationrcStr); 0308 0309 QTemporaryFile tmp; 0310 tmp.open(); 0311 0312 KConfig *templateConfig = templaterc->copyTo(tmp.fileName()); 0313 const QString templateGroupPattern = QStringLiteral("Templates #"); 0314 const QStringList templateList = templateConfig->groupList().filter(QRegularExpression(QStringLiteral("Templates #\\d+"))); 0315 for (const QString &str : templateList) { 0316 bool found = false; 0317 const int collectionId = QStringView(str).right(str.length() - templateGroupPattern.length()).toInt(&found); 0318 if (found) { 0319 KConfigGroup oldGroup = templateConfig->group(str); 0320 const QString realPath = convertToFullCollectionPath(collectionId); 0321 if (!realPath.isEmpty()) { 0322 KConfigGroup newGroup(templateConfig, templateGroupPattern + realPath); 0323 oldGroup.copyTo(&newGroup); 0324 } 0325 oldGroup.deleteGroup(); 0326 } 0327 } 0328 templateConfig->sync(); 0329 0330 backupFile(tmp.fileName(), Utils::configsPath(), templatesconfigurationrcStr); 0331 delete templateConfig; 0332 } 0333 0334 storeDirectory(QStringLiteral("/messageviewerplugins/")); 0335 storeDirectory(QStringLiteral("/messageviewer/themes/")); 0336 0337 const QDir gravatarDirectory(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/gravatar/")); 0338 if (gravatarDirectory.exists()) { 0339 const QFileInfoList listFileInfo = gravatarDirectory.entryInfoList(QStringList() << QStringLiteral("*.png"), QDir::Files); 0340 const int listSize(listFileInfo.size()); 0341 for (int i = 0; i < listSize; ++i) { 0342 backupFile(listFileInfo.at(i).absoluteFilePath(), Utils::dataPath() + QStringLiteral("gravatar/"), listFileInfo.at(i).fileName()); 0343 } 0344 } 0345 0346 const QDir autocorrectDirectory(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/autocorrect/")); 0347 if (autocorrectDirectory.exists()) { 0348 const QFileInfoList listFileInfo = autocorrectDirectory.entryInfoList(QStringList() << QStringLiteral("*.xml"), QDir::Files); 0349 const int listSize(listFileInfo.size()); 0350 for (int i = 0; i < listSize; ++i) { 0351 backupFile(listFileInfo.at(i).absoluteFilePath(), Utils::dataPath() + QStringLiteral("autocorrect/"), listFileInfo.at(i).fileName()); 0352 } 0353 } 0354 const QString adblockFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kmail2/adblockrules_local"); 0355 if (QFileInfo::exists(adblockFilePath)) { 0356 backupFile(adblockFilePath, Utils::dataPath() + QStringLiteral("kmail2/"), QStringLiteral("adblockrules_local")); 0357 } 0358 0359 const QString kmailStr(QStringLiteral("kmail2rc")); 0360 const QString kmail2rc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + kmailStr; 0361 if (QFileInfo::exists(kmail2rc)) { 0362 KSharedConfigPtr kmailrc = KSharedConfig::openConfig(kmail2rc); 0363 0364 QTemporaryFile tmp; 0365 tmp.open(); 0366 0367 KConfig *kmailConfig = kmailrc->copyTo(tmp.fileName()); 0368 const QString folderGroupPattern = QStringLiteral("Folder-"); 0369 const QStringList folderList = kmailConfig->groupList().filter(QRegularExpression(QStringLiteral("Folder-\\d+"))); 0370 for (const QString &str : folderList) { 0371 bool found = false; 0372 const int collectionId = QStringView(str).right(str.length() - folderGroupPattern.length()).toInt(&found); 0373 if (found) { 0374 KConfigGroup oldGroup = kmailConfig->group(str); 0375 ImportExportMailUtil::cleanupFolderSettings(oldGroup); 0376 const QString realPath = convertToFullCollectionPath(collectionId); 0377 if (!realPath.isEmpty()) { 0378 KConfigGroup newGroup(kmailConfig, folderGroupPattern + realPath); 0379 oldGroup.copyTo(&newGroup); 0380 } 0381 oldGroup.deleteGroup(); 0382 } 0383 } 0384 const QString composerStr(QStringLiteral("Composer")); 0385 if (kmailConfig->hasGroup(composerStr)) { 0386 KConfigGroup composerGroup = kmailConfig->group(composerStr); 0387 const QString previousStr(QStringLiteral("previous-fcc")); 0388 if (composerGroup.hasKey(previousStr)) { 0389 const int collectionId = composerGroup.readEntry(previousStr, -1); 0390 if (collectionId != -1) { 0391 const QString realPath = convertToFullCollectionPath(collectionId); 0392 composerGroup.writeEntry(previousStr, realPath); 0393 } 0394 } 0395 } 0396 0397 const QString generalStr(QStringLiteral("General")); 0398 if (kmailConfig->hasGroup(generalStr)) { 0399 KConfigGroup generalGroup = kmailConfig->group(generalStr); 0400 const QString startupFolderStr(QStringLiteral("startupFolder")); 0401 if (generalGroup.hasKey(startupFolderStr)) { 0402 const int collectionId = generalGroup.readEntry(startupFolderStr, -1); 0403 if (collectionId != -1) { 0404 const QString realPath = convertToFullCollectionPath(collectionId); 0405 generalGroup.writeEntry(startupFolderStr, realPath); 0406 } 0407 } 0408 } 0409 0410 const QString storageModelSelectedMessageStr(QStringLiteral("MessageListView::StorageModelSelectedMessages")); 0411 if (kmailConfig->hasGroup(storageModelSelectedMessageStr)) { 0412 KConfigGroup storageGroup = kmailConfig->group(storageModelSelectedMessageStr); 0413 const QString storageModelSelectedPattern(QStringLiteral("MessageUniqueIdForStorageModel")); 0414 const QStringList storageList = storageGroup.keyList().filter(QRegularExpression(QStringLiteral("MessageUniqueIdForStorageModel\\d+"))); 0415 for (const QString &str : storageList) { 0416 bool found = false; 0417 const int collectionId = QStringView(str).right(str.length() - storageModelSelectedPattern.length()).toInt(&found); 0418 const QString oldValue = storageGroup.readEntry(str); 0419 if (found) { 0420 const QString realPath = convertToFullCollectionPath(collectionId); 0421 if (!realPath.isEmpty()) { 0422 storageGroup.writeEntry(QStringLiteral("%1%2").arg(storageModelSelectedPattern, realPath), oldValue); 0423 storageGroup.deleteEntry(str); 0424 } else { 0425 storageGroup.deleteEntry(str); 0426 } 0427 } 0428 } 0429 } 0430 0431 const QString collectionFolderViewStr(QStringLiteral("CollectionFolderView")); 0432 if (kmailConfig->hasGroup(collectionFolderViewStr)) { 0433 KConfigGroup favoriteGroup = kmailConfig->group(collectionFolderViewStr); 0434 0435 const QString currentKey(QStringLiteral("Current")); 0436 convertCollectionToRealPath(favoriteGroup, currentKey); 0437 0438 const QString expensionKey(QStringLiteral("Expansion")); 0439 convertCollectionListToRealPath(favoriteGroup, expensionKey); 0440 } 0441 0442 const QString favoriteCollectionStr(QStringLiteral("FavoriteCollections")); 0443 if (kmailConfig->hasGroup(favoriteCollectionStr)) { 0444 KConfigGroup favoriteGroup = kmailConfig->group(favoriteCollectionStr); 0445 0446 const QString favoriteCollectionIdsStr(QStringLiteral("FavoriteCollectionIds")); 0447 convertCollectionIdsToRealPath(favoriteGroup, favoriteCollectionIdsStr); 0448 } 0449 0450 const QString favoriteCollectionOrderStr(QStringLiteral("FavoriteCollectionsOrder")); 0451 if (kmailConfig->hasGroup(favoriteCollectionOrderStr)) { 0452 KConfigGroup favoriteGroup = kmailConfig->group(favoriteCollectionOrderStr); 0453 // For favorite id for root collection == 0 and we store only folder => c 0454 const QString favoriteCollectionIdsStr(QStringLiteral("0")); 0455 const QString prefixCollection(QStringLiteral("c")); 0456 convertCollectionIdsToRealPath(favoriteGroup, favoriteCollectionIdsStr, prefixCollection); 0457 } 0458 0459 // Event collection 0460 const QString eventCollectionStr(QStringLiteral("Event")); 0461 if (kmailConfig->hasGroup(eventCollectionStr)) { 0462 KConfigGroup eventGroup = kmailConfig->group(eventCollectionStr); 0463 const QString eventLastEventSelectedFolder(QStringLiteral("LastEventSelectedFolder")); 0464 convertCollectionIdsToRealPath(eventGroup, eventLastEventSelectedFolder); 0465 } 0466 0467 // Todo collection 0468 const QString todoCollectionStr(QStringLiteral("Todo")); 0469 if (kmailConfig->hasGroup(todoCollectionStr)) { 0470 KConfigGroup todoGroup = kmailConfig->group(todoCollectionStr); 0471 const QString todoLastEventSelectedFolder(QStringLiteral("LastSelectedFolder")); 0472 convertCollectionIdsToRealPath(todoGroup, todoLastEventSelectedFolder); 0473 } 0474 // FolderSelectionDialog collection 0475 const QString folderSelectionCollectionStr(QStringLiteral("FolderSelectionDialog")); 0476 if (kmailConfig->hasGroup(folderSelectionCollectionStr)) { 0477 KConfigGroup folderSelectionGroup = kmailConfig->group(folderSelectionCollectionStr); 0478 const QString folderSelectionSelectedFolder(QStringLiteral("LastSelectedFolder")); 0479 convertCollectionIdsToRealPath(folderSelectionGroup, folderSelectionSelectedFolder); 0480 } 0481 0482 // Note collection 0483 const QString noteCollectionStr(QStringLiteral("Note")); 0484 if (kmailConfig->hasGroup(noteCollectionStr)) { 0485 KConfigGroup noteGroup = kmailConfig->group(noteCollectionStr); 0486 const QString noteLastEventSelectedFolder(QStringLiteral("LastNoteSelectedFolder")); 0487 convertCollectionIdsToRealPath(noteGroup, noteLastEventSelectedFolder); 0488 } 0489 0490 // Convert MessageListTab collection id 0491 const QString messageListPaneStr(QStringLiteral("MessageListPane")); 0492 if (kmailConfig->hasGroup(messageListPaneStr)) { 0493 KConfigGroup messageListPaneGroup = kmailConfig->group(messageListPaneStr); 0494 const int numberOfTab = messageListPaneGroup.readEntry(QStringLiteral("tabNumber"), 0); 0495 for (int i = 0; i < numberOfTab; ++i) { 0496 KConfigGroup messageListPaneTabGroup = kmailConfig->group(QStringLiteral("MessageListTab%1").arg(i)); 0497 const QString messageListPaneTabFolderStr(QStringLiteral("collectionId")); 0498 convertCollectionIdsToRealPath(messageListPaneTabGroup, messageListPaneTabFolderStr); 0499 } 0500 } 0501 0502 // Automatic Add Contacts 0503 const QList<uint> listIdentities = listIdentityUoid(); 0504 for (uint identity : listIdentities) { 0505 const QString groupId = QStringLiteral("Automatic Add Contacts %1").arg(identity); 0506 if (kmailConfig->hasGroup(groupId)) { 0507 KConfigGroup identityGroup = kmailConfig->group(groupId); 0508 const QString automaticAddContactStr(QStringLiteral("Collection")); 0509 convertCollectionIdsToRealPath(identityGroup, automaticAddContactStr); 0510 } 0511 } 0512 0513 // TODO add confirm address too 0514 0515 // Clean up kmail2rc 0516 const QString tipOfDaysStr(QStringLiteral("TipOfDay")); 0517 if (kmailConfig->hasGroup(tipOfDaysStr)) { 0518 kmailConfig->deleteGroup(tipOfDaysStr); 0519 } 0520 const QString startupStr(QStringLiteral("Startup")); 0521 if (kmailConfig->hasGroup(startupStr)) { 0522 kmailConfig->deleteGroup(startupStr); 0523 } 0524 0525 const QString search(QStringLiteral("Search")); 0526 if (kmailConfig->hasGroup(search)) { 0527 KConfigGroup searchGroup = kmailConfig->group(search); 0528 searchGroup.deleteGroup(); 0529 } 0530 0531 kmailConfig->sync(); 0532 backupFile(tmp.fileName(), Utils::configsPath(), kmailStr); 0533 delete kmailConfig; 0534 } 0535 0536 emitInfo(i18n("Config backup done.")); 0537 } 0538 0539 void ExportMailJobInterface::backupIdentity() 0540 { 0541 setProgressDialogLabel(i18n("Backing up identity...")); 0542 0543 const QString emailidentitiesStr(QStringLiteral("emailidentities")); 0544 const QString emailidentitiesrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + emailidentitiesStr; 0545 if (QFileInfo::exists(emailidentitiesrc)) { 0546 KSharedConfigPtr identity = KSharedConfig::openConfig(emailidentitiesrc); 0547 0548 QTemporaryFile tmp; 0549 tmp.open(); 0550 0551 KConfig *identityConfig = identity->copyTo(tmp.fileName()); 0552 const QStringList accountList = identityConfig->groupList().filter(QRegularExpression(QStringLiteral("Identity #\\d+"))); 0553 for (const QString &account : accountList) { 0554 KConfigGroup group = identityConfig->group(account); 0555 const QString fcc = QStringLiteral("Fcc"); 0556 if (group.hasKey(fcc)) { 0557 const QString realPath = convertToFullCollectionPath(group.readEntry(fcc).toLongLong()); 0558 group.writeEntry(fcc, realPath); 0559 } 0560 const QString draft = QStringLiteral("Drafts"); 0561 if (group.hasKey(draft)) { 0562 const QString realPath = convertToFullCollectionPath(group.readEntry(draft).toLongLong()); 0563 group.writeEntry(draft, realPath); 0564 } 0565 const QString templates = QStringLiteral("Templates"); 0566 if (group.hasKey(templates)) { 0567 const QString realPath = convertToFullCollectionPath(group.readEntry(templates).toLongLong()); 0568 group.writeEntry(templates, realPath); 0569 } 0570 const QString vcard = QStringLiteral("VCardFile"); 0571 if (group.hasKey(vcard)) { 0572 const QString vcardFileName = group.readEntry(vcard); 0573 if (!vcardFileName.isEmpty()) { 0574 const int uoid = group.readEntry(QStringLiteral("uoid"), -1); 0575 QFile file(vcardFileName); 0576 if (file.exists()) { 0577 const bool fileAdded = 0578 archive()->addLocalFile(vcardFileName, Utils::identitiesPath() + QString::number(uoid) + QLatin1Char('/') + file.fileName()); 0579 if (!fileAdded) { 0580 emitError(i18n("vCard file \"%1\" cannot be saved.", file.fileName())); 0581 } 0582 } else { 0583 group.deleteEntry(vcard); 0584 } 0585 } 0586 } 0587 } 0588 0589 identityConfig->sync(); 0590 const bool fileAdded = archive()->addLocalFile(tmp.fileName(), Utils::identitiesPath() + QStringLiteral("emailidentities")); 0591 delete identityConfig; 0592 if (fileAdded) { 0593 emitInfo(i18n("Identity backup done.")); 0594 } else { 0595 emitError(i18n("Identity file cannot be added to backup file.")); 0596 } 0597 } 0598 } 0599 0600 void ExportMailJobInterface::slotMailsJobTerminated() 0601 { 0602 if (wasCanceled()) { 0603 Q_EMIT jobFinished(); 0604 return; 0605 } 0606 mIndexIdentifier++; 0607 QTimer::singleShot(0, this, &ExportMailJobInterface::slotWriteNextArchiveResource); 0608 } 0609 0610 void ExportMailJobInterface::slotWriteNextArchiveResource() 0611 { 0612 if (mIndexIdentifier < mAkonadiInstanceInfo.count()) { 0613 const Utils::AkonadiInstanceInfo agent = mAkonadiInstanceInfo.at(mIndexIdentifier); 0614 const QStringList capabilities(agent.capabilities); 0615 if (agent.mimeTypes.contains(KMime::Message::mimeType())) { 0616 if (capabilities.contains(QLatin1StringView("Resource")) && !capabilities.contains(QLatin1StringView("Virtual")) 0617 && !capabilities.contains(QLatin1StringView("MailTransport"))) { 0618 const QString identifier = agent.identifier; 0619 if (identifier.contains(QLatin1StringView("akonadi_maildir_resource_")) 0620 || identifier.contains(QLatin1StringView("akonadi_mixedmaildir_resource_"))) { 0621 const QString archivePath = Utils::mailsPath() + identifier + QLatin1Char('/'); 0622 const QString url = resourcePath(identifier); 0623 if (!mAgentPaths.contains(url)) { 0624 if (!url.isEmpty()) { 0625 mAgentPaths << url; 0626 exportResourceToArchive(archivePath, url, identifier); 0627 } else { 0628 qCDebug(PIMDATAEXPORTERCORE_LOG) << "Url is empty for " << identifier; 0629 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0630 } 0631 } else { 0632 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0633 } 0634 } else if (identifier.contains(QLatin1StringView("akonadi_mbox_resource_"))) { 0635 backupMailResourceFile(identifier, Utils::mailsPath()); // FIXME addressbookPath or MailPAth ??? 0636 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0637 } else { 0638 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0639 } 0640 } else { 0641 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0642 } 0643 } else { 0644 QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated); 0645 } 0646 } else { 0647 QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources); 0648 } 0649 } 0650 0651 void ExportMailJobInterface::backupResources() 0652 { 0653 setProgressDialogLabel(i18n("Backing up resources...")); 0654 0655 for (const Utils::AkonadiInstanceInfo &agent : std::as_const(mAkonadiInstanceInfo)) { 0656 const QStringList capabilities = agent.capabilities; 0657 if (agent.mimeTypes.contains(KMime::Message::mimeType())) { 0658 if (capabilities.contains(QLatin1StringView("Resource")) && !capabilities.contains(QLatin1StringView("Virtual")) 0659 && !capabilities.contains(QLatin1StringView("MailTransport"))) { 0660 const QString identifier = agent.identifier; 0661 // Store just pop3/imap/kolab/gmail account. Store other config when we copy data. 0662 if (identifier.contains(QLatin1StringView("pop3")) || identifier.contains(QLatin1StringView("imap")) 0663 || identifier.contains(QLatin1StringView("_kolab_")) || identifier.contains(QLatin1StringView("_gmail_"))) { 0664 const QString errorStr = storeResources(archive(), identifier, Utils::resourcesPath()); 0665 if (!errorStr.isEmpty()) { 0666 emitError(errorStr); 0667 } 0668 } else { 0669 qCDebug(PIMDATAEXPORTERCORE_LOG) << " resource \"" << identifier << "\" will not store"; 0670 } 0671 } 0672 } 0673 } 0674 0675 emitInfo(i18n("Resources backup done.")); 0676 } 0677 0678 #include "moc_exportmailjobinterface.cpp"