File indexing completed on 2024-05-19 05:16:11

0001 /*
0002     SPDX-FileCopyrightText: 2009 Jonathan Armond <jon.armond@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "kmigratorbase.h"
0008 
0009 #include <Akonadi/AgentInstanceCreateJob>
0010 #include <Akonadi/AgentManager>
0011 #include <Akonadi/AgentType>
0012 
0013 #include "migration_debug.h"
0014 #include <KConfigGroup>
0015 #include <KLocalizedString>
0016 #include <KSharedConfig>
0017 #include <QCoreApplication>
0018 #include <QDir>
0019 #include <QFile>
0020 #include <QFileInfo>
0021 #include <QMetaEnum>
0022 #include <QStandardPaths>
0023 #include <QTimer>
0024 
0025 using namespace Akonadi;
0026 
0027 namespace
0028 {
0029 QString messageTypeToString(KMigratorBase::MessageType type)
0030 {
0031     switch (type) {
0032     case KMigratorBase::Success:
0033         return QStringLiteral("Success");
0034     case KMigratorBase::Skip:
0035         return QStringLiteral("Skipped");
0036     case KMigratorBase::Info:
0037         return QStringLiteral("Info   ");
0038     case KMigratorBase::Warning:
0039         return QStringLiteral("WARNING");
0040     case KMigratorBase::Error:
0041         return QStringLiteral("ERROR  ");
0042     }
0043     Q_ASSERT(false);
0044     return {};
0045 }
0046 }
0047 
0048 KMigratorBase::KMigratorBase()
0049 {
0050     const QString logFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QCoreApplication::applicationName()
0051         + QLatin1StringView("/migration.log");
0052     QFileInfo fileInfo(logFileName);
0053     QDir().mkpath(fileInfo.absolutePath());
0054 
0055     m_logFile = new QFile(logFileName);
0056     if (!m_logFile->open(QFile::Append)) {
0057         delete m_logFile;
0058         m_logFile = nullptr;
0059         qCWarning(MIGRATION_LOG) << "Unable to open log file: " << logFileName;
0060     }
0061     logMessage(Info, QStringLiteral("Starting migration..."));
0062     connect(this, &KMigratorBase::message, this, &KMigratorBase::logMessage);
0063 
0064     // load the vtable before we continue
0065     QTimer::singleShot(0, this, &KMigratorBase::migrate);
0066 }
0067 
0068 KMigratorBase::~KMigratorBase()
0069 {
0070     logMessage(Info, QStringLiteral("Migration finished."));
0071     delete m_logFile;
0072 }
0073 
0074 KMigratorBase::MigrationState KMigratorBase::migrationState(const QString &identifier) const
0075 {
0076     KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Resource ") + identifier);
0077     QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("MigrationState"));
0078     const QString s = cfg.readEntry("MigrationState", e.valueToKey(None));
0079     MigrationState state = (MigrationState)e.keyToValue(s.toLatin1().constData());
0080 
0081     if (state != None) {
0082         const QString resId = cfg.readEntry("ResourceIdentifier", "");
0083         // previously migrated but removed again
0084         if (!AgentManager::self()->instance(resId).isValid()) {
0085             state = None;
0086         }
0087     }
0088 
0089     return state;
0090 }
0091 
0092 void KMigratorBase::setMigrationState(const QString &identifier, MigrationState state, const QString &resId, const QString &type)
0093 {
0094     KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Resource ") + identifier);
0095     QMetaEnum e = metaObject()->enumerator(metaObject()->indexOfEnumerator("MigrationState"));
0096     const QString stateStr = QLatin1StringView(e.valueToKey(state));
0097     cfg.writeEntry("MigrationState", stateStr);
0098     cfg.writeEntry("ResourceIdentifier", resId);
0099     cfg.sync();
0100 
0101     cfg = KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("Bridged"));
0102     QStringList bridgedResources = cfg.readEntry(type + QLatin1StringView("Resources"), QStringList());
0103     if (state == Bridged) {
0104         if (!bridgedResources.contains(identifier)) {
0105             bridgedResources << identifier;
0106         }
0107     } else {
0108         bridgedResources.removeAll(identifier);
0109     }
0110     cfg.writeEntry(type + QLatin1StringView("Resources"), bridgedResources);
0111     cfg.sync();
0112 }
0113 
0114 KJob *KMigratorBase::createAgentInstance(const QString &typeId, QObject *receiver, const char *slot)
0115 {
0116     Q_EMIT message(Info, i18n("Creating instance of type %1", typeId));
0117     auto job = new AgentInstanceCreateJob(typeId, this);
0118     // clang-format off
0119     connect(job, SIGNAL(result(KJob*)), receiver, slot);
0120     // clang-format on
0121     job->start();
0122     return job;
0123 }
0124 
0125 void KMigratorBase::logMessage(KMigratorBase::MessageType type, const QString &msg)
0126 {
0127     if (m_logFile) {
0128         m_logFile->write(QString(QLatin1Char('[') + QDateTime::currentDateTime().toString() + QLatin1StringView("] ") + messageTypeToString(type)
0129                                  + QLatin1StringView(": ") + msg + QLatin1Char('\n'))
0130                              .toUtf8());
0131         m_logFile->flush();
0132     }
0133 }
0134 
0135 #include "moc_kmigratorbase.cpp"