2020-04-17 21:45:50 +01:00
|
|
|
|
// /***************************************************************************
|
|
|
|
|
|
// Aaru Data Preservation Suite
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// Filename : SplashWindowViewModel.cs
|
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
|
//
|
|
|
|
|
|
// Component : GUI view models.
|
|
|
|
|
|
//
|
|
|
|
|
|
// --[ Description ] ----------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// View model and code for the splash window.
|
|
|
|
|
|
//
|
|
|
|
|
|
// --[ License ] --------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
// it under the terms of the GNU General public License as
|
|
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
// GNU General public License for more details.
|
|
|
|
|
|
//
|
|
|
|
|
|
// You should have received a copy of the GNU General public License
|
|
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2022-12-03 16:07:10 +00:00
|
|
|
|
// Copyright © 2011-2023 Natalia Portillo
|
2020-04-17 21:45:50 +01:00
|
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2022-11-15 01:35:06 +00:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-04-09 04:18:29 +01:00
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using Aaru.Console;
|
|
|
|
|
|
using Aaru.Core;
|
|
|
|
|
|
using Aaru.Database;
|
2020-04-16 20:40:25 +01:00
|
|
|
|
using Aaru.Gui.ViewModels.Dialogs;
|
|
|
|
|
|
using Aaru.Gui.Views.Dialogs;
|
|
|
|
|
|
using Aaru.Gui.Views.Windows;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
using Aaru.Localization;
|
2020-04-09 04:18:29 +01:00
|
|
|
|
using Aaru.Settings;
|
|
|
|
|
|
using Avalonia.Threading;
|
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2020-04-09 03:28:08 +01:00
|
|
|
|
using ReactiveUI;
|
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
namespace Aaru.Gui.ViewModels.Windows;
|
|
|
|
|
|
|
2023-10-04 08:29:56 +01:00
|
|
|
|
public sealed class SplashWindowViewModel(SplashWindow view) : ViewModelBase
|
2020-04-09 03:28:08 +01:00
|
|
|
|
{
|
2023-10-04 08:29:56 +01:00
|
|
|
|
double _currentProgress;
|
|
|
|
|
|
double _maxProgress;
|
|
|
|
|
|
string _message;
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
public string Message
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _message;
|
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _message, value);
|
|
|
|
|
|
}
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
public double MaxProgress
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _maxProgress;
|
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _maxProgress, value);
|
|
|
|
|
|
}
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
public double CurrentProgress
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _currentProgress;
|
|
|
|
|
|
set => this.RaiseAndSetIfChanged(ref _currentProgress, value);
|
|
|
|
|
|
}
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
internal void OnOpened()
|
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Welcome_to_Aaru;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
MaxProgress = 9;
|
|
|
|
|
|
CurrentProgress = 0;
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(InitializeConsole);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InitializeConsole()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Initializing_console;
|
2020-04-09 03:28:08 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 03:28:08 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ConsoleHandler.Init();
|
2022-11-19 21:10:41 +00:00
|
|
|
|
AaruConsole.WriteLine(UI.Aaru_started);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(LoadSettings);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
void LoadSettings()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Loading_settings;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Loading_settings);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// TODO: Detect there are no settings yet
|
2022-11-15 15:58:43 +00:00
|
|
|
|
Settings.Settings.LoadSettings();
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(MigrateLocalDatabase);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
void MigrateLocalDatabase()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Migrating_local_database;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Migrating_local_database);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
AaruContext ctx = null;
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2022-11-15 15:58:43 +00:00
|
|
|
|
ctx = AaruContext.Create(Settings.Settings.LocalDbPath, false);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ctx.Database.Migrate();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch(NotSupportedException)
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2020-07-10 17:38:52 +01:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ctx?.Database.CloseConnection();
|
|
|
|
|
|
ctx?.Dispose();
|
2020-07-10 17:38:52 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
catch(Exception)
|
2020-07-10 17:38:52 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// Should not ever arrive here, but if it does, keep trying to replace it anyway
|
|
|
|
|
|
}
|
2020-07-10 17:38:52 +01:00
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
File.Delete(Settings.Settings.LocalDbPath);
|
|
|
|
|
|
ctx = AaruContext.Create(Settings.Settings.LocalDbPath);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ctx.Database.EnsureCreated();
|
2020-07-10 17:38:52 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ctx.Database.
|
2023-10-04 17:34:40 +01:00
|
|
|
|
ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\"MigrationId\" TEXT PRIMARY KEY, \"ProductVersion\" TEXT)");
|
2020-04-18 19:16:31 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
foreach(string migration in ctx.Database.GetPendingMigrations())
|
2023-10-03 23:27:57 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
ctx.Database.
|
2022-11-15 15:58:43 +00:00
|
|
|
|
ExecuteSqlRaw($"INSERT INTO \"__EFMigrationsHistory\" (MigrationId, ProductVersion) VALUES ('{
|
|
|
|
|
|
migration}', '0.0.0')");
|
2023-10-03 23:27:57 +01:00
|
|
|
|
}
|
2020-04-18 19:16:31 +01:00
|
|
|
|
|
2020-04-09 04:18:29 +01:00
|
|
|
|
ctx.SaveChanges();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// Remove duplicates
|
2023-10-04 17:34:40 +01:00
|
|
|
|
foreach(var duplicate in ctx.SeenDevices.AsEnumerable().
|
|
|
|
|
|
GroupBy(a => new
|
|
|
|
|
|
{
|
|
|
|
|
|
a.Manufacturer,
|
|
|
|
|
|
a.Model,
|
|
|
|
|
|
a.Revision,
|
|
|
|
|
|
a.Bus
|
|
|
|
|
|
}).
|
|
|
|
|
|
Where(a => a.Count() > 1).
|
|
|
|
|
|
Distinct().
|
|
|
|
|
|
Select(a => a.Key))
|
2023-10-03 23:27:57 +01:00
|
|
|
|
{
|
2022-03-26 16:52:00 +00:00
|
|
|
|
ctx.RemoveRange(ctx.SeenDevices.
|
2023-10-04 17:34:40 +01:00
|
|
|
|
Where(d => d.Manufacturer == duplicate.Manufacturer &&
|
|
|
|
|
|
d.Model == duplicate.Model &&
|
|
|
|
|
|
d.Revision == duplicate.Revision &&
|
|
|
|
|
|
d.Bus == duplicate.Bus).
|
|
|
|
|
|
Skip(1));
|
2023-10-03 23:27:57 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
// Remove nulls
|
2023-10-04 17:34:40 +01:00
|
|
|
|
ctx.RemoveRange(ctx.SeenDevices.Where(d => d.Manufacturer == null &&
|
|
|
|
|
|
d.Model == null &&
|
2022-11-15 15:58:43 +00:00
|
|
|
|
d.Revision == null));
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
ctx.SaveChanges();
|
|
|
|
|
|
|
|
|
|
|
|
Dispatcher.UIThread.Post(UpdateMainDatabase);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UpdateMainDatabase()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Updating_main_database;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Updating_main_database);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-11-15 15:58:43 +00:00
|
|
|
|
bool mainDbUpdate = !File.Exists(Settings.Settings.MainDbPath);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-07 07:36:44 +00:00
|
|
|
|
// TODO: Update database
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
var mainContext = AaruContext.Create(Settings.Settings.MainDbPath, false);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
if(mainContext.Database.GetPendingMigrations().Any())
|
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
|
AaruConsole.WriteLine(UI.New_database_version_updating);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
try
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-11-15 15:58:43 +00:00
|
|
|
|
File.Delete(Settings.Settings.MainDbPath);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
catch(Exception)
|
|
|
|
|
|
{
|
2022-11-19 21:10:41 +00:00
|
|
|
|
AaruConsole.ErrorWriteLine(UI.Exception_trying_to_remove_old_database_version);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-11-19 21:10:41 +00:00
|
|
|
|
AaruConsole.ErrorWriteLine(UI.Please_manually_remove_file_at_0, Settings.Settings.MainDbPath);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
// TODO: Update database
|
2020-04-10 22:33:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(CheckGdprCompliance);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-15 01:35:06 +00:00
|
|
|
|
[SuppressMessage("ReSharper", "AsyncVoidMethod")]
|
2022-03-06 13:29:38 +00:00
|
|
|
|
async void CheckGdprCompliance()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Checking_GDPR_compliance;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Checking_GDPR_compliance);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
if(Settings.Settings.Current.GdprCompliance < DicSettings.GDPR_LEVEL)
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
var settingsDialog = new SettingsDialog();
|
|
|
|
|
|
var settingsDialogViewModel = new SettingsViewModel(settingsDialog, true);
|
|
|
|
|
|
settingsDialog.DataContext = settingsDialogViewModel;
|
2023-10-04 08:29:56 +01:00
|
|
|
|
await settingsDialog.ShowDialog(view);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
LoadStatistics();
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
void LoadStatistics()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Loading_statistics;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Loading_statistics);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Statistics.LoadStats();
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(RegisterEncodings);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
void RegisterEncodings()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Registering_encodings;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Registering_encodings);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(SaveStatistics);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
void SaveStatistics()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Saving_statistics;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Saving_statistics);
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Task.Run(() =>
|
2020-04-09 04:18:29 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Statistics.SaveStats();
|
2020-04-09 04:18:29 +01:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
Dispatcher.UIThread.Post(LoadMainWindow);
|
|
|
|
|
|
});
|
2020-04-09 03:28:08 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
void LoadMainWindow()
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentProgress++;
|
2022-11-19 21:10:41 +00:00
|
|
|
|
Message = UI.Loading_main_window;
|
|
|
|
|
|
AaruConsole.WriteLine(UI.Loading_main_window);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
WorkFinished?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal event EventHandler WorkFinished;
|
2020-04-09 03:28:08 +01:00
|
|
|
|
}
|