File indexing completed on 2025-06-29 04:52:39
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "resourceconverterbase.h" 0008 #include "utils.h" 0009 #include <KConfigGroup> 0010 #include <KLocalizedString> 0011 #include <KZip> 0012 #include <PimCommon/PimUtil> 0013 #include <QDir> 0014 #include <QFileInfo> 0015 #include <QTemporaryFile> 0016 0017 ResourceConverterBase::ResourceConverterBase() = default; 0018 0019 ResourceConverterBase::~ResourceConverterBase() = default; 0020 0021 QString ResourceConverterBase::adaptResourcePath(const KSharedConfigPtr &resourceConfig, const QString &storedData) 0022 { 0023 QString newUrl = ResourceConverterBase::resourcePath(resourceConfig); 0024 if (!newUrl.contains(installDefaultDirectory())) { 0025 QFileInfo fileInfo(newUrl); 0026 fileInfo.fileName(); 0027 // qCDebug(PIMDATAEXPORTERCORE_LOG)<<" url "<<url.path(); 0028 QString currentPath = installDefaultDirectory() + QLatin1Char('/') + storedData; 0029 newUrl = (currentPath + QLatin1Char('/') + fileInfo.fileName()); 0030 if (!QDir(currentPath).exists()) { 0031 if (!QDir().mkpath(currentPath)) { 0032 qCWarning(PIMDATAEXPORTERCORE_LOG) << "Impossible to create subpath " << currentPath; 0033 } 0034 } 0035 } 0036 if (QFileInfo::exists(newUrl)) { 0037 QString newFileName = newUrl; 0038 QFileInfo fileInfo(newFileName); 0039 for (int i = 0;; ++i) { 0040 const QString currentPath = fileInfo.path() + QLatin1Char('/') + QString::number(i) + QLatin1Char('/'); 0041 newFileName = currentPath + fileInfo.fileName(); 0042 if (!QFileInfo::exists(newFileName)) { 0043 if (!QDir().mkpath(currentPath)) { 0044 qCWarning(PIMDATAEXPORTERCORE_LOG) << "Impossible to create subpath " << currentPath; 0045 } 0046 break; 0047 } 0048 } 0049 newUrl = newFileName; 0050 } 0051 return newUrl; 0052 } 0053 0054 QString ResourceConverterBase::resourcePath(const KSharedConfigPtr &resourceConfig, const QString &defaultPath) 0055 { 0056 KConfigGroup group = resourceConfig->group(QStringLiteral("General")); 0057 QString url = group.readEntry(QStringLiteral("Path"), defaultPath); 0058 if (!url.isEmpty()) { 0059 url.replace(QLatin1StringView("$HOME"), QDir::homePath()); 0060 } 0061 url = changeResourcePath(url); 0062 return url; 0063 } 0064 0065 QString ResourceConverterBase::resourcePath(const QString &agentIdentifier, const QString &defaultPath) 0066 { 0067 const QString agentFileName = agentIdentifier + QStringLiteral("rc"); 0068 const QString configFileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + agentFileName; 0069 // qDebug() << "configFileName " << configFileName; 0070 0071 KSharedConfigPtr resourceConfig = KSharedConfig::openConfig(configFileName); 0072 const QString url = resourcePath(resourceConfig, defaultPath); 0073 // qDebug() << " resourcePath " << url; 0074 return url; 0075 } 0076 0077 QString ResourceConverterBase::changeResourcePath(QString url) const 0078 { 0079 return url; 0080 } 0081 0082 // Merge two methods I think 0083 void ResourceConverterBase::convertCollectionIdsToRealPath(KConfigGroup &group, const QString ¤tKey, const QString &prefixCollection) 0084 { 0085 if (group.hasKey(currentKey)) { 0086 const QStringList value = group.readEntry(currentKey, QStringList()); 0087 QStringList newValue; 0088 for (QString str : value) { 0089 bool found = false; 0090 if (!prefixCollection.isEmpty() && str.startsWith(prefixCollection)) { 0091 str.remove(0, prefixCollection.length()); 0092 } 0093 const qlonglong collectionId = str.toLongLong(&found); 0094 if (found) { 0095 const QString realPath = convertToFullCollectionPath(collectionId); 0096 if (!realPath.isEmpty()) { 0097 newValue << realPath; 0098 } 0099 } 0100 } 0101 if (newValue.isEmpty()) { 0102 group.deleteEntry(currentKey); 0103 } else { 0104 group.writeEntry(currentKey, newValue); 0105 } 0106 } 0107 } 0108 0109 void ResourceConverterBase::convertCollectionListToRealPath(KConfigGroup &group, const QString ¤tKey) 0110 { 0111 if (group.hasKey(currentKey)) { 0112 const QStringList listExpension = group.readEntry(currentKey, QStringList()); 0113 if (listExpension.isEmpty()) { 0114 group.deleteEntry(currentKey); 0115 } else { 0116 QStringList result; 0117 for (QString collection : listExpension) { 0118 collection.remove(QLatin1Char('c')); 0119 bool found = false; 0120 const qlonglong collectionValue = collection.toLongLong(&found); 0121 if (found && collectionValue != -1) { 0122 const QString realPath = convertToFullCollectionPath(collectionValue); 0123 if (!realPath.isEmpty()) { 0124 result << realPath; 0125 } 0126 } 0127 } 0128 if (result.isEmpty()) { 0129 group.deleteEntry(currentKey); 0130 } else { 0131 group.writeEntry(currentKey, result); 0132 } 0133 } 0134 } 0135 } 0136 0137 void ResourceConverterBase::convertCollectionToRealPath(KConfigGroup &group, const QString ¤tKey) 0138 { 0139 if (group.hasKey(currentKey)) { 0140 QString collectionId = group.readEntry(currentKey); 0141 if (collectionId.isEmpty()) { 0142 group.deleteEntry(currentKey); 0143 } else { 0144 collectionId.remove(QLatin1Char('c')); 0145 bool found = false; 0146 const qlonglong collectionValue = collectionId.toLongLong(&found); 0147 if (found && collectionValue != -1) { 0148 const QString realPath = convertToFullCollectionPath(collectionValue); 0149 group.writeEntry(currentKey, realPath); 0150 } else { 0151 group.deleteEntry(currentKey); 0152 } 0153 } 0154 } 0155 } 0156 0157 QString ResourceConverterBase::agentFileName(const QString &filename) 0158 { 0159 QString agentFileConfigName = filename; 0160 agentFileConfigName.remove(Utils::resourcesPath()); 0161 agentFileConfigName.remove(agentFileConfigName.length() - 2, 2); // Remove "rc" 0162 agentFileConfigName = Utils::resourcesPath() + Utils::prefixAkonadiConfigFile() + agentFileConfigName; 0163 return agentFileConfigName; 0164 } 0165 0166 QString ResourceConverterBase::storeResources(KZip *archive, const QString &identifier, const QString &path) 0167 { 0168 const QString agentFileName = identifier + QStringLiteral("rc"); 0169 const QString configFileName = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + agentFileName; 0170 qCWarning(PIMDATAEXPORTERCORE_LOG) << "configFileName " << configFileName << "agentFileName " << configFileName; 0171 0172 KSharedConfigPtr resourceConfig = KSharedConfig::openConfig(configFileName); 0173 QTemporaryFile tmp; 0174 tmp.open(); 0175 KConfig *config = resourceConfig->copyTo(tmp.fileName()); 0176 0177 if (identifier.contains(POP3_RESOURCE_IDENTIFIER)) { 0178 const QString targetCollection = QStringLiteral("targetCollection"); 0179 KConfigGroup group = config->group(QStringLiteral("General")); 0180 if (group.hasKey(targetCollection)) { 0181 group.writeEntry(targetCollection, convertToFullCollectionPath(group.readEntry(targetCollection).toLongLong())); 0182 } 0183 } else if (PimCommon::Util::isImapResource(identifier)) { 0184 const QString trash = QStringLiteral("TrashCollection"); 0185 KConfigGroup group = config->group(QStringLiteral("cache")); 0186 if (group.hasKey(trash)) { 0187 group.writeEntry(trash, convertToFullCollectionPath(group.readEntry(trash).toLongLong())); 0188 } 0189 } 0190 // Customize resource if necessary here. 0191 config->sync(); 0192 bool fileAdded = archive->addLocalFile(tmp.fileName(), path + agentFileName); 0193 delete config; 0194 if (!fileAdded) { 0195 return i18n("Resource file \"%1\" cannot be added to backup file.", agentFileName); 0196 } 0197 0198 const QString agentConfigFileName = Utils::prefixAkonadiConfigFile() + identifier; 0199 const QString agentConfigFileNamePath = 0200 QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1StringView("/akonadi/") + agentConfigFileName; 0201 if (QFileInfo::exists(agentConfigFileNamePath)) { 0202 fileAdded = archive->addLocalFile(agentConfigFileNamePath, path + agentConfigFileName); 0203 if (!fileAdded) { 0204 return i18n("Resource file \"%1\" cannot be added to backup file.", agentConfigFileNamePath); 0205 } 0206 } else { 0207 return i18n("Resource config file \"%1\" doesn't exist.", agentConfigFileNamePath); 0208 } 0209 0210 return {}; 0211 }