File indexing completed on 2024-05-05 14:22:25
0001 // SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com> 0002 // 0003 // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #include "edexecutor.h" 0006 #include "backupplan.h" 0007 0008 #include <QAction> 0009 #include <QDir> 0010 #include <QFileInfo> 0011 #include <QMenu> 0012 #include <QTimer> 0013 #include <Solid/DeviceNotifier> 0014 #include <Solid/DeviceInterface> 0015 #include <Solid/StorageDrive> 0016 #include <Solid/StorageVolume> 0017 0018 EDExecutor::EDExecutor(BackupPlan *pPlan, KupDaemon *pKupDaemon) 0019 :PlanExecutor(pPlan, pKupDaemon), mStorageAccess(nullptr), mWantsToRunBackup(false), mWantsToShowFiles(false), mWantsToPurge(false) 0020 { 0021 connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceAdded(QString)), SLOT(deviceAdded(QString))); 0022 connect(Solid::DeviceNotifier::instance(), SIGNAL(deviceRemoved(QString)), SLOT(deviceRemoved(QString))); 0023 } 0024 0025 void EDExecutor::checkStatus() { 0026 QList<Solid::Device> lDeviceList = Solid::Device::listFromType(Solid::DeviceInterface::StorageVolume); 0027 foreach (const Solid::Device &lDevice, lDeviceList) { 0028 deviceAdded(lDevice.udi()); 0029 } 0030 updateAccessibility(); 0031 } 0032 0033 void EDExecutor::deviceAdded(const QString &pUdi) { 0034 Solid::Device lDevice(pUdi); 0035 if(!lDevice.is<Solid::StorageVolume>()) { 0036 return; 0037 } 0038 auto *lVolume = lDevice.as<Solid::StorageVolume>(); 0039 QString lUUID = lVolume->uuid(); 0040 if(lUUID.isEmpty()) { //seems to happen for vfat partitions 0041 Solid::Device lDriveDevice; 0042 if(lDevice.is<Solid::StorageDrive>()) { 0043 lDriveDevice = lDevice; 0044 } else { 0045 lDriveDevice = lDevice.parent(); 0046 } 0047 lUUID += lDriveDevice.description(); 0048 lUUID += QStringLiteral("|"); 0049 lUUID += lVolume->label(); 0050 } 0051 if(mPlan->mExternalUUID == lUUID) { 0052 mCurrentUdi = pUdi; 0053 mStorageAccess = lDevice.as<Solid::StorageAccess>(); 0054 enterAvailableState(); 0055 } 0056 } 0057 0058 void EDExecutor::deviceRemoved(const QString &pUdi) { 0059 if(mCurrentUdi == pUdi) { 0060 mWantsToRunBackup = false; 0061 mCurrentUdi.clear(); 0062 mStorageAccess = nullptr; 0063 enterNotAvailableState(); 0064 } 0065 } 0066 0067 void EDExecutor::updateAccessibility() { 0068 if(mWantsToRunBackup) { 0069 startBackup(); // run startBackup again now that it has been mounted 0070 } else if(mWantsToShowFiles) { 0071 showBackupFiles(); 0072 } else if(mWantsToPurge) { 0073 showBackupPurger(); 0074 } 0075 } 0076 0077 void EDExecutor::startBackup() { 0078 if(!ensureAccessible(mWantsToRunBackup)) { 0079 exitBackupRunningState(false); 0080 return; 0081 } 0082 PlanExecutor::startBackup(); 0083 } 0084 0085 void EDExecutor::showBackupFiles() { 0086 if(!ensureAccessible(mWantsToShowFiles)) { 0087 return; 0088 } 0089 PlanExecutor::showBackupFiles(); 0090 } 0091 0092 void EDExecutor::showBackupPurger() { 0093 if(!ensureAccessible(mWantsToPurge)) { 0094 return; 0095 } 0096 PlanExecutor::showBackupPurger(); 0097 } 0098 0099 bool EDExecutor::ensureAccessible(bool &pReturnLater) { 0100 pReturnLater = false; // reset in case we are here for the second time 0101 if(!mStorageAccess) { 0102 return false; 0103 } 0104 if(mStorageAccess->isAccessible()) { 0105 if(!mStorageAccess->filePath().isEmpty()) { 0106 mDestinationPath = mStorageAccess->filePath(); 0107 mDestinationPath += QStringLiteral("/"); 0108 mDestinationPath += mPlan->mExternalDestinationPath; 0109 QDir lDir(mDestinationPath); 0110 if(!lDir.exists()) { 0111 lDir.mkpath(mDestinationPath); 0112 } 0113 QFileInfo lDestinationInfo(mDestinationPath); 0114 if(lDestinationInfo.exists() && lDestinationInfo.isDir()) { 0115 return true; 0116 } 0117 } 0118 return false; 0119 } 0120 connect(mStorageAccess, SIGNAL(accessibilityChanged(bool,QString)), SLOT(updateAccessibility())); 0121 mStorageAccess->setup(); //try to mount it, fail silently for now. 0122 pReturnLater = true; 0123 return false; 0124 }