File indexing completed on 2025-02-09 07:11:25
0001 /* 0002 This file is part of the Kasten Framework, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2008-2009, 2011, 2014 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "abstractfilesystemsyncwithremotejob_p.hpp" 0010 0011 // library 0012 #include "abstractmodelfilesystemsynchronizer.hpp" 0013 #include <abstractdocument.hpp> 0014 // KF 0015 #include <KIO/FileCopyJob> 0016 #include <KJobWidgets> 0017 // Qt 0018 #include <QFileInfo> 0019 #include <QDateTime> 0020 #include <QTemporaryFile> 0021 0022 namespace Kasten { 0023 0024 void AbstractFileSystemSyncWithRemoteJobPrivate::syncWithRemote() 0025 { 0026 Q_Q(AbstractFileSystemSyncWithRemoteJob); 0027 0028 bool isWorkFileOk; 0029 if (mOption == AbstractModelSynchronizer::ReplaceRemote) { 0030 if (mUrl.isLocalFile()) { 0031 mWorkFilePath = mUrl.toLocalFile(); 0032 mFile = new QFile(mWorkFilePath); 0033 isWorkFileOk = mFile->open(QIODevice::WriteOnly); 0034 } else { 0035 auto* temporaryFile = new QTemporaryFile; 0036 isWorkFileOk = temporaryFile->open(); 0037 0038 mWorkFilePath = temporaryFile->fileName(); 0039 mTempFilePath = mWorkFilePath; 0040 mFile = temporaryFile; 0041 } 0042 if (!isWorkFileOk) { 0043 q->setErrorText(mFile->errorString()); 0044 } 0045 } else { 0046 if (mUrl.isLocalFile()) { 0047 // file protocol. We do not need the network 0048 mWorkFilePath = mUrl.toLocalFile(); 0049 isWorkFileOk = true; 0050 } else { 0051 QTemporaryFile tmpFile; 0052 tmpFile.setAutoRemove(false); 0053 tmpFile.open(); 0054 0055 mWorkFilePath = tmpFile.fileName(); 0056 mTempFilePath = mWorkFilePath; 0057 0058 KIO::FileCopyJob* fileCopyJob = 0059 KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite); 0060 KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); 0061 0062 isWorkFileOk = fileCopyJob->exec(); 0063 if (!isWorkFileOk) { 0064 q->setErrorText(fileCopyJob->errorString()); 0065 } 0066 } 0067 0068 if (isWorkFileOk) { 0069 mFile = new QFile(mWorkFilePath); 0070 isWorkFileOk = mFile->open(QIODevice::ReadWrite); 0071 if (!isWorkFileOk) { 0072 q->setErrorText(mFile->errorString()); 0073 } 0074 } 0075 } 0076 0077 if (isWorkFileOk) { 0078 const QUrl oldUrl = mSynchronizer->url(); 0079 if (oldUrl.isLocalFile()) { 0080 mSynchronizer->stopFileWatching(); 0081 } else { 0082 mSynchronizer->stopNetworkWatching(); 0083 } 0084 0085 q->startSyncWithRemote(); 0086 } else { 0087 q->setError(KJob::KilledJobError); 0088 delete mFile; 0089 // TODO: should we rather skip completeSync in success API? 0090 q->emitResult(); 0091 } 0092 } 0093 0094 void AbstractFileSystemSyncWithRemoteJobPrivate::completeSync(bool success) 0095 { 0096 Q_Q(AbstractFileSystemSyncWithRemoteJob); 0097 0098 if (success) { 0099 mFile->close(); // TODO: when is new time written, on close? 0100 QFileInfo fileInfo(*mFile); 0101 mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); 0102 0103 mSynchronizer->setUrl(mUrl); 0104 0105 if (!mUrl.isLocalFile()) { 0106 KIO::FileCopyJob* fileCopyJob = 0107 KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), mUrl, -1, KIO::Overwrite); 0108 KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); 0109 0110 const bool uploaded = fileCopyJob->exec(); 0111 if (!uploaded) { 0112 q->setError(KJob::KilledJobError); 0113 q->setErrorText(fileCopyJob->errorString()); 0114 } else { 0115 mSynchronizer->startNetworkWatching(); 0116 mSynchronizer->setRemoteState(RemoteUnknown); 0117 } 0118 } else { 0119 mSynchronizer->startFileWatching(); 0120 mSynchronizer->setRemoteState(RemoteInSync); 0121 } 0122 0123 } else { 0124 q->setError(KJob::KilledJobError); 0125 q->setErrorText(mFile->errorString()); 0126 } 0127 0128 delete mFile; 0129 0130 if (!mTempFilePath.isEmpty()) { 0131 QFile::remove(mTempFilePath); 0132 } 0133 0134 q->emitResult(); 0135 } 0136 0137 }