File indexing completed on 2025-01-05 04:29:55

0001 /**
0002  * SPDX-FileCopyrightText: 2021 Bart De Vries <bart@mogwai.be>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "storagemovejob.h"
0008 #include "storagemovejoblogging.h"
0009 
0010 #include <QDir>
0011 #include <QFile>
0012 #include <QTimer>
0013 
0014 #include <KLocalizedString>
0015 
0016 StorageMoveJob::StorageMoveJob(const QString &from, const QString &to, QStringList &list, QObject *parent)
0017     : KJob(parent)
0018     , m_from(from)
0019     , m_to(to)
0020     , m_list(list)
0021 {
0022 }
0023 
0024 void StorageMoveJob::start()
0025 {
0026     QTimer::singleShot(0, this, &StorageMoveJob::moveFiles);
0027 }
0028 
0029 void StorageMoveJob::moveFiles()
0030 {
0031     qCDebug(kastsStorageMoveJob) << "Begin moving" << m_list << "from" << m_from << "to" << m_to;
0032 
0033     bool success = true;
0034 
0035     QStringList fileList; // this list will contain all files that need to be moved
0036 
0037     for (QString item : m_list) {
0038         // make a list of files to be moved; path is relative to m_from
0039         if (QFileInfo(m_from + QStringLiteral("/") + item).isDir()) {
0040             // this item is a dir; now add all files in that subdir
0041             QStringList tempList = QDir(m_from + QStringLiteral("/") + item + QStringLiteral("/")).entryList(QDir::Files);
0042             for (QString file : tempList) {
0043                 fileList += item + QStringLiteral("/") + file;
0044             }
0045 
0046             // if the item is a subdir, let's try to create it in the new location
0047             // if this fails, then the destination is not writeable, and the move
0048             // should be aborted
0049             success = QFileInfo().absoluteDir().mkpath(m_to + QStringLiteral("/") + item) && success;
0050         } else if (QFileInfo(m_from + QStringLiteral("/") + item).isFile()) {
0051             // this item is a file; simply add it to the list
0052             fileList += item;
0053         }
0054     }
0055 
0056     if (!success) {
0057         setError(2);
0058         setErrorText(i18n("Destination path not writable"));
0059         emitResult();
0060         return;
0061     }
0062 
0063     setTotalAmount(Files, fileList.size());
0064     setProcessedAmount(Files, 0);
0065 
0066     for (int i = 0; i < fileList.size(); i++) {
0067         // First check if we need to abort this job
0068         if (m_abort) {
0069             // Remove files that were already copied
0070             for (int j = 0; j < i; j++) {
0071                 qCDebug(kastsStorageMoveJob) << "Removing file" << QDir(m_to).absoluteFilePath(fileList[j]);
0072                 QFile(QDir(m_to).absoluteFilePath(fileList[j])).remove();
0073             }
0074             setError(1);
0075             setErrorText(i18n("Operation aborted by user"));
0076             emitResult();
0077             return;
0078         }
0079 
0080         // Now we can start copying
0081         QString fromPath = QDir(m_from).absoluteFilePath(fileList[i]);
0082         QString toPath = QDir(m_to).absoluteFilePath(fileList[i]);
0083         if (QFileInfo::exists(toPath) && (QFileInfo(fromPath).size() == QFileInfo(toPath).size())) {
0084             qCDebug(kastsStorageMoveJob) << "Identical file already exists in destination; skipping" << toPath;
0085         } else {
0086             qCDebug(kastsStorageMoveJob) << "Copy" << fromPath << "to" << toPath;
0087             success = QFile(fromPath).copy(toPath) && success;
0088         }
0089         if (!success)
0090             break;
0091         setProcessedAmount(Files, i + 1);
0092     }
0093 
0094     if (m_abort) {
0095         setError(1);
0096         setErrorText(i18n("Operation aborted by user"));
0097     } else if (success) {
0098         // now it's safe to delete all the files from the original location
0099         for (QString file : fileList) {
0100             QFile(QDir(m_from).absoluteFilePath(file)).remove();
0101             qCDebug(kastsStorageMoveJob) << "Removing file" << QDir(m_from).absoluteFilePath(file);
0102         }
0103 
0104         // delete the directories as well
0105         for (const QString &item : m_list) {
0106             if (!item.isEmpty() && QFileInfo(m_from + QStringLiteral("/") + item).isDir()) {
0107                 QDir(m_from).rmdir(item);
0108             }
0109         }
0110     } else {
0111         setError(2);
0112         setErrorText(i18n("An error occurred while copying data"));
0113     }
0114 
0115     emitResult();
0116 }
0117 
0118 bool StorageMoveJob::doKill()
0119 {
0120     m_abort = true;
0121     return true;
0122 }