File indexing completed on 2024-03-24 05:49:24
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 "backupplan.h" 0006 #include "kuputils.h" 0007 0008 #include <QDir> 0009 #include <QStandardPaths> 0010 #include <QString> 0011 0012 #include <KFormat> 0013 #include <KLocalizedString> 0014 #include <utility> 0015 0016 BackupPlan::BackupPlan(int pPlanNumber, KSharedConfigPtr pConfig, QObject *pParent) 0017 :KCoreConfigSkeleton(std::move(pConfig), pParent), mPlanNumber(pPlanNumber) 0018 { 0019 setCurrentGroup(QString(QStringLiteral("Plan/%1")).arg(mPlanNumber)); 0020 0021 addItemString(QStringLiteral("Description"), mDescription, 0022 xi18nc("@label Default name for a new backup plan, %1 is the number of the plan in order", 0023 "Backup plan %1", pPlanNumber)); 0024 QStringList lDefaultIncludeList; 0025 lDefaultIncludeList << QDir::homePath(); 0026 addItemStringList(QStringLiteral("Paths included"), mPathsIncluded, lDefaultIncludeList); 0027 QStringList lDefaultExcludeList; 0028 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.cache"); 0029 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.bup"); 0030 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.thumbnails"); 0031 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.local/share/Trash"); 0032 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.local/share/baloo"); 0033 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.local/share/TelegramDesktop/tdata/temp"); 0034 lDefaultExcludeList << QDir::homePath() + QStringLiteral("/.config/Riot/Cache"); 0035 QMutableStringListIterator i(lDefaultExcludeList); 0036 while(i.hasNext()) { 0037 ensureNoTrailingSlash(i.next()); 0038 } 0039 0040 addItemStringList(QStringLiteral("Paths excluded"), mPathsExcluded, lDefaultExcludeList); 0041 addItemInt(QStringLiteral("Backup type"), mBackupType); 0042 addItemInt(QStringLiteral("Backup version"), mBackupVersion); 0043 0044 addItemInt(QStringLiteral("Schedule type"), mScheduleType, 2); 0045 addItemInt(QStringLiteral("Schedule interval"), mScheduleInterval, 1); 0046 addItemInt(QStringLiteral("Schedule interval unit"), mScheduleIntervalUnit, 3); 0047 addItemInt(QStringLiteral("Usage limit"), mUsageLimit, 25); 0048 addItemBool(QStringLiteral("Ask first"), mAskBeforeTakingBackup, true); 0049 0050 addItemInt(QStringLiteral("Destination type"), mDestinationType, 1); 0051 addItem(new KCoreConfigSkeleton::ItemUrl(currentGroup(), 0052 QStringLiteral("Filesystem destination path"), 0053 mFilesystemDestinationPath, 0054 QUrl::fromLocalFile(QDir::homePath() + QStringLiteral("/.bup")))); 0055 addItemString(QStringLiteral("External drive UUID"), mExternalUUID); 0056 addItemPath(QStringLiteral("External drive destination path"), mExternalDestinationPath, i18n("Backups")); 0057 addItemString(QStringLiteral("External volume label"), mExternalVolumeLabel); 0058 addItemULongLong(QStringLiteral("External volume capacity"), mExternalVolumeCapacity); 0059 addItemString(QStringLiteral("External device description"), mExternalDeviceDescription); 0060 addItemInt(QStringLiteral("External partition number"), mExternalPartitionNumber); 0061 addItemInt(QStringLiteral("External partitions count"), mExternalPartitionsOnDrive); 0062 0063 addItemBool(QStringLiteral("Show hidden folders"), mShowHiddenFolders); 0064 addItemBool(QStringLiteral("Generate recovery info"), mGenerateRecoveryInfo); 0065 addItemBool(QStringLiteral("Check backups"), mCheckBackups); 0066 addItemBool(QStringLiteral("Exclude patterns"), mExcludePatterns); 0067 addItemString(QStringLiteral("Exclude patterns file path"), mExcludePatternsPath); 0068 0069 addItemDateTime(QStringLiteral("Last complete backup"), mLastCompleteBackup); 0070 addItemDouble(QStringLiteral("Last backup size"), mLastBackupSize); 0071 addItemDouble(QStringLiteral("Last available space"), mLastAvailableSpace); 0072 addItemUInt(QStringLiteral("Accumulated usage time"), mAccumulatedUsageTime); 0073 load(); 0074 } 0075 0076 void BackupPlan::setPlanNumber(int pPlanNumber) { 0077 mPlanNumber = pPlanNumber; 0078 QString lGroupName = QString(QStringLiteral("Plan/%1")).arg(mPlanNumber); 0079 foreach(KConfigSkeletonItem *lItem, items()) { 0080 lItem->setGroup(lGroupName); 0081 } 0082 } 0083 0084 void BackupPlan::removePlanFromConfig() { 0085 config()->deleteGroup(QString(QStringLiteral("Plan/%1")).arg(mPlanNumber)); 0086 save(); 0087 } 0088 0089 void BackupPlan::copyFrom(const BackupPlan &pPlan) { 0090 mDescription = i18nc("default description of newly duplicated backup plan", 0091 "%1 (copy)", pPlan.mDescription); 0092 mPathsIncluded = pPlan.mPathsIncluded; 0093 mPathsExcluded = pPlan.mPathsExcluded; 0094 mBackupType = pPlan.mBackupType; 0095 mScheduleType = pPlan.mScheduleType; 0096 mScheduleInterval = pPlan.mScheduleInterval; 0097 mScheduleIntervalUnit = pPlan.mScheduleIntervalUnit; 0098 mUsageLimit = pPlan.mUsageLimit; 0099 mAskBeforeTakingBackup = pPlan.mAskBeforeTakingBackup; 0100 mDestinationType = pPlan.mDestinationType; 0101 mFilesystemDestinationPath = pPlan.mFilesystemDestinationPath; 0102 mExternalUUID = pPlan.mExternalUUID; 0103 mExternalDestinationPath = pPlan.mExternalDestinationPath; 0104 mExternalVolumeLabel = pPlan.mExternalVolumeLabel; 0105 mExternalDeviceDescription = pPlan.mExternalDeviceDescription; 0106 mExternalPartitionNumber = pPlan.mExternalPartitionNumber; 0107 mExternalPartitionsOnDrive = pPlan.mExternalPartitionsOnDrive; 0108 mExternalVolumeCapacity = pPlan.mExternalVolumeCapacity; 0109 mShowHiddenFolders = pPlan.mShowHiddenFolders; 0110 mGenerateRecoveryInfo = pPlan.mGenerateRecoveryInfo; 0111 mCheckBackups = pPlan.mCheckBackups; 0112 } 0113 0114 QDateTime BackupPlan::nextScheduledTime() { 0115 Q_ASSERT(mScheduleType == 1); 0116 if(!mLastCompleteBackup.isValid()) 0117 return QDateTime(); //plan has never been run 0118 0119 return mLastCompleteBackup.addSecs(scheduleIntervalInSeconds()); 0120 } 0121 0122 qint64 BackupPlan::scheduleIntervalInSeconds() { 0123 Q_ASSERT(mScheduleType == 1); 0124 0125 switch(mScheduleIntervalUnit) { 0126 case 0: 0127 return mScheduleInterval * 60; 0128 case 1: 0129 return mScheduleInterval * 60 * 60; 0130 case 2: 0131 return mScheduleInterval * 60 * 60 * 24; 0132 case 3: 0133 return mScheduleInterval * 60 * 60 * 24 * 7; 0134 default: 0135 return 0; 0136 } 0137 } 0138 0139 BackupPlan::Status BackupPlan::backupStatus() { 0140 if(!mLastCompleteBackup.isValid()) { 0141 return BAD; 0142 } 0143 if(mScheduleType == MANUAL) { 0144 return NO_STATUS; 0145 } 0146 0147 qint64 lStatus = 5; //trigger BAD status if schedule type is something strange 0148 qint64 lInterval = 1; 0149 0150 switch(mScheduleType) { 0151 case INTERVAL: 0152 lStatus = mLastCompleteBackup.secsTo(QDateTime::currentDateTimeUtc()); 0153 lInterval = scheduleIntervalInSeconds(); 0154 break; 0155 case USAGE: 0156 lStatus = mAccumulatedUsageTime; 0157 lInterval = mUsageLimit * 3600; 0158 break; 0159 } 0160 0161 if(lStatus < lInterval) 0162 return GOOD; 0163 if(lStatus < lInterval * 3) 0164 return MEDIUM; 0165 return BAD; 0166 } 0167 0168 QString BackupPlan::iconName(Status pStatus) { 0169 switch(pStatus) { 0170 case GOOD: 0171 return QStringLiteral("security-high"); 0172 case MEDIUM: 0173 return QStringLiteral("security-medium"); 0174 case BAD: 0175 return QStringLiteral("security-low"); 0176 case NO_STATUS: 0177 break; 0178 } 0179 return QString(); 0180 } 0181 0182 QString BackupPlan::absoluteExcludesFilePath() { 0183 if(QDir::isRelativePath(mExcludePatternsPath)) { 0184 return QDir::homePath() + QDir::separator() + mExcludePatternsPath; 0185 } 0186 return mExcludePatternsPath; 0187 } 0188 0189 void BackupPlan::usrRead() { 0190 //correct the time spec after default read routines. 0191 mLastCompleteBackup.setTimeSpec(Qt::UTC); 0192 QMutableStringListIterator lExcludes(mPathsExcluded); 0193 while(lExcludes.hasNext()) { 0194 ensureNoTrailingSlash(lExcludes.next()); 0195 } 0196 QMutableStringListIterator lIncludes(mPathsIncluded); 0197 while(lIncludes.hasNext()) { 0198 ensureNoTrailingSlash(lIncludes.next()); 0199 } 0200 } 0201 0202 QString BackupPlan::statusText() { 0203 QLocale lLocale; 0204 KFormat lFormat(lLocale); 0205 QString lStatus; 0206 if(mLastCompleteBackup.isValid()) { 0207 QDateTime lLocalTime = mLastCompleteBackup.toLocalTime(); 0208 0209 lStatus += i18nc("%1 is fancy formatted date", "Last saved: %1", 0210 lFormat.formatRelativeDate(lLocalTime.date(), QLocale::LongFormat)); 0211 0212 if(mLastBackupSize > 0.0) { 0213 lStatus += '\n'; 0214 lStatus += i18nc("%1 is storage size of archive", "Size: %1", 0215 lFormat.formatByteSize(mLastBackupSize)); 0216 } 0217 if(mLastAvailableSpace > 0.0) { 0218 lStatus += '\n'; 0219 lStatus += i18nc("%1 is free storage space", "Free space: %1", 0220 lFormat.formatByteSize(mLastAvailableSpace)); 0221 } 0222 } else { 0223 lStatus = xi18nc("@label", "This backup plan has never been run."); 0224 } 0225 return lStatus; 0226 }