exportmailjobinterface.cpp 30.1 KB
Newer Older
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
   Copyright (C) 2012-2020 Laurent Montel <montel@kde.org>
3

Laurent Montel's avatar
Laurent Montel committed
4
5
6
7
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
8

Laurent Montel's avatar
Laurent Montel committed
9
10
11
12
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.
13

Laurent Montel's avatar
Laurent Montel committed
14
15
16
17
   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
18
19
*/

Laurent Montel's avatar
Laurent Montel committed
20
#include "exportmailjobinterface.h"
21
#include "importexportmailutil.h"
Laurent Montel's avatar
Laurent Montel committed
22

Laurent Montel's avatar
Laurent Montel committed
23
#include <MailCommon/FilterImporterExporter>
Laurent Montel's avatar
Laurent Montel committed
24
#include "importexportprogressindicatorbase.h"
25

Laurent Montel's avatar
Laurent Montel committed
26
#include <MailTransport/TransportManager>
27
28

#include <KZip>
29
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
30
#include <QTemporaryFile>
Laurent Montel's avatar
Laurent Montel committed
31

Laurent Montel's avatar
Laurent Montel committed
32
#include "pimdataexportcore_debug.h"
Laurent Montel's avatar
Laurent Montel committed
33
#include <KMime/Message>
34
#include <QFile>
35
#include <QDir>
Laurent Montel's avatar
Laurent Montel committed
36
#include <QTimer>
Laurent Montel's avatar
Laurent Montel committed
37
#include <QStandardPaths>
Laurent Montel's avatar
Laurent Montel committed
38
#include <QRegularExpression>
Laurent Montel's avatar
Laurent Montel committed
39
#include <resourceconverterimpl.h>
40

41
42
43
#include <KIdentityManagement/IdentityManager>
#include <KIdentityManagement/Identity>

Laurent Montel's avatar
Laurent Montel committed
44
ExportMailJobInterface::ExportMailJobInterface(QObject *parent, Utils::StoredTypes typeSelected, ArchiveStorage *archiveStorage, int numberOfStep)
Laurent Montel's avatar
Laurent Montel committed
45
    : AbstractImportExportJob(parent, archiveStorage, typeSelected, numberOfStep)
46
47
48
{
}

Laurent Montel's avatar
Laurent Montel committed
49
ExportMailJobInterface::~ExportMailJobInterface()
50
51
52
{
}

Laurent Montel's avatar
Laurent Montel committed
53
bool ExportMailJobInterface::checkBackupType(Utils::StoredType type) const
Laurent Montel's avatar
Laurent Montel committed
54
{
Laurent Montel's avatar
Laurent Montel committed
55
    return mTypeSelected & type;
Laurent Montel's avatar
Laurent Montel committed
56
57
}

Laurent Montel's avatar
Laurent Montel committed
58
void ExportMailJobInterface::start()
59
{
60
    Q_EMIT title(i18n("Start export KMail settings..."));
Laurent Montel's avatar
Laurent Montel committed
61
    createProgressDialog(i18n("Export KMail settings"));
Laurent Montel's avatar
Laurent Montel committed
62
    if (checkBackupType(Utils::Identity)) {
Laurent Montel's avatar
Laurent Montel committed
63
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupIdentity);
Laurent Montel's avatar
Laurent Montel committed
64
    } else if (checkBackupType(Utils::MailTransport)) {
Laurent Montel's avatar
Laurent Montel committed
65
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMailTransport);
Laurent Montel's avatar
Laurent Montel committed
66
    } else if (checkBackupType(Utils::Config)) {
Laurent Montel's avatar
Laurent Montel committed
67
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupConfig);
Laurent Montel's avatar
Laurent Montel committed
68
    } else if (checkBackupType(Utils::Mails)) {
Laurent Montel's avatar
Laurent Montel committed
69
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMails);
Laurent Montel's avatar
Laurent Montel committed
70
    } else if (checkBackupType(Utils::Resources)) {
Laurent Montel's avatar
Laurent Montel committed
71
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources);
Laurent Montel's avatar
Laurent Montel committed
72
73
74
75
    } else {
        Q_EMIT jobFinished();
    }
}
76

Laurent Montel's avatar
Laurent Montel committed
77
void ExportMailJobInterface::slotCheckBackupIdentity()
Laurent Montel's avatar
Laurent Montel committed
78
{
Laurent Montel's avatar
Laurent Montel committed
79
    if (checkBackupType(Utils::Identity)) {
Laurent Montel's avatar
Laurent Montel committed
80
81
82
        backupIdentity();
        increaseProgressDialog();
        if (wasCanceled()) {
83
            Q_EMIT jobFinished();
Laurent Montel's avatar
Laurent Montel committed
84
85
            return;
        }
86
    }
Laurent Montel's avatar
Laurent Montel committed
87
    QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMailTransport);
Laurent Montel's avatar
Laurent Montel committed
88
89
}

Laurent Montel's avatar
Laurent Montel committed
90
void ExportMailJobInterface::slotCheckBackupMailTransport()
Laurent Montel's avatar
Laurent Montel committed
91
{
Laurent Montel's avatar
Laurent Montel committed
92
    if (checkBackupType(Utils::MailTransport)) {
Laurent Montel's avatar
Laurent Montel committed
93
94
95
        backupTransports();
        increaseProgressDialog();
        if (wasCanceled()) {
96
            Q_EMIT jobFinished();
Laurent Montel's avatar
Laurent Montel committed
97
98
            return;
        }
99
    }
Laurent Montel's avatar
Laurent Montel committed
100
    QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupConfig);
