File indexing completed on 2024-05-26 05:27:01

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 "importaddressbookjobinterface.h"
0008 #include "archivestorage.h"
0009 
0010 #include <KArchive>
0011 #include <KArchiveEntry>
0012 #include <KConfigGroup>
0013 #include <KLocalizedString>
0014 #include <KZip>
0015 
0016 #include <QDir>
0017 #include <QFile>
0018 #include <QStandardPaths>
0019 #include <QTimer>
0020 
0021 ImportAddressbookJobInterface::ImportAddressbookJobInterface(QObject *parent, Utils::StoredTypes typeSelected, ArchiveStorage *archiveStorage, int numberOfStep)
0022     : AbstractImportExportJob(parent, archiveStorage, typeSelected, numberOfStep)
0023 {
0024     initializeImportJob();
0025 }
0026 
0027 ImportAddressbookJobInterface::~ImportAddressbookJobInterface() = default;
0028 
0029 QString ImportAddressbookJobInterface::configLocation() const
0030 {
0031     return installConfigLocation();
0032 }
0033 
0034 QString ImportAddressbookJobInterface::installConfigLocation() const
0035 {
0036     return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/');
0037 }
0038 
0039 void ImportAddressbookJobInterface::start()
0040 {
0041     Q_EMIT title(i18n("Starting to import KAddressBook settings..."));
0042     mArchiveDirectory = archive()->directory();
0043     createProgressDialog(i18n("Import KAddressBook settings"));
0044     searchAllFiles(mArchiveDirectory, QString(), QStringLiteral("addressbook"));
0045     initializeListStep();
0046     QTimer::singleShot(0, this, &ImportAddressbookJobInterface::slotNextStep);
0047 }
0048 
0049 void ImportAddressbookJobInterface::slotNextStep()
0050 {
0051     ++mIndex;
0052     if (mIndex < mListStep.count()) {
0053         const Utils::StoredType type = mListStep.at(mIndex);
0054         if (type == Utils::Resources) {
0055             restoreResources();
0056         } else if (type == Utils::Config) {
0057             restoreConfig();
0058         }
0059     } else {
0060         Q_EMIT jobFinished();
0061     }
0062 }
0063 
0064 void ImportAddressbookJobInterface::addSpecificResourceSettings(const KSharedConfig::Ptr &resourceConfig,
0065                                                                 const QString &resourceName,
0066                                                                 QMap<QString, QVariant> &settings)
0067 {
0068     if (resourceName == QLatin1StringView("akonadi_vcard_resource")) {
0069         KConfigGroup general = resourceConfig->group(QStringLiteral("General"));
0070         if (general.hasKey(QStringLiteral("DisplayName"))) {
0071             settings.insert(QStringLiteral("DisplayName"), general.readEntry(QStringLiteral("DisplayName")));
0072         }
0073         if (general.hasKey(QStringLiteral("ReadOnly"))) {
0074             settings.insert(QStringLiteral("ReadOnly"), general.readEntry(QStringLiteral("ReadOnly"), false));
0075         }
0076         if (general.hasKey(QStringLiteral("MonitorFile"))) {
0077             settings.insert(QStringLiteral("MonitorFile"), general.readEntry(QStringLiteral("MonitorFile"), true));
0078         }
0079     }
0080 }
0081 
0082 bool ImportAddressbookJobInterface::isAConfigFile(const QString &name) const
0083 {
0084     return name.endsWith(QLatin1StringView("rc"))
0085         && (name.startsWith(QLatin1StringView("akonadi_vcarddir_resource_")) || name.startsWith(QLatin1StringView("akonadi_vcard_resource_"))
0086             || name.startsWith(QLatin1StringView("akonadi_contacts_resource_")));
0087 }
0088 
0089 void ImportAddressbookJobInterface::restoreConfig()
0090 {
0091     increaseProgressDialog();
0092     setProgressDialogLabel(i18n("Restore configs..."));
0093     const QString kaddressbookStr(QStringLiteral("kaddressbookrc"));
0094     const KArchiveEntry *kaddressbookrcentry = mArchiveDirectory->entry(Utils::configsPath() + kaddressbookStr);
0095     if (kaddressbookrcentry && kaddressbookrcentry->isFile()) {
0096         const auto kaddressbookrcFile = static_cast<const KArchiveFile *>(kaddressbookrcentry);
0097         const QString searchExistingFilerc = configLocation() + kaddressbookStr;
0098         const QString installPathFilerc = installConfigLocation() + kaddressbookStr;
0099 
0100         if (QFileInfo::exists(searchExistingFilerc)) {
0101             if (overwriteConfigMessageBox(kaddressbookStr)) {
0102                 importkaddressBookConfig(kaddressbookrcFile, installPathFilerc, kaddressbookStr, Utils::configsPath());
0103             } // Else merge!
0104         } else {
0105             importkaddressBookConfig(kaddressbookrcFile, installPathFilerc, kaddressbookStr, Utils::configsPath());
0106         }
0107     }
0108     restoreUiRcFile(QStringLiteral("kaddressbookui.rc"), QStringLiteral("kaddressbook"));
0109     emitInfo(i18n("Config restored."));
0110     QTimer::singleShot(0, this, &ImportAddressbookJobInterface::slotNextStep);
0111 }
0112 
0113 void ImportAddressbookJobInterface::importkaddressBookConfig(const KArchiveFile *file, const QString &config, const QString &filename, const QString &prefix)
0114 {
0115     copyToFile(file, config, filename, prefix);
0116     KSharedConfig::Ptr kaddressBookConfig = KSharedConfig::openConfig(config);
0117 
0118     convertCollectionListStrToAkonadiId(kaddressBookConfig, QStringLiteral("CollectionViewCheckState"), QStringLiteral("Selection"), true);
0119 
0120     const QString collectionViewStateStr(QStringLiteral("CollectionViewState"));
0121     if (kaddressBookConfig->hasGroup(collectionViewStateStr)) {
0122         KConfigGroup group = kaddressBookConfig->group(collectionViewStateStr);
0123         QString currentKey(QStringLiteral("Current"));
0124         convertRealPathToCollection(group, currentKey, true);
0125 
0126         currentKey = QStringLiteral("Expansion");
0127         convertRealPathToCollectionList(group, currentKey, true);
0128 
0129         currentKey = QStringLiteral("Selection");
0130         convertRealPathToCollection(group, currentKey, true);
0131     }
0132     const QString cvsTemplateDirName = QStringLiteral("/kaddressbook/csv-templates/");
0133     const KArchiveEntry *csvtemplateEntry = mArchiveDirectory->entry(Utils::dataPath() + cvsTemplateDirName);
0134     if (csvtemplateEntry && csvtemplateEntry->isDirectory()) {
0135         const auto csvTemplateDir = static_cast<const KArchiveDirectory *>(csvtemplateEntry);
0136         const QStringList lst = csvTemplateDir->entries();
0137         for (const QString &entryName : lst) {
0138             const KArchiveEntry *entry = csvTemplateDir->entry(entryName);
0139             if (entry && entry->isFile()) {
0140                 const auto csvTemplateFile = static_cast<const KArchiveFile *>(entry);
0141                 const QString name = csvTemplateFile->name();
0142                 QString autocorrectionPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + cvsTemplateDirName;
0143                 if (QFileInfo::exists(autocorrectionPath)) {
0144                     if (overwriteConfigMessageBox(name)) {
0145                         copyToFile(csvTemplateFile, autocorrectionPath + QLatin1Char('/') + name, name, Utils::dataPath() + cvsTemplateDirName);
0146                     }
0147                 } else {
0148                     autocorrectionPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + cvsTemplateDirName;
0149                     copyToFile(csvTemplateFile, autocorrectionPath + QLatin1Char('/') + name, name, Utils::dataPath() + cvsTemplateDirName);
0150                 }
0151             }
0152         }
0153     }
0154 
0155     importDataSubdirectory(QStringLiteral("/kaddressbook/viewertemplates/"));
0156     importDataSubdirectory(QStringLiteral("/kaddressbook/printing/"));
0157     kaddressBookConfig->sync();
0158 }
0159 
0160 void ImportAddressbookJobInterface::restoreResources()
0161 {
0162     emitInfo(i18n("Restore resources..."));
0163     setProgressDialogLabel(i18n("Restore resources..."));
0164     increaseProgressDialog();
0165     QStringList listResource;
0166     listResource << restoreResourceFile(QStringLiteral("akonadi_vcard_resource"), Utils::addressbookPath(), Utils::storeAddressbook());
0167 
0168     if (!mListResourceFile.isEmpty()) {
0169         QDir dir(mTempDirName);
0170         dir.mkdir(Utils::addressbookPath());
0171         const QString copyToDirName(mTempDirName + QLatin1Char('/') + Utils::addressbookPath());
0172         QDir().mkpath(copyToDirName);
0173         const int numberOfResourceFile = mListResourceFile.size();
0174         for (int i = 0; i < numberOfResourceFile; ++i) {
0175             ResourceFiles value = mListResourceFile.at(i);
0176             QMap<QString, QVariant> settings;
0177             if (value.akonadiConfigFile.contains(QLatin1StringView("akonadi_vcarddir_resource_"))
0178                 || value.akonadiConfigFile.contains(QLatin1StringView("akonadi_contacts_resource_"))) {
0179                 const KArchiveEntry *fileResouceEntry = mArchiveDirectory->entry(value.akonadiConfigFile);
0180                 if (fileResouceEntry && fileResouceEntry->isFile()) {
0181                     const auto file = static_cast<const KArchiveFile *>(fileResouceEntry);
0182                     copyArchiveFileTo(file, copyToDirName);
0183                     QString resourceName(file->name());
0184 
0185                     QString filename(resourceName);
0186                     KSharedConfig::Ptr resourceConfig = KSharedConfig::openConfig(copyToDirName + QLatin1Char('/') + resourceName);
0187 
0188                     // TODO fix default path ????? backupaddressbook ???
0189                     const QString newUrl = adaptResourcePath(resourceConfig, Utils::storeAddressbook());
0190                     QFileInfo newUrlInfo(newUrl);
0191                     const QString dataFile = value.akonadiResources;
0192                     const KArchiveEntry *dataResouceEntry = mArchiveDirectory->entry(dataFile);
0193                     if (dataResouceEntry->isFile()) {
0194                         const auto fileEntry = static_cast<const KArchiveFile *>(dataResouceEntry);
0195                         // TODO  adapt directory name too
0196                         extractZipFile(fileEntry,
0197                                        copyToDirName,
0198                                        newUrlInfo.path(),
0199                                        value.akonadiConfigFile.contains(QLatin1StringView("akonadi_contacts_resource_")));
0200                     }
0201                     settings.insert(QStringLiteral("Path"), newUrl);
0202 
0203                     const QString agentConfigFile = value.akonadiAgentConfigFile;
0204                     if (!agentConfigFile.isEmpty()) {
0205                         const KArchiveEntry *akonadiAgentConfigEntry = mArchiveDirectory->entry(agentConfigFile);
0206                         if (akonadiAgentConfigEntry->isFile()) {
0207                             const auto akonadiAgentConfigEntryFile = static_cast<const KArchiveFile *>(akonadiAgentConfigEntry);
0208                             copyArchiveFileTo(akonadiAgentConfigEntryFile, copyToDirName);
0209                             resourceName = akonadiAgentConfigEntryFile->name();
0210                             filename = Utils::akonadiAgentName(copyToDirName + QLatin1Char('/') + resourceName);
0211                         }
0212                     }
0213                     QString instanceType;
0214                     if (value.akonadiConfigFile.contains(QLatin1StringView("akonadi_vcarddir_resource_"))) {
0215                         instanceType = QStringLiteral("akonadi_vcarddir_resource");
0216                     } else if (value.akonadiConfigFile.contains(QLatin1StringView("akonadi_contacts_resource_"))) {
0217                         instanceType = QStringLiteral("akonadi_contacts_resource");
0218                     } else {
0219                         qCWarning(PIMDATAEXPORTERCORE_LOG) << " not supported" << value.akonadiConfigFile;
0220                     }
0221 
0222                     const QString newResource = createResource(instanceType, filename, settings, true);
0223                     infoAboutNewResource(newResource);
0224                     qCDebug(PIMDATAEXPORTERCORE_LOG) << " newResource" << newResource;
0225                     listResource << newResource;
0226                 }
0227             }
0228         }
0229     }
0230 
0231     emitInfo(i18n("Resources restored."));
0232     // It's maildir support. Need to add support
0233     synchronizeResource(listResource);
0234 }
0235 
0236 QString ImportAddressbookJobInterface::applicationName() const
0237 {
0238     return QStringLiteral("[KAddressBook]");
0239 }
0240 
0241 #include "moc_importaddressbookjobinterface.cpp"