migrateapplicationfiles.cpp 7.2 KB
Newer Older
1
/*
2
  SPDX-FileCopyrightText: 2015-2020 Laurent Montel <montel@kde.org>
3

4
  SPDX-License-Identifier: GPL-2.0-or-later
5
6
7
8
*/

#include "migrateapplicationfiles.h"
#include "pimcommon_debug.h"
9

10
#include <Kdelibs4Migration>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <KSharedConfig>
#include <KConfigGroup>
#include <QFile>
#include <QFileInfo>
#include <QDir>

using namespace PimCommon;

class PimCommon::MigrateApplicationFilesPrivate
{
public:
    QVector<MigrateFileInfo> mMigrateInfoList;
    QString mConfigFileName;
    QString mApplicationName;
    Kdelibs4Migration mMigration;
Laurent Montel's avatar
Laurent Montel committed
26
27
    int mMigrateApplicationVersion = 1;
    int mCurrentConfigVersion = 0;
28
29
30
};

MigrateApplicationFiles::MigrateApplicationFiles(QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
31
32
    : QObject(parent)
    , d(new PimCommon::MigrateApplicationFilesPrivate)
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{
}

MigrateApplicationFiles::~MigrateApplicationFiles()
{
    delete d;
}

void MigrateApplicationFiles::finished()
{
    writeConfig();
    Q_EMIT migrateDone();
}

bool MigrateApplicationFiles::start()
{
    if (d->mApplicationName.isEmpty()) {
        qCDebug(PIMCOMMON_LOG) << "Missing application name";
    }
    // Testing for kdehome
    if (!d->mMigration.kdeHomeFound()) {
        finished();
        return false;
    }

    if (d->mMigrateInfoList.isEmpty()) {
        finished();
        return false;
    }

    if (d->mConfigFileName.isEmpty()) {
        qCDebug(PIMCOMMON_LOG) << " config file name not defined.";
        finished();
        return false;
    }
    return migrateConfig();
}

bool MigrateApplicationFiles::migrateConfig()
{
    qCDebug(PIMCOMMON_LOG) << "Start migration...";
Laurent Montel's avatar
Laurent Montel committed
74
    for (const MigrateFileInfo &info : qAsConst(d->mMigrateInfoList)) {
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
        if ((info.version() == -1) || (info.version() > d->mCurrentConfigVersion)) {
            if (info.folder()) {
                migrateFolder(info);
            } else {
                migrateFile(info);
            }
        }
    }
    qCDebug(PIMCOMMON_LOG) << "Migration finished.";
    finished();
    return true;
}

QString MigrateApplicationFiles::applicationName() const
{
    return d->mApplicationName;
}

void MigrateApplicationFiles::setApplicationName(const QString &applicationName)
{
    d->mApplicationName = applicationName;
}

int MigrateApplicationFiles::currentConfigVersion() const
{
    return d->mCurrentConfigVersion;
}

void MigrateApplicationFiles::setCurrentConfigVersion(int currentConfigVersion)
{
    d->mCurrentConfigVersion = currentConfigVersion;
}

QString MigrateApplicationFiles::configFileName() const
{
    return d->mConfigFileName;
}

void MigrateApplicationFiles::setConfigFileName(const QString &configFileName)
{
    d->mConfigFileName = configFileName;
}

void MigrateApplicationFiles::writeConfig()
{
    KSharedConfig::Ptr config = KSharedConfig::openConfig(d->mConfigFileName, KConfig::SimpleConfig);
    KConfigGroup grp = config->group(QStringLiteral("Migratekde4"));
    grp.writeEntry(QStringLiteral("Version"), d->mMigrateApplicationVersion);
    grp.sync();
}

void MigrateApplicationFiles::migrateFolder(const MigrateFileInfo &info)
{
    QString originalPath;
    QString newPath;
    if (info.type() == QLatin1String("data")) {
        originalPath = d->mMigration.locateLocal("data", info.path());
        newPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + info.path();
        QFileInfo fileInfo(newPath);
        QDir().mkpath(fileInfo.absolutePath());
    } else {
        qCDebug(PIMCOMMON_LOG) << "Type not supported: " << info.type();
    }
    if (!originalPath.isEmpty()) {
        copyRecursively(originalPath, newPath);
    }
}

bool MigrateApplicationFiles::copyRecursively(const QString &srcFilePath, const QString &tgtFilePath)
{
    QFileInfo srcFileInfo(srcFilePath);
    if (srcFileInfo.isDir()) {
        QDir targetDir(tgtFilePath);
        targetDir.cdUp();
        if (!targetDir.mkpath(QFileInfo(tgtFilePath).path())) {
            return false;
        }
        QDir sourceDir(srcFilePath);
        const QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
Laurent Montel's avatar
Laurent Montel committed
154
        for (const QString &fileName : fileNames) {
155
156
157
158
159
160
161
162
163
164
165
            const QString newSrcFilePath = srcFilePath + QLatin1Char('/') + fileName;
            const QString newTgtFilePath = tgtFilePath + QLatin1Char('/') + fileName;
            if (!copyRecursively(newSrcFilePath, newTgtFilePath)) {
                return false;
            }
        }
    } else {
        if (!QDir().mkpath(QFileInfo(tgtFilePath).absolutePath())) {
            qCDebug(PIMCOMMON_LOG) << "Can not create path " << srcFileInfo.absolutePath();
            return false;
        }
166
        if (!QFileInfo::exists(tgtFilePath) && !QFile::copy(srcFilePath, tgtFilePath)) {
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
            qCDebug(PIMCOMMON_LOG) << " can't copy" << srcFilePath << " tgtFilePath" << tgtFilePath;
            return false;
        }
    }
    return true;
}

void MigrateApplicationFiles::migrateFile(const MigrateFileInfo &info)
{
    QString originalPath;
    QString newPath;
    if (info.type() == QLatin1String("data")) {
        originalPath = d->mMigration.locateLocal("data", info.path());
        newPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + info.path();
        QFileInfo fileInfo(newPath);
        QDir().mkpath(fileInfo.absolutePath());
    } else {
        qCDebug(PIMCOMMON_LOG) << "Type not supported: " << info.type();
    }

    if (!originalPath.isEmpty()) {
        if (info.filePatterns().isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
189
            if (!QFileInfo::exists(newPath)) {
190
191
192
193
194
195
196
197
                QFile copyFile(originalPath);
                if (!copyFile.copy(newPath)) {
                    qCDebug(PIMCOMMON_LOG) << "impossible to copy " << originalPath << " to " << newPath;
                }
            }
        } else {
            QDir sourceDir(originalPath);
            const QStringList fileNames = sourceDir.entryList(info.filePatterns(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
Laurent Montel's avatar
Laurent Montel committed
198
            for (const QString &file : fileNames) {
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
                QFile copyFile(originalPath + QLatin1Char('/') + file);
                if (!copyFile.copy(newPath + QLatin1Char('/') + file)) {
                    qCDebug(PIMCOMMON_LOG) << "impossible to copy " << copyFile.fileName() << " to " << newPath;
                }
            }
        }
    }
}

int MigrateApplicationFiles::version() const
{
    return d->mMigrateApplicationVersion;
}

void MigrateApplicationFiles::setVersion(int version)
{
    d->mMigrateApplicationVersion = version;
}

bool MigrateApplicationFiles::checkIfNecessary()
{
    if (d->mConfigFileName.isEmpty()) {
        qCDebug(PIMCOMMON_LOG) << " config file name not defined.";
        return false;
    }
    KSharedConfig::Ptr config = KSharedConfig::openConfig(d->mConfigFileName, KConfig::SimpleConfig);
    if (config->hasGroup(QStringLiteral("Migratekde4"))) {
        KConfigGroup grp = config->group(QStringLiteral("Migratekde4"));
        d->mCurrentConfigVersion = grp.readEntry(QStringLiteral("Version"), 0);
        if (d->mCurrentConfigVersion < d->mMigrateApplicationVersion) {
            return true;
        } else {
            return false;
        }
    }
    return true;
}

void MigrateApplicationFiles::insertMigrateInfo(const MigrateFileInfo &info)
{
    if (info.isValid()) {
        d->mMigrateInfoList.append(info);
    }
}