count the files deletion and warn if threshold is exceeded

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2024-09-13 12:25:29 +02:00
parent 1bdcb33863
commit 17d5ef6985
4 changed files with 63 additions and 14 deletions

View file

@ -54,6 +54,7 @@ static constexpr char fullLocalDiscoveryIntervalC[] = "fullLocalDiscoveryInterva
static constexpr char notificationRefreshIntervalC[] = "notificationRefreshInterval"; static constexpr char notificationRefreshIntervalC[] = "notificationRefreshInterval";
static constexpr char monoIconsC[] = "monoIcons"; static constexpr char monoIconsC[] = "monoIcons";
static constexpr char promptDeleteC[] = "promptDeleteAllFiles"; static constexpr char promptDeleteC[] = "promptDeleteAllFiles";
static constexpr char deleteFilesThresholdC[] = "deleteFilesThreshold";
static constexpr char crashReporterC[] = "crashReporter"; static constexpr char crashReporterC[] = "crashReporter";
static constexpr char optionalServerNotificationsC[] = "optionalServerNotifications"; static constexpr char optionalServerNotificationsC[] = "optionalServerNotifications";
static constexpr char showCallNotificationsC[] = "showCallNotifications"; static constexpr char showCallNotificationsC[] = "showCallNotifications";
@ -112,6 +113,8 @@ static const QStringList defaultUpdateChannelsList { QStringLiteral("stable"), Q
static const QString defaultUpdateChannelName = "stable"; static const QString defaultUpdateChannelName = "stable";
static const QStringList enterpriseUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("enterprise") }; static const QStringList enterpriseUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("enterprise") };
static const QString defaultEnterpriseChannel = "enterprise"; static const QString defaultEnterpriseChannel = "enterprise";
static constexpr int deleteFilesThresholdDefaultValue = 100;
} }
namespace OCC { namespace OCC {
@ -1038,7 +1041,7 @@ bool ConfigFile::showMainDialogAsNormalWindow() const {
bool ConfigFile::promptDeleteFiles() const bool ConfigFile::promptDeleteFiles() const
{ {
QSettings settings(configFile(), QSettings::IniFormat); QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(promptDeleteC), false).toBool(); return settings.value(QLatin1String(promptDeleteC), true).toBool();
} }
void ConfigFile::setPromptDeleteFiles(bool promptDeleteFiles) void ConfigFile::setPromptDeleteFiles(bool promptDeleteFiles)
@ -1047,6 +1050,18 @@ void ConfigFile::setPromptDeleteFiles(bool promptDeleteFiles)
settings.setValue(QLatin1String(promptDeleteC), promptDeleteFiles); settings.setValue(QLatin1String(promptDeleteC), promptDeleteFiles);
} }
int ConfigFile::deleteFilesThreshold() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(deleteFilesThresholdC), deleteFilesThresholdDefaultValue).toInt();
}
void ConfigFile::setDeleteFilesThreshold(int thresholdValue)
{
QSettings settings(configFile(), QSettings::IniFormat);
settings.setValue(QLatin1String(deleteFilesThresholdC), thresholdValue);
}
bool ConfigFile::monoIcons() const bool ConfigFile::monoIcons() const
{ {
QSettings settings(configFile(), QSettings::IniFormat); QSettings settings(configFile(), QSettings::IniFormat);

View file

@ -93,6 +93,9 @@ public:
[[nodiscard]] bool promptDeleteFiles() const; [[nodiscard]] bool promptDeleteFiles() const;
void setPromptDeleteFiles(bool promptDeleteFiles); void setPromptDeleteFiles(bool promptDeleteFiles);
[[nodiscard]] int deleteFilesThreshold() const;
void setDeleteFilesThreshold(int thresholdValue);
[[nodiscard]] bool crashReporter() const; [[nodiscard]] bool crashReporter() const;
void setCrashReporter(bool enabled); void setCrashReporter(bool enabled);

View file

@ -802,19 +802,7 @@ void SyncEngine::slotDiscoveryFinished()
_progressInfo->_status = ProgressInfo::Reconcile; _progressInfo->_status = ProgressInfo::Reconcile;
emit transmissionProgress(*_progressInfo); emit transmissionProgress(*_progressInfo);
const auto displayDialog = ConfigFile().promptDeleteFiles() && !_syncOptions.isCmd(); if (handleMassDeletion()) {
if (!_hasNoneFiles && _hasRemoveFile && displayDialog) {
qCInfo(lcEngine) << "All the files are going to be changed, asking the user";
int side = 0; // > 0 means more deleted on the server. < 0 means more deleted on the client
for (const auto &it : _syncItems) {
if (it->_instruction == CSYNC_INSTRUCTION_REMOVE) {
side += it->_direction == SyncFileItem::Down ? 1 : -1;
}
}
promptUserBeforePropagation([this, side](auto &&callback){
emit aboutToRemoveAllFiles(side >= 0 ? SyncFileItem::Down : SyncFileItem::Up, callback);
});
return; return;
} }
@ -1106,6 +1094,47 @@ void SyncEngine::finishSync()
qCInfo(lcEngine) << "#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QStringLiteral("Post-Reconcile Finished")) << "ms"; qCInfo(lcEngine) << "#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QStringLiteral("Post-Reconcile Finished")) << "ms";
} }
bool SyncEngine::handleMassDeletion()
{
const auto displayDialog = ConfigFile().promptDeleteFiles() && !_syncOptions.isCmd();
const auto allFilesDeleted = !_hasNoneFiles && _hasRemoveFile;
auto deletionCounter = 0;
for (const auto &oneItem : qAsConst(_syncItems)) {
if (oneItem->_instruction == CSYNC_INSTRUCTION_REMOVE) {
if (oneItem->isDirectory()) {
const auto result = _journal->listFilesInPath(oneItem->_file.toUtf8(), [&deletionCounter] (const auto &oneRecord) {
if (oneRecord.isFile()) {
++deletionCounter;
}
});
if (!result) {
qCDebug(lcEngine()) << "unable to find the number of files within a deleted folder:" << oneItem->_file;
}
} else {
++deletionCounter;
}
}
}
const auto filesDeletedThresholdExceeded = deletionCounter > ConfigFile().deleteFilesThreshold();
if ((allFilesDeleted || filesDeletedThresholdExceeded) && displayDialog) {
qCInfo(lcEngine) << "All the files are going to be changed, asking the user";
int side = 0; // > 0 means more deleted on the server. < 0 means more deleted on the client
for (const auto &it : qAsConst(_syncItems)) {
if (it->_instruction == CSYNC_INSTRUCTION_REMOVE) {
side += it->_direction == SyncFileItem::Down ? 1 : -1;
}
}
promptUserBeforePropagation([this, side](auto &&callback){
emit aboutToRemoveAllFiles(side >= 0 ? SyncFileItem::Down : SyncFileItem::Up, callback);
});
return true;
}
return false;
}
void SyncEngine::handleRemnantReadOnlyFolders() void SyncEngine::handleRemnantReadOnlyFolders()
{ {
promptUserBeforePropagation([this](auto &&callback) { promptUserBeforePropagation([this](auto &&callback) {

View file

@ -369,6 +369,8 @@ private:
void finishSync(); void finishSync();
bool handleMassDeletion();
void handleRemnantReadOnlyFolders(); void handleRemnantReadOnlyFolders();
template <typename T> template <typename T>