File indexing completed on 2024-12-22 05:05:26
0001 /* 0002 SPDX-FileCopyrightText: 2012-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "importcalendarjobinterface.h" 0008 #include "archivestorage.h" 0009 0010 #include <KArchive> 0011 #include <KArchiveDirectory> 0012 #include <KArchiveEntry> 0013 #include <KConfigGroup> 0014 #include <KLocalizedString> 0015 #include <KZip> 0016 0017 #include "pimdataexportcore_debug.h" 0018 0019 #include <QColor> 0020 #include <QDir> 0021 #include <QFile> 0022 #include <QStandardPaths> 0023 #include <QTimer> 0024 0025 ImportCalendarJobInterface::ImportCalendarJobInterface(QObject *parent, Utils::StoredTypes typeSelected, ArchiveStorage *archiveStorage, int numberOfStep) 0026 : AbstractImportExportJob(parent, archiveStorage, typeSelected, numberOfStep) 0027 { 0028 initializeImportJob(); 0029 } 0030 0031 ImportCalendarJobInterface::~ImportCalendarJobInterface() = default; 0032 0033 void ImportCalendarJobInterface::start() 0034 { 0035 Q_EMIT title(i18n("Starting to import KOrganizer settings...")); 0036 mArchiveDirectory = archive()->directory(); 0037 createProgressDialog(i18n("Import KOrganizer settings")); 0038 searchAllFiles(mArchiveDirectory, QString(), QStringLiteral("calendar")); 0039 initializeListStep(); 0040 QTimer::singleShot(0, this, &ImportCalendarJobInterface::slotNextStep); 0041 } 0042 0043 void ImportCalendarJobInterface::slotNextStep() 0044 { 0045 ++mIndex; 0046 if (mIndex < mListStep.count()) { 0047 Utils::StoredType type = mListStep.at(mIndex); 0048 if (type == Utils::Resources) { 0049 restoreResources(); 0050 } else if (type == Utils::Config) { 0051 restoreConfig(); 0052 } else { 0053 qCDebug(PIMDATAEXPORTERCORE_LOG) << Q_FUNC_INFO << " not supported type " << type; 0054 slotNextStep(); 0055 } 0056 } else { 0057 Q_EMIT jobFinished(); 0058 } 0059 } 0060 0061 void ImportCalendarJobInterface::addSpecificResourceSettings(const KSharedConfig::Ptr &resourceConfig, 0062 const QString &resourceName, 0063 QMap<QString, QVariant> &settings) 0064 { 0065 if (resourceName == QLatin1StringView("akonadi_ical_resource")) { 0066 KConfigGroup general = resourceConfig->group(QStringLiteral("General")); 0067 if (general.hasKey(QStringLiteral("DisplayName"))) { 0068 settings.insert(QStringLiteral("DisplayName"), general.readEntry(QStringLiteral("DisplayName"))); 0069 } 0070 if (general.hasKey(QStringLiteral("ReadOnly"))) { 0071 settings.insert(QStringLiteral("ReadOnly"), general.readEntry(QStringLiteral("ReadOnly"), false)); 0072 } 0073 if (general.hasKey(QStringLiteral("MonitorFile"))) { 0074 settings.insert(QStringLiteral("MonitorFile"), general.readEntry(QStringLiteral("MonitorFile"), true)); 0075 } 0076 } 0077 } 0078 0079 bool ImportCalendarJobInterface::isAConfigFile(const QString &name) const 0080 { 0081 return name.endsWith(QLatin1StringView("rc")) 0082 && (name.contains(QLatin1StringView("akonadi_ical_resource_")) || name.contains(QLatin1StringView("akonadi_davgroupware_resource_")) 0083 || name.contains(QLatin1StringView("akonadi_icaldir_resource_")) || name.contains(QLatin1StringView("akonadi_openxchange_resource_")) 0084 || name.contains(QLatin1StringView("akonadi_google_resource_"))); 0085 } 0086 0087 void ImportCalendarJobInterface::restoreConfig() 0088 { 0089 increaseProgressDialog(); 0090 setProgressDialogLabel(i18n("Restore configs...")); 0091 const QString korganizerPrinterrcStr(QStringLiteral("calendar_printing.rc")); 0092 const QString oldKorganizerPrintrrcStr(QStringLiteral("korganizer_printing.rc")); 0093 const KArchiveEntry *oldKorganizerPrinterEntry = mArchiveDirectory->entry(Utils::configsPath() + oldKorganizerPrintrrcStr); 0094 if (oldKorganizerPrinterEntry && oldKorganizerPrinterEntry->isFile()) { 0095 const auto korganizerFile = static_cast<const KArchiveFile *>(oldKorganizerPrinterEntry); 0096 const QString oldKorganizerPrintrrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + korganizerPrinterrcStr; 0097 if (QFileInfo::exists(oldKorganizerPrintrrc)) { 0098 if (overwriteConfigMessageBox(oldKorganizerPrintrrc)) { 0099 copyToFile(korganizerFile, oldKorganizerPrintrrc, oldKorganizerPrintrrcStr, Utils::configsPath()); 0100 } 0101 } else { 0102 copyToFile(korganizerFile, oldKorganizerPrintrrc, oldKorganizerPrintrrcStr, Utils::configsPath()); 0103 } 0104 } else { 0105 const KArchiveEntry *korganizerPrinterEntry = mArchiveDirectory->entry(Utils::configsPath() + korganizerPrinterrcStr); 0106 if (korganizerPrinterEntry && korganizerPrinterEntry->isFile()) { 0107 const auto korganizerFile = static_cast<const KArchiveFile *>(korganizerPrinterEntry); 0108 const QString korganizerPrinterrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + korganizerPrinterrcStr; 0109 if (QFileInfo::exists(korganizerPrinterrc)) { 0110 if (overwriteConfigMessageBox(korganizerPrinterrcStr)) { 0111 copyToFile(korganizerFile, korganizerPrinterrc, korganizerPrinterrcStr, Utils::configsPath()); 0112 } 0113 } else { 0114 copyToFile(korganizerFile, korganizerPrinterrc, korganizerPrinterrcStr, Utils::configsPath()); 0115 } 0116 } 0117 } 0118 0119 { 0120 const QString korganizerStr(QStringLiteral("korganizerrc")); 0121 const KArchiveEntry *korganizerrcentry = mArchiveDirectory->entry(Utils::configsPath() + korganizerStr); 0122 if (korganizerrcentry && korganizerrcentry->isFile()) { 0123 const auto korganizerrcFile = static_cast<const KArchiveFile *>(korganizerrcentry); 0124 const QString korganizerrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + korganizerStr; 0125 if (QFileInfo::exists(korganizerrc)) { 0126 if (overwriteConfigMessageBox(korganizerStr)) { 0127 importkorganizerConfig(korganizerrcFile, korganizerrc, korganizerStr, Utils::configsPath()); 0128 } 0129 } else { 0130 importkorganizerConfig(korganizerrcFile, korganizerrc, korganizerStr, Utils::configsPath()); 0131 } 0132 } 0133 } 0134 0135 { 0136 const QString eventviewStr(QStringLiteral("eventviewsrc")); 0137 const KArchiveEntry *eventviewentry = mArchiveDirectory->entry(Utils::configsPath() + eventviewStr); 0138 if (eventviewentry && eventviewentry->isFile()) { 0139 const auto eventviewrcFile = static_cast<const KArchiveFile *>(eventviewentry); 0140 const QString eventviewrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + eventviewStr; 0141 if (QFileInfo::exists(eventviewrc)) { 0142 if (overwriteConfigMessageBox(eventviewStr)) { 0143 importeventViewConfig(eventviewrcFile, eventviewrc, eventviewStr, Utils::configsPath()); 0144 } 0145 } else { 0146 importeventViewConfig(eventviewrcFile, eventviewrc, eventviewStr, Utils::configsPath()); 0147 } 0148 } 0149 } 0150 { 0151 const QString kalendaracStr(QStringLiteral("kalendaracrc")); 0152 const KArchiveEntry *kalendaracentry = mArchiveDirectory->entry(Utils::configsPath() + kalendaracStr); 0153 if (kalendaracentry && kalendaracentry->isFile()) { 0154 const auto kalendaracFile = static_cast<const KArchiveFile *>(kalendaracentry); 0155 const QString kalendaracrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + kalendaracStr; 0156 if (QFileInfo::exists(kalendaracrc)) { 0157 if (overwriteConfigMessageBox(kalendaracStr)) { 0158 copyToFile(kalendaracFile, kalendaracrc, kalendaracStr, Utils::configsPath()); 0159 } 0160 } else { 0161 copyToFile(kalendaracFile, kalendaracrc, kalendaracStr, Utils::configsPath()); 0162 } 0163 } 0164 } 0165 { 0166 const QString kalendarStr(QStringLiteral("kalendarrc")); 0167 const KArchiveEntry *kalendarentry = mArchiveDirectory->entry(Utils::configsPath() + kalendarStr); 0168 if (kalendarentry && kalendarentry->isFile()) { 0169 const auto kalendarentryFile = static_cast<const KArchiveFile *>(kalendarentry); 0170 const QString kalendarentrycrc = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/') + kalendarStr; 0171 if (QFileInfo::exists(kalendarentrycrc)) { 0172 if (overwriteConfigMessageBox(kalendarStr)) { 0173 importKalendarConfig(kalendarentryFile, kalendarentrycrc, kalendarStr, Utils::configsPath()); 0174 } 0175 } else { 0176 importKalendarConfig(kalendarentryFile, kalendarentrycrc, kalendarStr, Utils::configsPath()); 0177 } 0178 } 0179 } 0180 0181 { 0182 const QString freebusyStr(QStringLiteral("freebusyurls")); 0183 const KArchiveEntry *freebusyentry = mArchiveDirectory->entry(Utils::dataPath() + QLatin1StringView("korganizer/") + freebusyStr); 0184 if (freebusyentry && freebusyentry->isFile()) { 0185 const auto freebusyrcFile = static_cast<const KArchiveFile *>(freebusyentry); 0186 0187 const QString freebusypath = 0188 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/korganizer/") + freebusyStr; 0189 if (QFileInfo::exists(freebusypath)) { 0190 // TODO 4.12 merge it. 0191 if (overwriteConfigMessageBox(freebusyStr)) { 0192 copyToFile(freebusyrcFile, freebusypath, freebusyStr, Utils::dataPath()); 0193 } 0194 } else { 0195 copyToFile(freebusyrcFile, freebusypath, freebusyStr, Utils::dataPath()); 0196 } 0197 } 0198 } 0199 0200 { 0201 const KArchiveEntry *templateEntry = mArchiveDirectory->entry(Utils::dataPath() + QStringLiteral("korganizer/templates/")); 0202 if (templateEntry && templateEntry->isDirectory()) { 0203 // TODO 4.12 verify if template already exists. 0204 const QString templatePath = 0205 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("korganizer/templates/"); 0206 const auto templateDir = static_cast<const KArchiveDirectory *>(templateEntry); 0207 if (!templateDir->copyTo(templatePath)) { 0208 qCDebug(PIMDATAEXPORTERCORE_LOG) << "template cannot copy to " << templatePath; 0209 } 0210 } 0211 } 0212 0213 { 0214 const KArchiveEntry *designerEntry = mArchiveDirectory->entry(Utils::dataPath() + QStringLiteral("korganizer/designer/")); 0215 if (designerEntry && designerEntry->isDirectory()) { 0216 const QString templatePath = 0217 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("korganizer/designer/"); 0218 const auto templateDir = static_cast<const KArchiveDirectory *>(designerEntry); 0219 if (!templateDir->copyTo(templatePath)) { 0220 qCDebug(PIMDATAEXPORTERCORE_LOG) << "template cannot copy to " << templatePath; 0221 } 0222 } 0223 } 0224 0225 restoreUiRcFile(QStringLiteral("korganizerui.rc"), QStringLiteral("korganizer")); 0226 restoreUiRcFile(QStringLiteral("korganizer_part.rc"), QStringLiteral("korganizer")); 0227 0228 restoreConfigFile(QStringLiteral("eventviewsrc")); 0229 emitInfo(i18n("Config restored.")); 0230 QTimer::singleShot(0, this, &ImportCalendarJobInterface::slotNextStep); 0231 } 0232 0233 void ImportCalendarJobInterface::importkorganizerConfig(const KArchiveFile *file, const QString &config, const QString &filename, const QString &prefix) 0234 { 0235 copyToFile(file, config, filename, prefix); 0236 KSharedConfig::Ptr korganizerConfig = KSharedConfig::openConfig(config); 0237 0238 convertCollectionListStrToAkonadiId(korganizerConfig, QStringLiteral("GlobalCollectionSelection"), QStringLiteral("Selection"), true); 0239 convertCollectionListStrToAkonadiId(korganizerConfig, QStringLiteral("CollectionTreeView"), QStringLiteral("Expansion"), true); 0240 convertCollectionListStrToAkonadiId(korganizerConfig, QStringLiteral("GlobalCollectionView"), QStringLiteral("Expansion"), true); 0241 0242 korganizerConfig->sync(); 0243 } 0244 0245 void ImportCalendarJobInterface::importKalendarConfig(const KArchiveFile *file, const QString &config, const QString &filename, const QString &prefix) 0246 { 0247 copyToFile(file, config, filename, prefix); 0248 KSharedConfig::Ptr kalendarConfig = KSharedConfig::openConfig(config); 0249 0250 convertCollectionListStrToAkonadiId(kalendarConfig, QStringLiteral("GlobalCollectionSelection"), QStringLiteral("Selection"), true); 0251 convertResourceColors(kalendarConfig); 0252 kalendarConfig->sync(); 0253 } 0254 0255 void ImportCalendarJobInterface::importeventViewConfig(const KArchiveFile *file, const QString &config, const QString &filename, const QString &prefix) 0256 { 0257 copyToFile(file, config, filename, prefix); 0258 KSharedConfig::Ptr eventviewConfig = KSharedConfig::openConfig(config); 0259 convertResourceColors(eventviewConfig); 0260 eventviewConfig->sync(); 0261 } 0262 0263 void ImportCalendarJobInterface::convertResourceColors(const KSharedConfig::Ptr &config) 0264 { 0265 const QString resourceColorStr(QStringLiteral("Resources Colors")); 0266 if (config->hasGroup(resourceColorStr)) { 0267 KConfigGroup group = config->group(resourceColorStr); 0268 const QStringList keyList = group.keyList(); 0269 for (const QString &key : keyList) { 0270 const Akonadi::Collection::Id id = convertPathToId(key); 0271 if (id != -1) { 0272 const QColor color = group.readEntry(key, QColor()); 0273 group.writeEntry(QString::number(id), color); 0274 } 0275 group.deleteEntry(key); 0276 } 0277 } 0278 } 0279 0280 void ImportCalendarJobInterface::restoreResources() 0281 { 0282 emitInfo(i18n("Restore resources...")); 0283 setProgressDialogLabel(i18n("Restore resources...")); 0284 increaseProgressDialog(); 0285 QStringList listResource; 0286 listResource << restoreResourceFile(QStringLiteral("akonadi_ical_resource"), Utils::calendarPath(), Utils::storeCalendar()); 0287 listResource << restoreResourceFile(QStringLiteral("akonadi_davgroupware_resource"), Utils::calendarPath(), Utils::storeCalendar()); 0288 listResource << restoreResourceFile(QStringLiteral("akonadi_openxchange_resource"), Utils::calendarPath(), Utils::storeCalendar()); 0289 listResource << restoreResourceFile(QStringLiteral("akonadi_google_resource"), Utils::calendarPath(), Utils::storeCalendar()); 0290 0291 if (!mListResourceFile.isEmpty()) { 0292 QDir dir(mTempDirName); 0293 dir.mkdir(Utils::addressbookPath()); 0294 const QString copyToDirName(mTempDirName + QLatin1Char('/') + Utils::calendarPath()); 0295 QDir().mkpath(copyToDirName); 0296 const int numberOfResourceFile = mListResourceFile.size(); 0297 for (int i = 0; i < numberOfResourceFile; ++i) { 0298 ResourceFiles value = mListResourceFile.at(i); 0299 QMap<QString, QVariant> settings; 0300 if (value.akonadiConfigFile.contains(QLatin1StringView("akonadi_icaldir_resource_"))) { 0301 const KArchiveEntry *fileResouceEntry = mArchiveDirectory->entry(value.akonadiConfigFile); 0302 if (fileResouceEntry && fileResouceEntry->isFile()) { 0303 const auto file = static_cast<const KArchiveFile *>(fileResouceEntry); 0304 copyArchiveFileTo(file, copyToDirName); 0305 QString resourceName(file->name()); 0306 0307 QString filename(resourceName); 0308 // TODO adapt filename otherwise it will use all the time the 0309 // same filename. 0310 qCDebug(PIMDATAEXPORTERCORE_LOG) << " filename :" << filename; 0311 0312 KSharedConfig::Ptr resourceConfig = KSharedConfig::openConfig(copyToDirName + QLatin1Char('/') + resourceName); 0313 0314 const QString newUrl = adaptResourcePath(resourceConfig, Utils::storeCalendar()); 0315 QFileInfo newUrlInfo(newUrl); 0316 0317 const QString dataFile = value.akonadiResources; 0318 const KArchiveEntry *dataResouceEntry = mArchiveDirectory->entry(dataFile); 0319 bool isDirResource = value.akonadiConfigFile.contains(QLatin1StringView("akonadi_icaldir_resource_")); 0320 if (dataResouceEntry->isFile()) { 0321 const auto fileEntry = static_cast<const KArchiveFile *>(dataResouceEntry); 0322 // TODO adapt directory name too 0323 extractZipFile(fileEntry, 0324 copyToDirName, 0325 newUrlInfo.path(), 0326 value.akonadiConfigFile.contains(QLatin1StringView("akonadi_icaldir_resource_"))); 0327 } 0328 settings.insert(QStringLiteral("Path"), newUrl); 0329 0330 const QString agentConfigFile = value.akonadiAgentConfigFile; 0331 if (!agentConfigFile.isEmpty()) { 0332 const KArchiveEntry *akonadiAgentConfigEntry = mArchiveDirectory->entry(agentConfigFile); 0333 if (akonadiAgentConfigEntry->isFile()) { 0334 const auto fileEntry = static_cast<const KArchiveFile *>(akonadiAgentConfigEntry); 0335 copyArchiveFileTo(fileEntry, copyToDirName); 0336 resourceName = fileEntry->name(); 0337 filename = Utils::akonadiAgentName(copyToDirName + QLatin1Char('/') + resourceName); 0338 } 0339 } 0340 const QString resourceTypeName = isDirResource ? QStringLiteral("akonadi_icaldir_resource") : QStringLiteral("akonadi_ical_resource"); 0341 const QString newResource = createResource(resourceTypeName, filename, settings, true); 0342 infoAboutNewResource(newResource); 0343 listResource << newResource; 0344 qCDebug(PIMDATAEXPORTERCORE_LOG) << " newResource" << newResource; 0345 } 0346 } 0347 } 0348 } 0349 // It's maildir support. Need to add support 0350 synchronizeResource(listResource); 0351 } 0352 0353 QString ImportCalendarJobInterface::configLocation() const 0354 { 0355 return installConfigLocation(); 0356 } 0357 0358 QString ImportCalendarJobInterface::applicationName() const 0359 { 0360 return QStringLiteral("[Korganizer]"); 0361 } 0362 0363 QString ImportCalendarJobInterface::installConfigLocation() const 0364 { 0365 return QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + QLatin1Char('/'); 0366 } 0367 0368 #include "moc_importcalendarjobinterface.cpp"