File indexing completed on 2024-05-12 16:21:31

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