Laurent Montel's avatar
Laurent Montel committed
101
102
}

Laurent Montel's avatar
Laurent Montel committed
103
void ExportMailJobInterface::slotCheckBackupConfig()
Laurent Montel's avatar
Laurent Montel committed
104
{
Laurent Montel's avatar
Laurent Montel committed
105
    if (checkBackupType(Utils::Config)) {
Laurent Montel's avatar
Laurent Montel committed
106
107
108
        backupConfig();
        increaseProgressDialog();
        if (wasCanceled()) {
109
            Q_EMIT jobFinished();
Laurent Montel's avatar
Laurent Montel committed
110
111
            return;
        }
112
    }
Laurent Montel's avatar
Laurent Montel committed
113
    QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupMails);
Laurent Montel's avatar
Laurent Montel committed
114
115
}

Laurent Montel's avatar
Laurent Montel committed
116
void ExportMailJobInterface::slotCheckBackupMails()
Laurent Montel's avatar
Laurent Montel committed
117
{
118
    mAkonadiInstanceInfo = listOfResource();
Laurent Montel's avatar
Laurent Montel committed
119
    if (checkBackupType(Utils::Mails)) {
Laurent Montel's avatar
Laurent Montel committed
120
        increaseProgressDialog();
Laurent Montel's avatar
Laurent Montel committed
121
        setProgressDialogLabel(i18n("Backing up Mails..."));
122
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotWriteNextArchiveResource);
Laurent Montel's avatar
Laurent Montel committed
123
124
        return;
    }
Laurent Montel's avatar
Laurent Montel committed
125
    QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources);
Laurent Montel's avatar
Laurent Montel committed
126
127
}

Laurent Montel's avatar
Laurent Montel committed
128
void ExportMailJobInterface::backupTransports()
129
{
Laurent Montel's avatar
Laurent Montel committed
130
    setProgressDialogLabel(i18n("Backing up transports..."));
Laurent Montel's avatar
Laurent Montel committed
131

132
    const QString mailtransportsStr(QStringLiteral("mailtransports"));
Laurent Montel's avatar
Laurent Montel committed
133
    const QString maitransportsrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + mailtransportsStr;
134
    if (!QFileInfo::exists(maitransportsrc)) {
Laurent Montel's avatar
Laurent Montel committed
135
        Q_EMIT info(i18n("Transports backup done."));
Laurent Montel's avatar
Laurent Montel committed
136
    } else {
Laurent Montel's avatar
Laurent Montel committed
137
        KSharedConfigPtr mailtransportsConfig = KSharedConfig::openConfig(mailtransportsStr);
Laurent Montel's avatar
Laurent Montel committed
138

Laurent Montel's avatar
Laurent Montel committed
139
        QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
140
        tmp.open();
Laurent Montel's avatar
Laurent Montel committed
141
        KConfig *config = mailtransportsConfig->copyTo(tmp.fileName());
Laurent Montel's avatar
Laurent Montel committed
142

Laurent Montel's avatar
Laurent Montel committed
143
        config->sync();
Laurent Montel's avatar
Laurent Montel committed
144
        const bool fileAdded = archive()->addLocalFile(tmp.fileName(), Utils::transportsPath() + QStringLiteral("mailtransports"));
Laurent Montel's avatar
Laurent Montel committed
145
        delete config;
Laurent Montel's avatar
Laurent Montel committed
146
        if (fileAdded) {
Laurent Montel's avatar
Laurent Montel committed
147
            Q_EMIT info(i18n("Transports backup done."));
Laurent Montel's avatar
Laurent Montel committed
148
        } else {
Laurent Montel's avatar
Laurent Montel committed
149
            Q_EMIT error(i18n("Transport file cannot be added to backup file."));
Laurent Montel's avatar
Laurent Montel committed
150
        }
Laurent Montel's avatar
Laurent Montel committed
151
    }
152
153
}

Laurent Montel's avatar
Laurent Montel committed
154
void ExportMailJobInterface::slotCheckBackupResources()
Laurent Montel's avatar
Laurent Montel committed
155
156
157
158
159
160
161
162
163
164
165
166
{
    if (checkBackupType(Utils::Resources)) {
        backupResources();
        increaseProgressDialog();
        if (wasCanceled()) {
            Q_EMIT jobFinished();
            return;
        }
    }
    Q_EMIT jobFinished();
}

