Files
Aaru/Aaru.Gui/ViewModels/Windows/SplashWindowViewModel.cs

314 lines
9.6 KiB
C#
Raw Normal View History

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/>.
//
// ----------------------------------------------------------------------------
2024-05-01 04:17:32 +01:00
// Copyright © 2011-2024 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;
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;
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()
{
Message = UI.Welcome_to_Aaru;
MaxProgress = 10;
2022-03-06 13:29:38 +00:00
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++;
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();
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++;
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
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++;
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
{
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
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
2024-05-01 04:05:22 +01:00
ctx.Database
.ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS \"__EFMigrationsHistory\" (\"MigrationId\" TEXT PRIMARY KEY, \"ProductVersion\" TEXT)");
2022-03-06 13:29:38 +00:00
foreach(string migration in ctx.Database.GetPendingMigrations())
2023-10-03 23:27:57 +01:00
{
2024-05-01 23:52:03 +01:00
#pragma warning disable EF1002
ctx.Database
2024-05-01 04:05:22 +01:00
.ExecuteSqlRaw($"INSERT INTO \"__EFMigrationsHistory\" (MigrationId, ProductVersion) VALUES ('{
migration}', '0.0.0')");
2024-05-01 23:52:03 +01:00
#pragma warning restore EF1002
2023-10-03 23:27:57 +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
2024-05-01 04:05:22 +01:00
foreach(var duplicate in ctx.SeenDevices.AsEnumerable()
.GroupBy(a => new
{
a.Manufacturer,
a.Model,
a.Revision,
a.Bus
2024-05-01 04:05:22 +01:00
})
.Where(a => a.Count() > 1)
.Distinct()
.Select(a => a.Key))
2023-10-03 23:27:57 +01:00
{
2024-05-01 04:05:22 +01:00
ctx.RemoveRange(ctx.SeenDevices
.Where(d => d.Manufacturer == duplicate.Manufacturer &&
d.Model == duplicate.Model &&
d.Revision == duplicate.Revision &&
2024-05-01 04:05:22 +01:00
d.Bus == duplicate.Bus)
.Skip(1));
2023-10-03 23:27:57 +01:00
}
2022-03-06 13:29:38 +00:00
// Remove nulls
ctx.RemoveRange(ctx.SeenDevices.Where(d => d.Manufacturer == null &&
d.Model == null &&
d.Revision == null));
2022-03-06 13:29:38 +00:00
ctx.SaveChanges();
Dispatcher.UIThread.Post(UpdateMainDatabase);
});
}
void UpdateMainDatabase()
{
CurrentProgress++;
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
{
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
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())
{
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
{
File.Delete(Settings.Settings.MainDbPath);
2020-04-09 04:18:29 +01:00
}
2022-03-06 13:29:38 +00:00
catch(Exception)
{
AaruConsole.ErrorWriteLine(UI.Exception_trying_to_remove_old_database_version);
2020-04-09 04:18:29 +01: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
}
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++;
Message = UI.Checking_GDPR_compliance;
AaruConsole.WriteLine(UI.Checking_GDPR_compliance);
2020-04-09 04:18:29 +01: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++;
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++;
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
Dispatcher.UIThread.Post(RegisterPlugins);
});
}
// There are too many places that depend on this being inited to be sure all are covered, so init it here.
void RegisterPlugins()
{
CurrentProgress++;
Message = UI.Registering_plugins;
AaruConsole.WriteLine(UI.Registering_plugins);
Task.Run(() =>
{
PluginBase.Init();
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++;
Message = UI.Saving_statistics;
AaruConsole.WriteLine(UI.Saving_statistics);
2020-04-09 04:18:29 +01:00
Task.Run(async () =>
2020-04-09 04:18:29 +01:00
{
await 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++;
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
}