File indexing completed on 2024-12-22 05:05:28

0001 /*
0002    SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "importnotesjobinterface.h"
0008 #include "archivestorage.h"
0009 
0010 #include <KArchive>
0011 #include <KLocalizedString>
0012 
0013 #include <KConfigGroup>
0014 #include <KZip>
0015 
0016 #include <QDir>
0017 #include <QFile>
0018 #include <QStandardPaths>
0019 #include <QTimer>
0020 
0021 ImportNotesJobInterface::ImportNotesJobInterface(QObject *parent, Utils::StoredTypes typeSelected, ArchiveStorage *archiveStorage, int numberOfStep)
0022     : AbstractImportExportJob(parent, archiveStorage, typeSelected, numberOfStep)
0023 {
0024     initializeImportJob();
0025 }
0026 
0027 ImportNotesJobInterface::~ImportNotesJobInterface() = default;
0028 
0029 void ImportNotesJobInterface::slotNextStep()
0030 {
0031     ++mIndex;
0032     if (mIndex < mListStep.count()) {
0033         const Utils::StoredType type = mListStep.at(mIndex);
0034         if (type == Utils::Resources) {
0035             restoreResources();
0036         } else if (type == Utils::Config) {
0037             restoreConfig();
0038         } else {
0039             qCDebug(PIMDATAEXPORTERCORE_LOG) << Q_FUNC_INFO << " not supported type " << type;
0040             slotNextStep();
0041         }
0042     } else {
0043         Q_EMIT jobFinished();
0044     }
0045 }
0046 
0047 void ImportNotesJobInterface::start()
0048 {
0049     Q_EMIT title(i18n("Starting to import KNotes settings..."));
0050     mArchiveDirectory = archive()->directory();
0051     searchAllFiles(mArchiveDirectory, QString(), QStringLiteral("note"));
0052     createProgressDialog(i18n("Import KNotes settings"));
0053     initializeListStep();
0054     QTimer::singleShot(0, this, &ImportNotesJobInterface::slotNextStep);
0055 }
0056 
0057 bool ImportNotesJobInterface::isAConfigFile(const QString &name) const
0058 {
0059     return name.endsWith(QLatin1StringView("rc")) && (name.contains(QLatin1StringView("akonadi_akonotes_resource_")));
0060 }
0061 
0062 QString ImportNotesJobInterface::configLocation() const
0063 {
0064     return installConfigLocation();
0065 }
0066 
0067 QString ImportNotesJobInterface::installConfigLocation() const
0068 {
0069     return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/');
0070 }
0071 
0072 QString ImportNotesJobInterface::applicationName() const
0073 {
0074     return QStringLiteral("[KNotes]");
0075 }
0076 
0077 void ImportNotesJobInterface::restoreConfig()
0078 {
0079     increaseProgressDialog();
0080     setProgressDialogLabel(i18n("Restore configs..."));
0081     const QString knotesStr(QStringLiteral("knotesrc"));
0082     restoreConfigFile(knotesStr);
0083     if (archiveVersion() <= 1) {
0084         const QString globalNoteSettingsStr(QStringLiteral("globalnotesettings"));
0085         restoreConfigFile(globalNoteSettingsStr);
0086     } else {
0087         const QString globalNoteStr(QStringLiteral("globalnotesettings"));
0088         const KArchiveEntry *globalNotecentry = mArchiveDirectory->entry(Utils::configsPath() + globalNoteStr);
0089         if (globalNotecentry && globalNotecentry->isFile()) {
0090             const auto globalNotecentryrc = static_cast<const KArchiveFile *>(globalNotecentry);
0091             const QString searchExistingGlobalNoterc = configLocation() + globalNoteStr;
0092             const QString installPathGlobalNoterc = installConfigLocation() + globalNoteStr;
0093 
0094             if (QFileInfo::exists(searchExistingGlobalNoterc)) {
0095                 if (overwriteConfigMessageBox(globalNoteStr)) {
0096                     importKNoteGlobalSettings(globalNotecentryrc, installPathGlobalNoterc, globalNoteStr, Utils::configsPath());
0097                 } // Else merge!
0098             } else {
0099                 importKNoteGlobalSettings(globalNotecentryrc, installPathGlobalNoterc, globalNoteStr, Utils::configsPath());
0100             }
0101         }
0102     }
0103 
0104     restoreUiRcFile(QStringLiteral("knotesappui.rc"), QStringLiteral("knotes"));
0105     restoreUiRcFile(QStringLiteral("knotesui.rc"), QStringLiteral("knotes"));
0106     restoreUiRcFile(QStringLiteral("knotes_part.rc"), QStringLiteral("knotes"));
0107     restoreConfigFile(QStringLiteral("akonadi_notes_agent.notifyrc"));
0108 
0109     emitInfo(i18n("Config restored."));
0110     QTimer::singleShot(0, this, &ImportNotesJobInterface::slotNextStep);
0111 }
0112 
0113 void ImportNotesJobInterface::restoreData()
0114 {
0115     increaseProgressDialog();
0116     setProgressDialogLabel(i18n("Restore data..."));
0117     if (archiveVersion() <= 1) {
0118         // Knote < knote-akonadi
0119         const KArchiveEntry *notesEntry = mArchiveDirectory->entry(Utils::dataPath() + QStringLiteral("knotes/"));
0120         if (notesEntry && notesEntry->isDirectory()) {
0121             const QString notesPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("knotes/");
0122             overwriteDirectory(notesPath, notesEntry);
0123         }
0124         QTimer::singleShot(0, this, &ImportNotesJobInterface::slotNextStep);
0125     } else {
0126         restoreResources();
0127     }
0128     importDataSubdirectory(QStringLiteral("/knotes/print/theme/"));
0129     emitInfo(i18n("Data restored."));
0130 }
0131 
0132 void ImportNotesJobInterface::importKNoteGlobalSettings(const KArchiveFile *archive, const QString &configrc, const QString &filename, const QString &prefix)
0133 {
0134     copyToFile(archive, configrc, filename, prefix);
0135     KSharedConfig::Ptr globalSettingsConfig = KSharedConfig::openConfig(configrc);
0136 
0137     const QString composerStr(QStringLiteral("SelectNoteFolder"));
0138     if (globalSettingsConfig->hasGroup(composerStr)) {
0139         KConfigGroup composerGroup = globalSettingsConfig->group(composerStr);
0140         const QString previousStr(QStringLiteral("DefaultFolder"));
0141         (void)convertRealPathToCollection(composerGroup, previousStr);
0142     }
0143     globalSettingsConfig->sync();
0144 }
0145 
0146 void ImportNotesJobInterface::restoreResources()
0147 {
0148     emitInfo(i18n("Restore resources..."));
0149     setProgressDialogLabel(i18n("Restore resources..."));
0150     QStringList listResource;
0151     if (!mListResourceFile.isEmpty()) {
0152         QDir dir(mTempDirName);
0153         dir.mkdir(Utils::notePath());
0154         const QString copyToDirName(mTempDirName + QLatin1Char('/') + Utils::notePath());
0155         QDir().mkpath(copyToDirName);
0156         const int numberOfResourceFile = mListResourceFile.size();
0157         for (int i = 0; i < numberOfResourceFile; ++i) {
0158             ResourceFiles value = mListResourceFile.at(i);
0159             QMap<QString, QVariant> settings;
0160             if (value.akonadiConfigFile.contains(QLatin1StringView("akonadi_akonotes_resource_"))) {
0161                 const KArchiveEntry *fileResouceEntry = mArchiveDirectory->entry(value.akonadiConfigFile);
0162                 if (fileResouceEntry && fileResouceEntry->isFile()) {
0163                     const auto file = static_cast<const KArchiveFile *>(fileResouceEntry);
0164                     copyArchiveFileTo(file, copyToDirName);
0165                     QString resourceName(file->name());
0166 
0167                     QString filename(resourceName);
0168                     // TODO adapt filename otherwise it will use all the time the
0169                     // same filename.
0170                     qCDebug(PIMDATAEXPORTERCORE_LOG) << " filename :" << filename;
0171 
0172                     KSharedConfig::Ptr resourceConfig = KSharedConfig::openConfig(copyToDirName + QLatin1Char('/') + resourceName);
0173 
0174                     const QString newUrl = adaptResourcePath(resourceConfig, Utils::backupnote());
0175                     QFileInfo newUrlInfo(newUrl);
0176                     const QString dataFile = value.akonadiResources;
0177                     const KArchiveEntry *dataResouceEntry = mArchiveDirectory->entry(dataFile);
0178                     if (dataResouceEntry->isFile()) {
0179                         const auto file = static_cast<const KArchiveFile *>(dataResouceEntry);
0180                         // TODO  adapt directory name too
0181                         extractZipFile(file, copyToDirName, newUrlInfo.path());
0182                     }
0183                     settings.insert(QStringLiteral("Path"), newUrl);
0184 
0185                     const QString agentConfigFile = value.akonadiAgentConfigFile;
0186                     if (!agentConfigFile.isEmpty()) {
0187                         const KArchiveEntry *akonadiAgentConfigEntry = mArchiveDirectory->entry(agentConfigFile);
0188                         if (akonadiAgentConfigEntry->isFile()) {
0189                             const auto fileEntry = static_cast<const KArchiveFile *>(akonadiAgentConfigEntry);
0190                             copyArchiveFileTo(fileEntry, copyToDirName);
0191                             resourceName = fileEntry->name();
0192                             filename = Utils::akonadiAgentName(copyToDirName + QLatin1Char('/') + resourceName);
0193                         }
0194                     }
0195 
0196                     const QString newResource = createResource(QStringLiteral("akonadi_akonotes_resource"), filename, settings, true);
0197                     infoAboutNewResource(newResource);
0198                     qCDebug(PIMDATAEXPORTERCORE_LOG) << " newResource" << newResource;
0199                     listResource << newResource;
0200                 }
0201             }
0202         }
0203     }
0204     synchronizeResource(listResource);
0205 }
0206 
0207 #include "moc_importnotesjobinterface.cpp"