Laurent Montel's avatar
Laurent Montel committed
167
void ExportMailJobInterface::backupConfig()
168
{
Laurent Montel's avatar
Laurent Montel committed
169
    setProgressDialogLabel(i18n("Backing up config..."));
Laurent Montel's avatar
Laurent Montel committed
170

171
    exportFilters();
172

173
    backupUiRcFile(QStringLiteral("sieveeditorui.rc"), QStringLiteral("sieveeditor"));
174
175
176
177
    backupUiRcFile(QStringLiteral("kmreadermainwin.rc"), QStringLiteral("kmail2"));
    backupUiRcFile(QStringLiteral("kmcomposerui.rc"), QStringLiteral("kmail2"));
    backupUiRcFile(QStringLiteral("kmmainwin.rc"), QStringLiteral("kmail2"));
    backupUiRcFile(QStringLiteral("kmail_part.rc"), QStringLiteral("kmail2"));
Laurent Montel's avatar
Laurent Montel committed
178
    backupUiRcFile(QStringLiteral("kontactsummary_part.rc"), QStringLiteral("kontactsummary"));
179
180
    backupUiRcFile(QStringLiteral("kontactui.rc"), QStringLiteral("kontact"));
    backupUiRcFile(QStringLiteral("kleopatra.rc"), QStringLiteral("kleopatra"));
Laurent Montel's avatar
Laurent Montel committed
181
182
183
    backupUiRcFile(QStringLiteral("headerthemeeditorui.rc"), QStringLiteral("headerthemeeditor"));
    backupUiRcFile(QStringLiteral("contactthemeeditorui.rc"), QStringLiteral("contactthemeeditor"));
    backupUiRcFile(QStringLiteral("contactprintthemeeditorui.rc"), QStringLiteral("contactprintthemeeditor"));
Laurent Montel's avatar
Laurent Montel committed
184
    backupUiRcFile(QStringLiteral("kwatchgnupgui.rc"), QStringLiteral("kwatchgnupg"));
185
    backupUiRcFile(QStringLiteral("akonadiconsoleui.rc"), QStringLiteral("akonadiconsole"));
186

187
188
189
190
191
192
193
194
    backupConfigFile(QStringLiteral("kabldaprc"));
    backupConfigFile(QStringLiteral("kmailsnippetrc"));
    backupConfigFile(QStringLiteral("sievetemplaterc"));
    backupConfigFile(QStringLiteral("customtemplatesrc"));
    backupConfigFile(QStringLiteral("kontactrc"));
    backupConfigFile(QStringLiteral("kontact_summaryrc"));
    backupConfigFile(QStringLiteral("storageservicerc"));
    backupConfigFile(QStringLiteral("kpimbalooblacklist"));
Laurent Montel's avatar
Laurent Montel committed
195
    backupConfigFile(QStringLiteral("kleopatrarc"));
Laurent Montel's avatar
Laurent Montel committed
196
    backupConfigFile(QStringLiteral("sieveeditorrc"));
Laurent Montel's avatar
Laurent Montel committed
197
    backupConfigFile(QStringLiteral("kwatchgnupgrc"));
Laurent Montel's avatar
Laurent Montel committed
198
    backupConfigFile(QStringLiteral("pimpluginsrc"));
Laurent Montel's avatar
Laurent Montel committed
199
    backupConfigFile(QStringLiteral("texttospeechrc"));
200
    backupConfigFile(QStringLiteral("kleopatracertificateselectiondialogrc"));
Laurent Montel's avatar
Laurent Montel committed
201
    backupConfigFile(QStringLiteral("dkimsettingsrc"));
Laurent Montel's avatar
Laurent Montel committed
202

203
    //Notify file config
204
205
206
207
208
209
210
211
212
213
    backupConfigFile(QStringLiteral("akonadi_mailfilter_agent.notifyrc"));
    backupConfigFile(QStringLiteral("akonadi_sendlater_agent.notifyrc"));
    backupConfigFile(QStringLiteral("akonadi_archivemail_agent.notifyrc"));
    backupConfigFile(QStringLiteral("kmail2.notifyrc"));
    backupConfigFile(QStringLiteral("akonadi_newmailnotifier_agent.notifyrc"));
    backupConfigFile(QStringLiteral("akonadi_maildispatcher_agent.notifyrc"));
    backupConfigFile(QStringLiteral("akonadi_followupreminder_agent.notifyrc"));
    backupConfigFile(QStringLiteral("messagevieweradblockrc"));
    backupConfigFile(QStringLiteral("messageviewer.notifyrc"));

214
215
    const QString folderMailArchiveStr(QStringLiteral("foldermailarchiverc"));
    const QString folderMailArchiverc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + folderMailArchiveStr;
216
    if (QFileInfo::exists(folderMailArchiverc)) {
217
218
219
220
221
222
223
224
        KSharedConfigPtr archivemailrc = KSharedConfig::openConfig(folderMailArchiveStr);

        QTemporaryFile tmp;
        tmp.open();

        KConfig *archiveConfig = archivemailrc->copyTo(tmp.fileName());
        const QStringList archiveList = archiveConfig->groupList().filter(QRegularExpression(QStringLiteral("FolderArchiveAccount")));

Laurent Montel's avatar
Laurent Montel committed
225
        for (const QString &str : archiveList) {
226
            KConfigGroup oldGroup = archiveConfig->group(str);
Laurent Montel's avatar
Laurent Montel committed
227
            const qint64 id = oldGroup.readEntry("topLevelCollectionId", -1);
Laurent Montel's avatar
Laurent Montel committed
228
            if (id != -1) {
229
                const QString realPath = convertToFullCollectionPath(id);
230
231
232
233
234
235
236
237
238
239
240
                if (!realPath.isEmpty()) {
                    oldGroup.writeEntry(QStringLiteral("topLevelCollectionId"), realPath);
                }
            }
        }
        archiveConfig->sync();

        backupFile(tmp.fileName(), Utils::configsPath(), folderMailArchiveStr);
        delete archiveConfig;
    }

241
    const QString archiveMailAgentConfigurationStr(QStringLiteral("akonadi_archivemail_agentrc"));
Laurent Montel's avatar
Laurent Montel committed
242
    const QString archiveMailAgentconfigurationrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + archiveMailAgentConfigurationStr;
243
    if (QFileInfo::exists(archiveMailAgentconfigurationrc)) {
Laurent Montel's avatar
Laurent Montel committed
244
245
        KSharedConfigPtr archivemailrc = KSharedConfig::openConfig(archiveMailAgentConfigurationStr);

Laurent Montel's avatar
Laurent Montel committed
246
        QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
247
248
        tmp.open();

Laurent Montel's avatar
Laurent Montel committed
249
        KConfig *archiveConfig = archivemailrc->copyTo(tmp.fileName());
Laurent Montel's avatar
Laurent Montel committed
250
        const QStringList archiveList = archiveConfig->groupList().filter(QRegularExpression(QStringLiteral("ArchiveMailCollection \\d+")));
251
        const QString archiveGroupPattern = QStringLiteral("ArchiveMailCollection ");
Laurent Montel's avatar
Laurent Montel committed
252

Laurent Montel's avatar
Laurent Montel committed
253
        for (const QString &str : archiveList) {
Laurent Montel's avatar
Laurent Montel committed
254
            bool found = false;
Sergio Martins's avatar
Sergio Martins committed
255
            const int collectionId = str.rightRef(str.length() - archiveGroupPattern.length()).toInt(&found);
Laurent Montel's avatar
Laurent Montel committed
256
257
            if (found) {
                KConfigGroup oldGroup = archiveConfig->group(str);
258
                const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
259
260
                if (!realPath.isEmpty()) {
                    const QString collectionPath(archiveGroupPattern + realPath);
Laurent Montel's avatar
Laurent Montel committed
261
262
                    KConfigGroup newGroup(archiveConfig, collectionPath);
                    oldGroup.copyTo(&newGroup);
263
                    newGroup.writeEntry(QStringLiteral("saveCollectionId"), collectionPath);
Laurent Montel's avatar
Laurent Montel committed
264
265
266
                }
                oldGroup.deleteGroup();
            }
267
        }
Laurent Montel's avatar
Laurent Montel committed
268
        archiveConfig->sync();
269

Laurent Montel's avatar
Laurent Montel committed
270
        backupFile(tmp.fileName(), Utils::configsPath(), archiveMailAgentConfigurationStr);
Laurent Montel's avatar
Laurent Montel committed
271
        delete archiveConfig;
Laurent Montel's avatar
Laurent Montel committed
272
    }
273

274
    const QString templatesconfigurationrcStr(QStringLiteral("templatesconfigurationrc"));
Laurent Montel's avatar
Laurent Montel committed
275
    const QString templatesconfigurationrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + templatesconfigurationrcStr;
276
    if (QFileInfo::exists(templatesconfigurationrc)) {
Laurent Montel's avatar
Laurent Montel committed
277
278
        KSharedConfigPtr templaterc = KSharedConfig::openConfig(templatesconfigurationrcStr);

Laurent Montel's avatar
Laurent Montel committed
279
        QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
280
281
        tmp.open();

Laurent Montel's avatar
Laurent Montel committed
282
        KConfig *templateConfig = templaterc->copyTo(tmp.fileName());
283
        const QString templateGroupPattern = QStringLiteral("Templates #");
284
        const QStringList templateList = templateConfig->groupList().filter(QRegularExpression(QStringLiteral("Templates #\\d+")));
Laurent Montel's avatar
Laurent Montel committed
285
        for (const QString &str : templateList) {
Laurent Montel's avatar
Laurent Montel committed
286
            bool found = false;
Sergio Martins's avatar
Sergio Martins committed
287
            const int collectionId = str.rightRef(str.length() - templateGroupPattern.length()).toInt(&found);
Laurent Montel's avatar
Laurent Montel committed
288
289
            if (found) {
                KConfigGroup oldGroup = templateConfig->group(str);
290
                const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
291
                if (!realPath.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
292
293
                    KConfigGroup newGroup(templateConfig, templateGroupPattern + realPath);
                    oldGroup.copyTo(&newGroup);
Laurent Montel's avatar
Laurent Montel committed
294
295
296
297
298
                }
                oldGroup.deleteGroup();
            }
        }
        templateConfig->sync();
299

Laurent Montel's avatar
Laurent Montel committed
300
        backupFile(tmp.fileName(), Utils::configsPath(), templatesconfigurationrcStr);
Laurent Montel's avatar
Laurent Montel committed
301
        delete templateConfig;
Laurent Montel's avatar
Laurent Montel committed
302
    }
303

304
    storeDirectory(QStringLiteral("/messageviewerplugins/"));
Laurent Montel's avatar
Laurent Montel committed
305
    storeDirectory(QStringLiteral("/messageviewer/themes/"));
Laurent Montel's avatar
Laurent Montel committed
306

Laurent Montel's avatar
Laurent Montel committed
307
    const QDir gravatarDirectory(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/gravatar/"));
Laurent Montel's avatar
Laurent Montel committed
308
309
310
311
    if (gravatarDirectory.exists()) {
        const QFileInfoList listFileInfo = gravatarDirectory.entryInfoList(QStringList() << QStringLiteral("*.png"), QDir::Files);
        const int listSize(listFileInfo.size());
        for (int i = 0; i < listSize; ++i) {
Laurent Montel's avatar
Laurent Montel committed
312
            backupFile(listFileInfo.at(i).absoluteFilePath(), Utils::dataPath() + QStringLiteral("gravatar/"), listFileInfo.at(i).fileName());
Laurent Montel's avatar
Laurent Montel committed
313
314
315
        }
    }

Laurent Montel's avatar
Laurent Montel committed
316
    const QDir autocorrectDirectory(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/autocorrect/"));
317
    if (autocorrectDirectory.exists()) {
Laurent Montel's avatar
Laurent Montel committed
318
        const QFileInfoList listFileInfo = autocorrectDirectory.entryInfoList(QStringList() << QStringLiteral("*.xml"), QDir::Files);
Laurent Montel's avatar
Laurent Montel committed
319
320
        const int listSize(listFileInfo.size());
        for (int i = 0; i < listSize; ++i) {
Laurent Montel's avatar
Laurent Montel committed
321
            backupFile(listFileInfo.at(i).absoluteFilePath(), Utils::dataPath() + QStringLiteral("autocorrect/"), listFileInfo.at(i).fileName());
322
323
        }
    }
Laurent Montel's avatar
Laurent Montel committed
324
    const QString adblockFilePath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kmail2/adblockrules_local");
325
    if (QFileInfo::exists(adblockFilePath)) {
Laurent Montel's avatar
Laurent Montel committed
326
        backupFile(adblockFilePath, Utils::dataPath() + QStringLiteral("kmail2/"), QStringLiteral("adblockrules_local"));
327
    }
328

329
    const QString kmailStr(QStringLiteral("kmail2rc"));
Laurent Montel's avatar
Laurent Montel committed
330
    const QString kmail2rc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + kmailStr;
331
    if (QFileInfo::exists(kmail2rc)) {
Laurent Montel's avatar
Laurent Montel committed
332
333
        KSharedConfigPtr kmailrc = KSharedConfig::openConfig(kmail2rc);

Laurent Montel's avatar
Laurent Montel committed
334
        QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
335
336
        tmp.open();

Laurent Montel's avatar
Laurent Montel committed
337
        KConfig *kmailConfig = kmailrc->copyTo(tmp.fileName());
338
        const QString folderGroupPattern = QStringLiteral("Folder-");
339
        const QStringList folderList = kmailConfig->groupList().filter(QRegularExpression(QStringLiteral("Folder-\\d+")));
Laurent Montel's avatar
Laurent Montel committed
340
        for (const QString &str : folderList) {
Laurent Montel's avatar
Laurent Montel committed
341
            bool found = false;
Sergio Martins's avatar
Sergio Martins committed
342
            const int collectionId = str.rightRef(str.length() - folderGroupPattern.length()).toInt(&found);
Laurent Montel's avatar
Laurent Montel committed
343
344
            if (found) {
                KConfigGroup oldGroup = kmailConfig->group(str);
345
                ImportExportMailUtil::cleanupFolderSettings(oldGroup);
346
                const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
347
                if (!realPath.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
348
349
                    KConfigGroup newGroup(kmailConfig, folderGroupPattern + realPath);
                    oldGroup.copyTo(&newGroup);
Laurent Montel's avatar
Laurent Montel committed
350
351
352
                }
                oldGroup.deleteGroup();
            }
353
        }
354
        const QString composerStr(QStringLiteral("Composer"));
Laurent Montel's avatar
Laurent Montel committed
355
356
        if (kmailConfig->hasGroup(composerStr)) {
            KConfigGroup composerGroup = kmailConfig->group(composerStr);
357
            const QString previousStr(QStringLiteral("previous-fcc"));
Laurent Montel's avatar
Laurent Montel committed
358
            if (composerGroup.hasKey(previousStr)) {
Laurent Montel's avatar
Laurent Montel committed
359
360
                const int collectionId = composerGroup.readEntry(previousStr, -1);
                if (collectionId != -1) {
361
                    const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
362
                    composerGroup.writeEntry(previousStr, realPath);
Laurent Montel's avatar
Laurent Montel committed
363
364
                }
            }
365
366
        }

367
        const QString generalStr(QStringLiteral("General"));
Laurent Montel's avatar
Laurent Montel committed
368
369
        if (kmailConfig->hasGroup(generalStr)) {
            KConfigGroup generalGroup = kmailConfig->group(generalStr);
370
            const QString startupFolderStr(QStringLiteral("startupFolder"));
Laurent Montel's avatar
Laurent Montel committed
371
            if (generalGroup.hasKey(startupFolderStr)) {
Laurent Montel's avatar
Laurent Montel committed
372
373
                const int collectionId = generalGroup.readEntry(startupFolderStr, -1);
                if (collectionId != -1) {
374
                    const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
375
                    generalGroup.writeEntry(startupFolderStr, realPath);
Laurent Montel's avatar
Laurent Montel committed
376
377
                }
            }
378
379
        }

380
        const QString storageModelSelectedMessageStr(QStringLiteral("MessageListView::StorageModelSelectedMessages"));
Laurent Montel's avatar
Laurent Montel committed
381
382
        if (kmailConfig->hasGroup(storageModelSelectedMessageStr)) {
            KConfigGroup storageGroup = kmailConfig->group(storageModelSelectedMessageStr);
383
            const QString storageModelSelectedPattern(QStringLiteral("MessageUniqueIdForStorageModel"));
Laurent Montel's avatar
Laurent Montel committed
384
            const QStringList storageList = storageGroup.keyList().filter(QRegularExpression(QStringLiteral("MessageUniqueIdForStorageModel\\d+")));
Laurent Montel's avatar
Laurent Montel committed
385
            for (const QString &str : storageList) {
Laurent Montel's avatar
Laurent Montel committed
386
                bool found = false;
Sergio Martins's avatar
Sergio Martins committed
387
                const int collectionId = str.rightRef(str.length() - storageModelSelectedPattern.length()).toInt(&found);
Laurent Montel's avatar
Laurent Montel committed
388
389
                const QString oldValue = storageGroup.readEntry(str);
                if (found) {
390
                    const QString realPath = convertToFullCollectionPath(collectionId);
Laurent Montel's avatar
Laurent Montel committed
391
                    if (!realPath.isEmpty()) {
Laurent Montel's avatar
Clazy++    
Laurent Montel committed
392
                        storageGroup.writeEntry(QStringLiteral("%1%2").arg(storageModelSelectedPattern, realPath), oldValue);
Laurent Montel's avatar
Laurent Montel committed
393
                        storageGroup.deleteEntry(str);
394
395
                    } else {
                        storageGroup.deleteEntry(str);
Laurent Montel's avatar
Laurent Montel committed
396
397
398
                    }
                }
            }
399
        }
400

401
        const QString collectionFolderViewStr(QStringLiteral("CollectionFolderView"));
402
403
        if (kmailConfig->hasGroup(collectionFolderViewStr)) {
            KConfigGroup favoriteGroup = kmailConfig->group(collectionFolderViewStr);
404

405
            const QString currentKey(QStringLiteral("Current"));
406
            convertCollectionToRealPath(favoriteGroup, currentKey);
407

408
            const QString expensionKey(QStringLiteral("Expansion"));
409
            convertCollectionListToRealPath(favoriteGroup, expensionKey);
410
411
        }

412
        const QString favoriteCollectionStr(QStringLiteral("FavoriteCollections"));
Laurent Montel's avatar
Laurent Montel committed
413
414
        if (kmailConfig->hasGroup(favoriteCollectionStr)) {
            KConfigGroup favoriteGroup = kmailConfig->group(favoriteCollectionStr);
415

416
            const QString favoriteCollectionIdsStr(QStringLiteral("FavoriteCollectionIds"));
417
            convertCollectionIdsToRealPath(favoriteGroup, favoriteCollectionIdsStr);
418
419
        }

420
421
422
423
424
425
        const QString favoriteCollectionOrderStr(QStringLiteral("FavoriteCollectionsOrder"));
        if (kmailConfig->hasGroup(favoriteCollectionOrderStr)) {
            KConfigGroup favoriteGroup = kmailConfig->group(favoriteCollectionOrderStr);
            //For favorite id for root collection == 0 and we store only folder => c
            const QString favoriteCollectionIdsStr(QStringLiteral("0"));
            const QString prefixCollection(QStringLiteral("c"));
426
            convertCollectionIdsToRealPath(favoriteGroup, favoriteCollectionIdsStr, prefixCollection);
427
428
        }

429
430
431
432
433
        //Event collection
        const QString eventCollectionStr(QStringLiteral("Event"));
        if (kmailConfig->hasGroup(eventCollectionStr)) {
            KConfigGroup eventGroup = kmailConfig->group(eventCollectionStr);
            const QString eventLastEventSelectedFolder(QStringLiteral("LastEventSelectedFolder"));
434
            convertCollectionIdsToRealPath(eventGroup, eventLastEventSelectedFolder);
435
436
437
438
439
440
441
        }

        //Todo collection
        const QString todoCollectionStr(QStringLiteral("Todo"));
        if (kmailConfig->hasGroup(todoCollectionStr)) {
            KConfigGroup todoGroup = kmailConfig->group(todoCollectionStr);
            const QString todoLastEventSelectedFolder(QStringLiteral("LastSelectedFolder"));
442
            convertCollectionIdsToRealPath(todoGroup, todoLastEventSelectedFolder);
443
        }
444
445
446
447
448
        //FolderSelectionDialog collection
        const QString folderSelectionCollectionStr(QStringLiteral("FolderSelectionDialog"));
        if (kmailConfig->hasGroup(folderSelectionCollectionStr)) {
            KConfigGroup folderSelectionGroup = kmailConfig->group(folderSelectionCollectionStr);
            const QString folderSelectionSelectedFolder(QStringLiteral("LastSelectedFolder"));
449
            convertCollectionIdsToRealPath(folderSelectionGroup, folderSelectionSelectedFolder);
450
451
        }

452
453
454
455
456
        //Note collection
        const QString noteCollectionStr(QStringLiteral("Note"));
        if (kmailConfig->hasGroup(noteCollectionStr)) {
            KConfigGroup noteGroup = kmailConfig->group(noteCollectionStr);
            const QString noteLastEventSelectedFolder(QStringLiteral("LastNoteSelectedFolder"));
457
            convertCollectionIdsToRealPath(noteGroup, noteLastEventSelectedFolder);
458
459
        }

460
461
462
463
464
465
466
467
        //Convert MessageListTab collection id
        const QString messageListPaneStr(QStringLiteral("MessageListPane"));
        if (kmailConfig->hasGroup(messageListPaneStr)) {
            KConfigGroup messageListPaneGroup = kmailConfig->group(messageListPaneStr);
            const int numberOfTab = messageListPaneGroup.readEntry(QStringLiteral("tabNumber"), 0);
            for (int i = 0; i < numberOfTab; ++i) {
                KConfigGroup messageListPaneTabGroup = kmailConfig->group(QStringLiteral("MessageListTab%1").arg(i));
                const QString messageListPaneTabFolderStr(QStringLiteral("collectionId"));
468
                convertCollectionIdsToRealPath(messageListPaneTabGroup, messageListPaneTabFolderStr);
469
470
471
            }
        }

472
        //Automatic Add Contacts
473
474
        KIdentityManagement::IdentityManager::ConstIterator end = mIdentityManager->end();
        for (KIdentityManagement::IdentityManager::ConstIterator it = mIdentityManager->begin(); it != end; ++it) {
475
476
477
478
479
            const uint identity = (*it).uoid();
            const QString groupId = QStringLiteral("Automatic Add Contacts %1").arg(identity);
            if (kmailConfig->hasGroup(groupId)) {
                KConfigGroup identityGroup = kmailConfig->group(groupId);
                const QString automaticAddContactStr(QStringLiteral("Collection"));
480
                convertCollectionIdsToRealPath(identityGroup, automaticAddContactStr);
481
482
483
484
            }
        }

        //TODO add confirm address too
485

Laurent Montel's avatar
Laurent Montel committed
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
        //Clean up kmail2rc
        const QString tipOfDaysStr(QStringLiteral("TipOfDay"));
        if (kmailConfig->hasGroup(tipOfDaysStr)) {
            kmailConfig->deleteGroup(tipOfDaysStr);
        }
        const QString startupStr(QStringLiteral("Startup"));
        if (kmailConfig->hasGroup(startupStr)) {
            kmailConfig->deleteGroup(startupStr);
        }

        const QString search(QStringLiteral("Search"));
        if (kmailConfig->hasGroup(search)) {
            KConfigGroup searchGroup = kmailConfig->group(search);
            searchGroup.deleteGroup();
        }

Laurent Montel's avatar
Laurent Montel committed
502
        kmailConfig->sync();
Laurent Montel's avatar
Laurent Montel committed
503
        backupFile(tmp.fileName(), Utils::configsPath(), kmailStr);
Laurent Montel's avatar
Laurent Montel committed
504
        delete kmailConfig;
Laurent Montel's avatar
Laurent Montel committed
505
    }
506

Laurent Montel's avatar
Laurent Montel committed
507
    Q_EMIT info(i18n("Config backup done."));
508
509
}

Laurent Montel's avatar
Laurent Montel committed
510
void ExportMailJobInterface::backupIdentity()
511
{
Laurent Montel's avatar
Laurent Montel committed
512
    setProgressDialogLabel(i18n("Backing up identity..."));
Laurent Montel's avatar
Laurent Montel committed
513

514
    const QString emailidentitiesStr(QStringLiteral("emailidentities"));
Laurent Montel's avatar
Laurent Montel committed
515
    const QString emailidentitiesrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + emailidentitiesStr;
516
    if (QFileInfo::exists(emailidentitiesrc)) {
Laurent Montel's avatar
Laurent Montel committed
517
        KSharedConfigPtr identity = KSharedConfig::openConfig(emailidentitiesrc);
Laurent Montel's avatar
Laurent Montel committed
518

Laurent Montel's avatar
Laurent Montel committed
519
        QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
520
521
        tmp.open();

Laurent Montel's avatar
Laurent Montel committed
522
        KConfig *identityConfig = identity->copyTo(tmp.fileName());
523
        const QStringList accountList = identityConfig->groupList().filter(QRegularExpression(QStringLiteral("Identity #\\d+")));
Laurent Montel's avatar
Laurent Montel committed
524
        for (const QString &account : accountList) {
Laurent Montel's avatar
Laurent Montel committed
525
            KConfigGroup group = identityConfig->group(account);
526
            const QString fcc = QStringLiteral("Fcc");
Laurent Montel's avatar
Laurent Montel committed
527
            if (group.hasKey(fcc)) {
528
                const QString realPath = convertToFullCollectionPath(group.readEntry(fcc).toLongLong());
529
                group.writeEntry(fcc, realPath);
Laurent Montel's avatar
Laurent Montel committed
530
            }
531
            const QString draft = QStringLiteral("Drafts");
Laurent Montel's avatar
Laurent Montel committed
532
            if (group.hasKey(draft)) {
533
                const QString realPath = convertToFullCollectionPath(group.readEntry(draft).toLongLong());
534
                group.writeEntry(draft, realPath);
Laurent Montel's avatar
Laurent Montel committed
535
            }
536
            const QString templates = QStringLiteral("Templates");
Laurent Montel's avatar
Laurent Montel committed
537
            if (group.hasKey(templates)) {
538
                const QString realPath = convertToFullCollectionPath(group.readEntry(templates).toLongLong());
539
                group.writeEntry(templates, realPath);
Laurent Montel's avatar
Laurent Montel committed
540
            }
541
            const QString vcard = QStringLiteral("VCardFile");
Laurent Montel's avatar
Laurent Montel committed
542
543
544
            if (group.hasKey(vcard)) {
                const QString vcardFileName = group.readEntry(vcard);
                if (!vcardFileName.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
545
                    const int uoid = group.readEntry(QStringLiteral("uoid"), -1);
Laurent Montel's avatar
Laurent Montel committed
546
547
                    QFile file(vcardFileName);
                    if (file.exists()) {
Laurent Montel's avatar
Laurent Montel committed
548
                        const bool fileAdded = archive()->addLocalFile(vcardFileName, Utils::identitiesPath() + QString::number(uoid) + QLatin1Char('/') + file.fileName());
Laurent Montel's avatar
Laurent Montel committed
549
550
551
                        if (!fileAdded) {
                            Q_EMIT error(i18n("vCard file \"%1\" cannot be saved.", file.fileName()));
                        }
Laurent Montel's avatar
Laurent Montel committed
552
553
554
                    } else {
                        group.deleteEntry(vcard);
                    }
555
                }
Laurent Montel's avatar
Laurent Montel committed
556
557
558
            }
        }

Laurent Montel's avatar
Laurent Montel committed
559
        identityConfig->sync();
Laurent Montel's avatar
Laurent Montel committed
560
        const bool fileAdded = archive()->addLocalFile(tmp.fileName(), Utils::identitiesPath() + QStringLiteral("emailidentities"));
Laurent Montel's avatar
Laurent Montel committed
561
        delete identityConfig;
Laurent Montel's avatar
Laurent Montel committed
562
        if (fileAdded) {
Laurent Montel's avatar
Laurent Montel committed
563
            Q_EMIT info(i18n("Identity backup done."));
Laurent Montel's avatar
Laurent Montel committed
564
        } else {
Laurent Montel's avatar
Laurent Montel committed
565
            Q_EMIT error(i18n("Identity file cannot be added to backup file."));
Laurent Montel's avatar
Laurent Montel committed
566
        }
Laurent Montel's avatar
Laurent Montel committed
567
    }
568
}
Laurent Montel's avatar
Laurent Montel committed
569
570
571
572
573
574
575
576

void ExportMailJobInterface::slotMailsJobTerminated()
{
    if (wasCanceled()) {
        Q_EMIT jobFinished();
        return;
    }
    mIndexIdentifier++;
577
    QTimer::singleShot(0, this, &ExportMailJobInterface::slotWriteNextArchiveResource);
Laurent Montel's avatar
Laurent Montel committed
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
}

void ExportMailJobInterface::slotWriteNextArchiveResource()
{
    if (mIndexIdentifier < mAkonadiInstanceInfo.count()) {
        const Utils::AkonadiInstanceInfo agent = mAkonadiInstanceInfo.at(mIndexIdentifier);
        const QStringList capabilities(agent.capabilities);
        if (agent.mimeTypes.contains(KMime::Message::mimeType())) {
            if (capabilities.contains(QLatin1String("Resource"))
                && !capabilities.contains(QLatin1String("Virtual"))
                && !capabilities.contains(QLatin1String("MailTransport"))) {
                const QString identifier = agent.identifier;
                if (identifier.contains(QLatin1String("akonadi_maildir_resource_"))
                    || identifier.contains(QLatin1String("akonadi_mixedmaildir_resource_"))) {
                    const QString archivePath = Utils::mailsPath() + identifier + QLatin1Char('/');
593
                    const QString url = resourcePath(identifier);
Laurent Montel's avatar
Laurent Montel committed
594
595
596
597
598
599
600
601
602
603
604
605
                    if (!mAgentPaths.contains(url)) {
                        if (!url.isEmpty()) {
                            mAgentPaths << url;
                            exportResourceToArchive(archivePath, url, identifier);
                        } else {
                            qCDebug(PIMDATAEXPORTERCORE_LOG) << "Url is empty for " << identifier;
                            QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
                        }
                    } else {
                        QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
                    }
                } else if (identifier.contains(QLatin1String("akonadi_mbox_resource_"))) {
606
                    backupMailResourceFile(identifier, Utils::mailsPath()); //FIxME addressbookPath or MailPAth ???
Laurent Montel's avatar
Laurent Montel committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
                    QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
                } else {
                    QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
                }
            } else {
                QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
            }
        } else {
            QTimer::singleShot(0, this, &ExportMailJobInterface::slotMailsJobTerminated);
        }
    } else {
        QTimer::singleShot(0, this, &ExportMailJobInterface::slotCheckBackupResources);
    }
}

622
623
624
625
626
627
628
629
630
631
632
633
634
635
void ExportMailJobInterface::backupResources()
{
    setProgressDialogLabel(i18n("Backing up resources..."));

    for (const Utils::AkonadiInstanceInfo &agent : qAsConst(mAkonadiInstanceInfo)) {
        const QStringList capabilities(agent.capabilities);
        if (agent.mimeTypes.contains(KMime::Message::mimeType())) {
            if (capabilities.contains(QLatin1String("Resource"))
                && !capabilities.contains(QLatin1String("Virtual"))
                && !capabilities.contains(QLatin1String("MailTransport"))) {
                const QString identifier = agent.identifier;
                //Store just pop3/imap/kolab/gmail account. Store other config when we copy data.
                if (identifier.contains(QLatin1String("pop3")) || identifier.contains(QLatin1String("imap"))
                    || identifier.contains(QLatin1String("_kolab_")) || identifier.contains(QLatin1String("_gmail_"))) {
Laurent Montel's avatar
Laurent Montel committed
636
                    const QString errorStr = storeResources(archive(), identifier, Utils::resourcesPath());
637
638
639
640
641
642
643
644
645
646
647
648
                    if (!errorStr.isEmpty()) {
                        Q_EMIT error(errorStr);
                    }
                } else {
                    qCDebug(PIMDATAEXPORTERCORE_LOG) << " resource \"" << identifier << "\" will not store";
                }
            }
        }
    }

    Q_EMIT info(i18n("Resources backup done."));
}