utils.cpp 11.7 KB
Newer Older
1
/*
2
   Copyright (C) 2012-2017 Montel Laurent <montel@kde.org>
Laurent Montel's avatar
Laurent Montel committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

   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.

   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.

   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 "utils.h"
21

Laurent Montel's avatar
Laurent Montel committed
22
#include "MailCommon/MailUtil"
Laurent Montel's avatar
Laurent Montel committed
23
#include "PimCommon/PimUtil"
24

Laurent Montel's avatar
Laurent Montel committed
25
#include <QSettings>
26
#include <KConfigGroup>
Laurent Montel's avatar
Laurent Montel committed
27

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

33
#include <QDir>
Laurent Montel's avatar
Laurent Montel committed
34
#include <QStandardPaths>
35

36 37 38 39 40
QString Utils::exportDataTypeFileName()
{
    return QStringLiteral("exportdatatype.xml");
}

Laurent Montel's avatar
Laurent Montel committed
41 42 43
int Utils::currentArchiveVersion()
{
    //Increase it when we add major feature!
44
    return 2;
Laurent Montel's avatar
Laurent Montel committed
45
}
Laurent Montel's avatar
Laurent Montel committed
46

Laurent Montel's avatar
Laurent Montel committed
47
QString Utils::transportsPath()
48
{
Laurent Montel's avatar
Laurent Montel committed
49
    return QStringLiteral("transports/");
50 51
}

Laurent Montel's avatar
Laurent Montel committed
52
QString Utils::resourcesPath()
53
{
Laurent Montel's avatar
Laurent Montel committed
54
    return QStringLiteral("resources/");
55 56
}

Laurent Montel's avatar
Laurent Montel committed
57
QString Utils::identitiesPath()
58
{
Laurent Montel's avatar
Laurent Montel committed
59
    return QStringLiteral("identities/");
60 61
}

Laurent Montel's avatar
Laurent Montel committed
62
QString Utils::mailsPath()
63
{
Laurent Montel's avatar
Laurent Montel committed
64
    return QStringLiteral("mails/");
65 66
}

Laurent Montel's avatar
Laurent Montel committed
67
QString Utils::configsPath()
68
{
Laurent Montel's avatar
Laurent Montel committed
69
    return QStringLiteral("configs/");
70 71
}

Laurent Montel's avatar
Laurent Montel committed
72
QString Utils::akonadiPath()
73
{
Laurent Montel's avatar
Laurent Montel committed
74
    return QStringLiteral("akonadi/");
75 76
}

Laurent Montel's avatar
Laurent Montel committed
77
QString Utils::dataPath()
Laurent Montel's avatar
Laurent Montel committed
78
{
Laurent Montel's avatar
Laurent Montel committed
79
    return QStringLiteral("data/");
Laurent Montel's avatar
Laurent Montel committed
80 81
}

Laurent Montel's avatar
Laurent Montel committed
82
QString Utils::calendarPath()
83
{
Laurent Montel's avatar
Laurent Montel committed
84
    return QStringLiteral("calendar/");
85 86
}

Laurent Montel's avatar
Laurent Montel committed
87
QString Utils::addressbookPath()
Laurent Montel's avatar
Laurent Montel committed
88
{
Laurent Montel's avatar
Laurent Montel committed
89
    return QStringLiteral("addressbook/");
Laurent Montel's avatar
Laurent Montel committed
90 91
}

Laurent Montel's avatar
Laurent Montel committed
92
QString Utils::alarmPath()
Laurent Montel's avatar
Laurent Montel committed
93
{
Laurent Montel's avatar
Laurent Montel committed
94
    return QStringLiteral("alarm/");
Laurent Montel's avatar
Laurent Montel committed
95 96
}

97 98
QString Utils::jotPath()
{
Laurent Montel's avatar
Laurent Montel committed
99
    return QStringLiteral("jot/");
100 101
}

Laurent Montel's avatar
Laurent Montel committed
102 103
QString Utils::notePath()
{
Laurent Montel's avatar
Laurent Montel committed
104
    return QStringLiteral("note/");
Laurent Montel's avatar
Laurent Montel committed
105 106
}

Laurent Montel's avatar
Laurent Montel committed
107 108
QString Utils::prefixAkonadiConfigFile()
{
Laurent Montel's avatar
Laurent Montel committed
109
    return QStringLiteral("agent_config_");
Laurent Montel's avatar
Laurent Montel committed
110
}
111

Laurent Montel's avatar
Laurent Montel committed
112 113
QString Utils::infoPath()
{
Laurent Montel's avatar
Laurent Montel committed
114
    return QStringLiteral("information/");
Laurent Montel's avatar
Laurent Montel committed
115 116
}

117
QString Utils::adaptResourcePath(KSharedConfigPtr resourceConfig, const QString &storedData)
Laurent Montel's avatar
Laurent Montel committed
118
{
119 120 121 122
    QString newUrl = Utils::resourcePath(resourceConfig);
    if (!newUrl.contains(QDir::homePath())) {
        QFileInfo fileInfo(newUrl);
        fileInfo.fileName();
Laurent Montel's avatar
Laurent Montel committed
123
        //qCDebug(PIMSETTINGEXPORTERCORE_LOG)<<" url "<<url.path();
124 125 126 127
        QString currentPath = QDir::homePath() + QLatin1Char('/') + storedData;
        newUrl = (currentPath + QLatin1Char('/') + fileInfo.fileName());
        if (!QDir(currentPath).exists()) {
            QDir().mkdir(currentPath);
128
        }
Laurent Montel's avatar
Laurent Montel committed
129
    }
130
    if (QFileInfo::exists(newUrl)) {
131 132
        QString newFileName = newUrl;
        QFileInfo fileInfo(newFileName);
Laurent Montel's avatar
Laurent Montel committed
133
        for (int i = 0;; ++i) {
134 135
            const QString currentPath = fileInfo.path() + QLatin1Char('/') + QString::number(i) + QLatin1Char('/');
            newFileName = currentPath + fileInfo.fileName();
136
            if (!QFileInfo::exists(newFileName)) {
137
                QDir().mkdir(currentPath);
Laurent Montel's avatar
Laurent Montel committed
138 139 140
                break;
            }
        }
141
        newUrl = newFileName;
Laurent Montel's avatar
Laurent Montel committed
142 143 144
    }
    return newUrl;
}
Laurent Montel's avatar
Laurent Montel committed
145

146
QString Utils::resourcePath(KSharedConfigPtr resourceConfig, const QString &defaultPath)
147
{
148
    KConfigGroup group = resourceConfig->group(QStringLiteral("General"));
Laurent Montel's avatar
Laurent Montel committed
149
    QString url = group.readEntry(QStringLiteral("Path"), defaultPath);
150 151 152
    if (!url.isEmpty()) {
        url.replace(QLatin1String("$HOME"), QDir::homePath());
    }
153
    return url;
154
}
155

156
void Utils::convertCollectionIdsToRealPath(KConfigGroup &group, const QString &currentKey)
157 158
{
    if (group.hasKey(currentKey)) {
Laurent Montel's avatar
Laurent Montel committed
159
        const QStringList value = group.readEntry(currentKey, QStringList());
160
        QStringList newValue;
Laurent Montel's avatar
Laurent Montel committed
161
        for (const QString &str : value) {
162 163 164
            bool found = false;
            const int collectionId = str.toInt(&found);
            if (found) {
Laurent Montel's avatar
Laurent Montel committed
165
                const QString realPath = MailCommon::Util::fullCollectionPath(Akonadi::Collection(collectionId));
166
                if (!realPath.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
167
                    newValue << realPath;
168 169 170
                }
            }
        }
Laurent Montel's avatar
Laurent Montel committed
171
        group.writeEntry(currentKey, newValue);
172 173 174
    }
}

Laurent Montel's avatar
Laurent Montel committed
175
void Utils::convertCollectionListToRealPath(KConfigGroup &group, const QString &currentKey)
176 177 178 179 180 181 182
{
    if (group.hasKey(currentKey)) {
        const QStringList listExpension = group.readEntry(currentKey, QStringList());
        if (listExpension.isEmpty()) {
            group.deleteEntry(currentKey);
        } else {
            QStringList result;
Laurent Montel's avatar
Laurent Montel committed
183
            for (QString collection : listExpension) {
184 185 186 187
                collection = collection.remove(QLatin1Char('c'));
                bool found = false;
                const int collectionValue = collection.toInt(&found);
                if (found && collectionValue != -1) {
Laurent Montel's avatar
Laurent Montel committed
188 189
                    const QString realPath = MailCommon::Util::fullCollectionPath(Akonadi::Collection(collectionValue));
                    if (!realPath.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
190
                        result << realPath;
Laurent Montel's avatar
Laurent Montel committed
191
                    }
192 193 194 195 196 197 198 199 200 201 202
                }
            }
            if (result.isEmpty()) {
                group.deleteEntry(currentKey);
            } else {
                group.writeEntry(currentKey, result);
            }
        }
    }
}

Laurent Montel's avatar
Laurent Montel committed
203
void Utils::convertCollectionToRealPath(KConfigGroup &group, const QString &currentKey)
204 205 206 207 208 209 210 211 212 213
{
    if (group.hasKey(currentKey)) {
        QString collectionId = group.readEntry(currentKey);
        if (collectionId.isEmpty()) {
            group.deleteEntry(currentKey);
        } else {
            collectionId = collectionId.remove(QLatin1Char('c'));
            bool found = false;
            const int collectionValue = collectionId.toInt(&found);
            if (found && collectionValue != -1) {
Laurent Montel's avatar
Laurent Montel committed
214 215
                const QString realPath = MailCommon::Util::fullCollectionPath(Akonadi::Collection(collectionValue));
                group.writeEntry(currentKey, realPath);
216 217 218 219 220 221
            } else {
                group.deleteEntry(currentKey);
            }
        }
    }
}
Laurent Montel's avatar
Laurent Montel committed
222

223
QString Utils::resourcePath(const Akonadi::AgentInstance &agent, const QString &defaultPath)
Laurent Montel's avatar
Laurent Montel committed
224 225
{
    const QString agentFileName = agent.identifier() + QLatin1String("rc");
Laurent Montel's avatar
Laurent Montel committed
226
    const QString configFileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + agentFileName;
Laurent Montel's avatar
Laurent Montel committed
227

Laurent Montel's avatar
Laurent Montel committed
228
    KSharedConfigPtr resourceConfig = KSharedConfig::openConfig(configFileName);
229
    const QString url = Utils::resourcePath(resourceConfig, defaultPath);
Laurent Montel's avatar
Laurent Montel committed
230 231 232
    return url;
}

Laurent Montel's avatar
Laurent Montel committed
233
QString Utils::storeResources(KZip *archive, const QString &identifier, const QString &path)
Laurent Montel's avatar
Laurent Montel committed
234 235
{
    const QString agentFileName = identifier + QLatin1String("rc");
Laurent Montel's avatar
Laurent Montel committed
236
    const QString configFileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + agentFileName;
Laurent Montel's avatar
Laurent Montel committed
237
    qCDebug(PIMSETTINGEXPORTERCORE_LOG) << "configFileName " << configFileName << "agentFileName " << configFileName;
Laurent Montel's avatar
Laurent Montel committed
238

Laurent Montel's avatar
Laurent Montel committed
239
    KSharedConfigPtr resourceConfig = KSharedConfig::openConfig(configFileName);
Laurent Montel's avatar
Laurent Montel committed
240
    QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
241
    tmp.open();
Laurent Montel's avatar
Laurent Montel committed
242
    KConfig *config = resourceConfig->copyTo(tmp.fileName());
Laurent Montel's avatar
Laurent Montel committed
243

244
    if (identifier.contains(POP3_RESOURCE_IDENTIFIER)) {
245
        const QString targetCollection = QStringLiteral("targetCollection");
Laurent Montel's avatar
Laurent Montel committed
246 247
        KConfigGroup group = config->group("General");
        if (group.hasKey(targetCollection)) {
Laurent Montel's avatar
Laurent Montel committed
248
            group.writeEntry(targetCollection, MailCommon::Util::fullCollectionPath(Akonadi::Collection(group.readEntry(targetCollection).toLongLong())));
Laurent Montel's avatar
Laurent Montel committed
249
        }
Laurent Montel's avatar
Laurent Montel committed
250
    } else if (PimCommon::Util::isImapResource(identifier)) {
251
        const QString trash = QStringLiteral("TrashCollection");
Laurent Montel's avatar
Laurent Montel committed
252 253
        KConfigGroup group = config->group("cache");
        if (group.hasKey(trash)) {
Laurent Montel's avatar
Laurent Montel committed
254
            group.writeEntry(trash, MailCommon::Util::fullCollectionPath(Akonadi::Collection(group.readEntry(trash).toLongLong())));
Laurent Montel's avatar
Laurent Montel committed
255 256 257 258
        }
    }
    //Customize resource if necessary here.
    config->sync();
Laurent Montel's avatar
Laurent Montel committed
259
    bool fileAdded  = archive->addLocalFile(tmp.fileName(), path + agentFileName);
Laurent Montel's avatar
Laurent Montel committed
260
    delete config;
Laurent Montel's avatar
Laurent Montel committed
261
    if (!fileAdded) {
Laurent Montel's avatar
Laurent Montel committed
262
        return i18n("Resource file \"%1\" cannot be added to backup file.", agentFileName);
Laurent Montel's avatar
Laurent Montel committed
263
    }
Laurent Montel's avatar
Laurent Montel committed
264 265 266

    const QString agentConfigFileName = QLatin1String("agent_config_") + identifier;
    const QString agentConfigFileNamePath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1String("/akonadi/") + agentConfigFileName;
267
    if (QFileInfo::exists(agentConfigFileNamePath)) {
Laurent Montel's avatar
Laurent Montel committed
268 269 270 271 272 273
        fileAdded  = archive->addLocalFile(agentConfigFileNamePath, path + agentConfigFileName);
        if (!fileAdded) {
            return i18n("Resource file \"%1\" cannot be added to backup file.", agentFileName);
        }
    }

Laurent Montel's avatar
Laurent Montel committed
274 275 276
    return QString();
}

Laurent Montel's avatar
Laurent Montel committed
277
QString Utils::akonadiAgentName(const QString &configPath)
Laurent Montel's avatar
Laurent Montel committed
278
{
Laurent Montel's avatar
Laurent Montel committed
279
    QSettings settings(configPath, QSettings::IniFormat);
Laurent Montel's avatar
Laurent Montel committed
280
    const QString name = settings.value(QStringLiteral("Agent/Name")).toString();
Laurent Montel's avatar
Laurent Montel committed
281 282 283
    return name;
}

Laurent Montel's avatar
Laurent Montel committed
284 285 286 287 288 289 290
KZip *Utils::openZip(const QString &filename, QString &errorMsg)
{
    KZip *zip = new KZip(filename);
    const bool result = zip->open(QIODevice::ReadOnly);
    if (!result) {
        errorMsg = i18n("Archive cannot be opened in read mode.");
        delete zip;
Laurent Montel's avatar
Laurent Montel committed
291
        return nullptr;
Laurent Montel's avatar
Laurent Montel committed
292 293 294
    }
    return zip;
}
Laurent Montel's avatar
Laurent Montel committed
295

296 297
void Utils::storeDataExportInfo(const QString &filename, KZip *archive)
{
298
    if (QFileInfo::exists(filename)) {
299
        const bool fileAdded  = archive->addLocalFile(filename, Utils::infoPath() + Utils::exportDataTypeFileName());
300 301 302 303 304 305 306 307
        if (fileAdded) {
            qCDebug(PIMSETTINGEXPORTERCORE_LOG) << "exporteddata file can not add to archive" << filename;
        }
    } else {
        qCDebug(PIMSETTINGEXPORTERCORE_LOG) << "exported file was not created" << filename;
    }
}

Laurent Montel's avatar
Laurent Montel committed
308 309
void Utils::addVersion(KZip *archive)
{
Laurent Montel's avatar
Laurent Montel committed
310
    QTemporaryFile tmp;
Laurent Montel's avatar
Laurent Montel committed
311
    tmp.open();
312
    const bool fileAdded  = archive->addLocalFile(tmp.fileName(), Utils::infoPath() + QStringLiteral("VERSION_%1").arg(currentArchiveVersion()));
Laurent Montel's avatar
Laurent Montel committed
313
    if (!fileAdded) {
Laurent Montel's avatar
Laurent Montel committed
314
        //TODO add i18n ?
Laurent Montel's avatar
Laurent Montel committed
315
        qCDebug(PIMSETTINGEXPORTERCORE_LOG) << "version file can not add to archive";
Laurent Montel's avatar
Laurent Montel committed
316 317
    }
}
Laurent Montel's avatar
Laurent Montel committed
318 319 320

int Utils::archiveVersion(KZip *archive)
{
Laurent Montel's avatar
Laurent Montel committed
321
    const KArchiveEntry *informationFile = archive->directory()->entry(Utils::infoPath() + QLatin1String("VERSION_1"));
Laurent Montel's avatar
Laurent Montel committed
322 323 324
    if (informationFile && informationFile->isFile()) {
        return 1;
    }
Laurent Montel's avatar
Laurent Montel committed
325
    informationFile = archive->directory()->entry(Utils::infoPath() + QLatin1String("VERSION_2"));
326 327 328
    if (informationFile && informationFile->isFile()) {
        return 2;
    }
Laurent Montel's avatar
Laurent Montel committed
329 330 331
    //TODO add more version when new version
    return 0;
}
Laurent Montel's avatar
Laurent Montel committed
332 333 334

QString Utils::appTypeToI18n(AppsType type)
{
Laurent Montel's avatar
Laurent Montel committed
335
    switch (type) {
Laurent Montel's avatar
Laurent Montel committed
336 337 338 339 340 341 342 343 344 345 346 347 348 349
    case KMail:
        return i18n("KMail");
    case KAddressBook:
        return i18n("KAddressBook");
    case KAlarm:
        return i18n("KAlarm");
    case KOrganizer:
        return i18n("KOrganizer");
    case KNotes:
        return i18n("KNotes");
    case Akregator:
        return i18n("Akregator");
    case Blogilo:
        return i18n("Blogilo");
Laurent Montel's avatar
Laurent Montel committed
350 351
    case Unknown:
        break;
Laurent Montel's avatar
Laurent Montel committed
352
    }
Laurent Montel's avatar
Laurent Montel committed
353
    qCDebug(PIMSETTINGEXPORTERCORE_LOG) << " type unknown " << type;
Laurent Montel's avatar
Laurent Montel committed
354 355 356 357 358
    return QString();
}

QString Utils::storedTypeToI18n(StoredType type)
{
Laurent Montel's avatar
Laurent Montel committed
359
    switch (type) {
Laurent Montel's avatar
Laurent Montel committed
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
    case None:
        return QString();
    case Identity:
        return i18n("Identity");
    case Mails:
        return i18n("Mails");
    case MailTransport:
        return i18n("Mail Transport");
    case Resources:
        return i18n("Resources");
    case Config:
        return i18n("Config");
    case AkonadiDb:
        return i18n("Akonadi Database");
    case Data:
        return i18n("Data");
    }
Laurent Montel's avatar
Laurent Montel committed
377
    qCDebug(PIMSETTINGEXPORTERCORE_LOG) << " type unknown " << type;
Laurent Montel's avatar
Laurent Montel committed
378 379
    return QString();
}