From 1fb3d256a022a4e65a957d6206223695e9627762 Mon Sep 17 00:00:00 2001 From: David Khristepher Santos Date: Mon, 26 Aug 2024 18:38:18 -0700 Subject: [PATCH] Fix issues with initial setup, crashing on startup, and scanning of new folders --- Diffusion.Database/Migrations.cs | 7 + .../Controls/MessagePopup.xaml.cs | 32 +++ Diffusion.Toolkit/MainWindow.xaml.Scanning.cs | 246 +++++++++--------- Diffusion.Toolkit/MainWindow.xaml.cs | 12 +- 4 files changed, 176 insertions(+), 121 deletions(-) diff --git a/Diffusion.Database/Migrations.cs b/Diffusion.Database/Migrations.cs index 255f0ca..7684101 100644 --- a/Diffusion.Database/Migrations.cs +++ b/Diffusion.Database/Migrations.cs @@ -99,6 +99,13 @@ public void Update(MigrationType migrationType) [Migrate(MigrationType.Pre)] private string RupertAvery20240203_0001_UniquePaths() { + var tableExists = _db.ExecuteScalar("SELECT COUNT(1) FROM sqlite_master WHERE type='table' AND name='Image'") == 1; + + if (!tableExists) + { + return null; + } + var dupePaths = _db.QueryScalars("SELECT Path FROM Image GROUP BY Path HAVING COUNT(*) > 1"); void RemoveImages(IEnumerable ids) diff --git a/Diffusion.Toolkit/Controls/MessagePopup.xaml.cs b/Diffusion.Toolkit/Controls/MessagePopup.xaml.cs index 4c3ba5a..4d095d3 100644 --- a/Diffusion.Toolkit/Controls/MessagePopup.xaml.cs +++ b/Diffusion.Toolkit/Controls/MessagePopup.xaml.cs @@ -26,6 +26,13 @@ public MessagePopupHandle ContinueWith(Action closing) return this; } + public async Task CloseAsync() + { + await _popup.WaitUntilReady(); + _popup.Close(); + _closing?.Invoke(); + } + public void Close() { _popup.Close(); @@ -84,6 +91,9 @@ private void Callback2(object? state) } } + + + public MessagePopup(MessagePopupManager manager, UIElement placementTarget, int timeout) : this(manager, placementTarget, timeout, false) { } @@ -91,6 +101,8 @@ public MessagePopup(MessagePopupManager manager, UIElement placementTarget, int public MessagePopup(MessagePopupManager manager, UIElement placementTarget, int timeout, bool showInput) { + _semaphore = new SemaphoreSlim(1); + _manager = manager; _timeout = timeout; InitializeComponent(); @@ -137,6 +149,26 @@ public MessagePopup(MessagePopupManager manager, UIElement placementTarget, int }); DataContext = _model; + + Loaded += OnLoaded; + Unloaded += OnUnloaded; + } + + public async Task WaitUntilReady() + { + await _semaphore.WaitAsync(100); + } + + private void OnUnloaded(object sender, RoutedEventArgs e) + { + _semaphore.Dispose(); + } + + private SemaphoreSlim _semaphore; + + private void OnLoaded(object sender, RoutedEventArgs e) + { + _semaphore.Release(); } diff --git a/Diffusion.Toolkit/MainWindow.xaml.Scanning.cs b/Diffusion.Toolkit/MainWindow.xaml.Scanning.cs index 8c654d2..4e26192 100644 --- a/Diffusion.Toolkit/MainWindow.xaml.Scanning.cs +++ b/Diffusion.Toolkit/MainWindow.xaml.Scanning.cs @@ -38,96 +38,68 @@ await Task.Run(() => { _model.IsBusy = true; }); - - if (options.UseRootFolders) + try { - var rootFolders = options.ImagePaths.Where(f => f.IsSelected); - - var total = 0; - - foreach (var folder in rootFolders) - { - total += _dataStore.CountAllPathImages(folder.Path); - } - Dispatcher.Invoke(() => + if (options.UseRootFolders) { - _model.CurrentProgress = 0; - _model.TotalProgress = total; - }); - - var current = 0; + var rootFolders = options.ImagePaths.Where(f => f.IsSelected); - var scanning = GetLocalizedText("Actions.Scanning.Status"); + var total = 0; - foreach (var folder in rootFolders) - { - if (token.IsCancellationRequested) + foreach (var folder in rootFolders) { - break; + total += _dataStore.CountAllPathImages(folder.Path); } - HashSet ignoreFiles = new HashSet(); + Dispatcher.Invoke(() => + { + _model.CurrentProgress = 0; + _model.TotalProgress = total; + }); - var folderImages = _dataStore.GetAllPathImages(folder.Path).ToDictionary(f => f.Path); + var current = 0; + var scanning = GetLocalizedText("Actions.Scanning.Status"); - if (Directory.Exists(folder.Path)) + foreach (var folder in rootFolders) { - //var filesOnDisk = MetadataScanner.GetFiles(folder.Path, _settings.FileExtensions, null, _settings.RecurseFolders.GetValueOrDefault(true), null); - var filesOnDisk = MetadataScanner.GetFiles(folder.Path, _settings.FileExtensions, ignoreFiles, _settings.RecurseFolders.GetValueOrDefault(true), _settings.ExcludePaths); + if (token.IsCancellationRequested) + { + break; + } + + HashSet ignoreFiles = new HashSet(); - foreach (var file in filesOnDisk) + var folderImages = _dataStore.GetAllPathImages(folder.Path).ToDictionary(f => f.Path); + + + if (Directory.Exists(folder.Path)) { - if (token.IsCancellationRequested) - { - break; - } + //var filesOnDisk = MetadataScanner.GetFiles(folder.Path, _settings.FileExtensions, null, _settings.RecurseFolders.GetValueOrDefault(true), null); + var filesOnDisk = MetadataScanner.GetFiles(folder.Path, _settings.FileExtensions, ignoreFiles, _settings.RecurseFolders.GetValueOrDefault(true), _settings.ExcludePaths); - if (folderImages.TryGetValue(file, out var imagePath)) + foreach (var file in filesOnDisk) { - if (imagePath.Unavailable) + if (token.IsCancellationRequested) { - restoredImages.Add(imagePath.Id); + break; } - folderImages.Remove(file); - } - - current++; - - if (current % 113 == 0) - { - Dispatcher.Invoke(() => + if (folderImages.TryGetValue(file, out var imagePath)) { - _model.CurrentProgress = current; - - var status = scanning - .Replace("{current}", $"{_model.CurrentProgress:#,###,##0}") - .Replace("{total}", $"{_model.TotalProgress:#,###,##0}"); - - _model.Status = status; - }); - } - } - - foreach (var folderImage in folderImages) - { - candidateImages.Add(folderImage.Value.Id); - } - } - else - { - if (options.ShowUnavailableRootFolders) - { - foreach (var folderImage in folderImages) - { - candidateImages.Add(folderImage.Value.Id); + if (imagePath.Unavailable) + { + restoredImages.Add(imagePath.Id); + } + folderImages.Remove(file); + } current++; if (current % 113 == 0) { + Dispatcher.Invoke(() => { _model.CurrentProgress = current; @@ -140,87 +112,125 @@ await Task.Run(() => }); } } + + foreach (var folderImage in folderImages) + { + candidateImages.Add(folderImage.Value.Id); + } } + else + { + if (options.ShowUnavailableRootFolders) + { + foreach (var folderImage in folderImages) + { + candidateImages.Add(folderImage.Value.Id); - } - } + current++; - Dispatcher.Invoke(() => - { - _model.CurrentProgress = total; - _model.TotalProgress = total; + if (current % 113 == 0) + { + Dispatcher.Invoke(() => + { + _model.CurrentProgress = current; - var unavailableFiles = GetLocalizedText("UnavailableFiles"); + var status = scanning + .Replace("{current}", $"{_model.CurrentProgress:#,###,##0}") + .Replace("{total}", $"{_model.TotalProgress:#,###,##0}"); - if (restoredImages.Any()) - { - _dataStore.SetUnavailable(restoredImages, false); + _model.Status = status; + }); + } + } + } + + } } - if (options.JustUpdate) + Dispatcher.Invoke(() => { - //var currentUnavailableImages = _dataStore.GetUnavailable(true); - //candidateImages = candidateImages.Except(currentUnavailableImages.Select(i => i.Id)).ToList(); + _model.CurrentProgress = total; + _model.TotalProgress = total; - _dataStore.SetUnavailable(candidateImages, true); - - var updated = GetLocalizedText("UnavailableFiles.Results.Updated"); - updated = updated.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + var unavailableFiles = GetLocalizedText("UnavailableFiles"); if (restoredImages.Any()) { - var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); - updated += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + _dataStore.SetUnavailable(restoredImages, false); } - _messagePopupManager.Show(updated, unavailableFiles, PopupButtons.OK); - } - else if (options.MarkForDeletion) - { - //var currentUnavailableImages = _dataStore.GetUnavailable(true); - //candidateImages = candidateImages.Except(currentUnavailableImages.Select(i => i.Id)).ToList(); + if (options.JustUpdate) + { + //var currentUnavailableImages = _dataStore.GetUnavailable(true); + //candidateImages = candidateImages.Except(currentUnavailableImages.Select(i => i.Id)).ToList(); - _dataStore.SetUnavailable(candidateImages, true); - _dataStore.SetDeleted(candidateImages, true); + _dataStore.SetUnavailable(candidateImages, true); - var marked = GetLocalizedText("UnavailableFiles.Results.MarkedForDeletion"); - marked = marked.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + var updated = GetLocalizedText("UnavailableFiles.Results.Updated"); + updated = updated.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); - if (restoredImages.Any()) - { - var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); - marked += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + if (restoredImages.Any()) + { + var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); + updated += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + } + + _messagePopupManager.Show(updated, unavailableFiles, PopupButtons.OK); } + else if (options.MarkForDeletion) + { + //var currentUnavailableImages = _dataStore.GetUnavailable(true); + //candidateImages = candidateImages.Except(currentUnavailableImages.Select(i => i.Id)).ToList(); - _messagePopupManager.Show(marked, unavailableFiles, PopupButtons.OK); - } - else if (options.RemoveImmediately) - { - _dataStore.RemoveImages(candidateImages); + _dataStore.SetUnavailable(candidateImages, true); + _dataStore.SetDeleted(candidateImages, true); - var removed = GetLocalizedText("UnavailableFiles.Results.Removed"); - removed = removed.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + var marked = GetLocalizedText("UnavailableFiles.Results.MarkedForDeletion"); + marked = marked.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); - if (restoredImages.Any()) - { - var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); - removed += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + if (restoredImages.Any()) + { + var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); + marked += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + } + + _messagePopupManager.Show(marked, unavailableFiles, PopupButtons.OK); } + else if (options.RemoveImmediately) + { + _dataStore.RemoveImages(candidateImages); + var removed = GetLocalizedText("UnavailableFiles.Results.Removed"); + removed = removed.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + + if (restoredImages.Any()) + { + var restored = GetLocalizedText("UnavailableFiles.Results.Restored"); + removed += " " + restored.Replace("{count}", $"{candidateImages.Count:#,###,##0}"); + } - _messagePopupManager.Show(removed, unavailableFiles, PopupButtons.OK); - } + _messagePopupManager.Show(removed, unavailableFiles, PopupButtons.OK); + } - var completed = GetLocalizedText("Actions.Scanning.Completed"); - _model.IsBusy = true; - _model.Status = completed; - _model.CurrentProgress = 0; - _model.TotalProgress = Int32.MaxValue; - }); + var completed = GetLocalizedText("Actions.Scanning.Completed"); + + _model.Status = completed; + _model.CurrentProgress = 0; + _model.TotalProgress = Int32.MaxValue; + }); + } } + finally + { + Dispatcher.Invoke(() => + { + _model.IsBusy = false; + }); + } + }); @@ -677,7 +687,7 @@ private async Task ScanInternal(IScanOptions settings, bool updateImages, { var folder = _dataStore.GetFolder(path); - if (folder.Unavailable) + if (folder is { Unavailable: true }) { foldersRestored = true; diff --git a/Diffusion.Toolkit/MainWindow.xaml.cs b/Diffusion.Toolkit/MainWindow.xaml.cs index b5e5a17..efb02f7 100644 --- a/Diffusion.Toolkit/MainWindow.xaml.cs +++ b/Diffusion.Toolkit/MainWindow.xaml.cs @@ -394,6 +394,8 @@ private async void OnLoaded(object sender, RoutedEventArgs e) { var dataStore = new DataStore(_dbPath); + var isFirstTime = false; + if (!_configuration.Exists()) { Logger.Log($"Opening Settings for first time"); @@ -418,8 +420,7 @@ private async void OnLoaded(object sender, RoutedEventArgs e) ThumbnailCache.CreateInstance(_settings.PageSize * 5, _settings.PageSize * 2); - await TryScanFolders(); - + isFirstTime = true; } else { @@ -536,7 +537,7 @@ await dataStore.Create(() => }, () => { - handle?.Close(); + handle?.CloseAsync(); }); _dataStoreOptions = new DataStoreOptions(dataStore); @@ -763,6 +764,11 @@ await dataStore.Create(() => if (_settings.ImagePaths.Any()) { _search.SearchImages(null); + + if (isFirstTime) + { + await TryScanFolders(); + } } Logger.Log($"Init completed");