Move all rom import code to Core.

This commit is contained in:
2020-08-23 22:17:49 +01:00
parent 8f289e3939
commit c0c8f8f5e1
4 changed files with 237 additions and 115 deletions

View File

@@ -0,0 +1,34 @@
/******************************************************************************
// RomRepoMgr - ROM repository manager
// ----------------------------------------------------------------------------
//
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// --[ 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/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2020 Natalia Portillo
*******************************************************************************/
using RomRepoMgr.Core.Models;
namespace RomRepoMgr.Core.EventArgs
{
public sealed class ImportedRomItemEventArgs : System.EventArgs
{
public ImportRomItem Item { get; set; }
}
}

View File

@@ -0,0 +1,33 @@
/******************************************************************************
// RomRepoMgr - ROM repository manager
// ----------------------------------------------------------------------------
//
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// --[ 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/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2020 Natalia Portillo
*******************************************************************************/
namespace RomRepoMgr.Core.Models
{
public sealed class ImportRomItem
{
public string Filename { get; set; }
public string Status { get; set; }
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Models;
using RomRepoMgr.Database;
using RomRepoMgr.Database.Models;
using SharpCompress.Compressors;
@@ -18,21 +19,114 @@ namespace RomRepoMgr.Core.Workers
readonly Dictionary<string, DbFile> _pendingFiles;
string _lastMessage;
long _position;
long _totalFiles;
public FileImporter(bool onlyKnown, bool deleteAfterImport)
{
_pendingFiles = new Dictionary<string, DbFile>();
_onlyKnown = onlyKnown;
_deleteAfterImport = deleteAfterImport;
_position = 0;
}
public string LastMessage { get; private set; }
public event EventHandler SetIndeterminateProgress2;
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds2;
public event EventHandler<ProgressEventArgs> SetProgress2;
public event EventHandler<MessageEventArgs> SetMessage2;
public event EventHandler SetIndeterminateProgress;
public event EventHandler<ProgressBoundsEventArgs> SetProgressBounds;
public event EventHandler<ProgressEventArgs> SetProgress;
public event EventHandler<MessageEventArgs> SetMessage;
public event EventHandler Finished;
public event EventHandler<ImportedRomItemEventArgs> ImportedRom;
public bool ImportRom(string path)
public void ProcessPath(string path, bool rootPath, bool removePathOnFinish)
{
try
{
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
SetMessage?.Invoke(this, new MessageEventArgs
{
Message = "Enumerating files..."
});
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
_totalFiles += files.LongLength;
SetProgressBounds?.Invoke(this, new ProgressBoundsEventArgs
{
Minimum = 0,
Maximum = _totalFiles
});
foreach(string file in files)
{
SetProgress?.Invoke(this, new ProgressEventArgs
{
Value = _position
});
SetMessage?.Invoke(this, new MessageEventArgs
{
Message = string.Format("Importing {0}...", Path.GetFileName(file))
});
bool ret = ImportRom(file);
if(ret)
{
ImportedRom?.Invoke(this, new ImportedRomItemEventArgs
{
Item = new ImportRomItem
{
Filename = Path.GetFileName(file),
Status = "OK"
}
});
}
else
{
ImportedRom?.Invoke(this, new ImportedRomItemEventArgs
{
Item = new ImportRomItem
{
Filename = Path.GetFileName(file),
Status = string.Format("Error: {0}", _lastMessage)
}
});
}
_position++;
}
if(removePathOnFinish)
{
SetMessage?.Invoke(this, new MessageEventArgs
{
Message = "Removing temporary path..."
});
Directory.Delete(path, true);
}
if(!rootPath)
return;
SaveChanges();
Finished?.Invoke(this, System.EventArgs.Empty);
}
catch(Exception)
{
// TODO: Send error back
if(rootPath)
Finished?.Invoke(this, System.EventArgs.Empty);
}
}
bool ImportRom(string path)
{
try
{
@@ -40,7 +134,7 @@ namespace RomRepoMgr.Core.Workers
byte[] dataBuffer;
SetMessage?.Invoke(this, new MessageEventArgs
SetMessage2?.Invoke(this, new MessageEventArgs
{
Message = "Hashing file..."
});
@@ -49,7 +143,7 @@ namespace RomRepoMgr.Core.Workers
if(inFs.Length > BUFFER_SIZE)
{
SetProgressBounds?.Invoke(this, new ProgressBoundsEventArgs
SetProgressBounds2?.Invoke(this, new ProgressBoundsEventArgs
{
Minimum = 0,
Maximum = inFs.Length
@@ -60,7 +154,7 @@ namespace RomRepoMgr.Core.Workers
for(offset = 0; offset < inFs.Length - remainder; offset += (int)BUFFER_SIZE)
{
SetProgress?.Invoke(this, new ProgressEventArgs
SetProgress2?.Invoke(this, new ProgressEventArgs
{
Value = offset
});
@@ -70,7 +164,7 @@ namespace RomRepoMgr.Core.Workers
checksumWorker.Update(dataBuffer);
}
SetProgress?.Invoke(this, new ProgressEventArgs
SetProgress2?.Invoke(this, new ProgressEventArgs
{
Value = offset
});
@@ -81,7 +175,7 @@ namespace RomRepoMgr.Core.Workers
}
else
{
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
dataBuffer = new byte[inFs.Length];
inFs.Read(dataBuffer, 0, (int)inFs.Length);
checksumWorker.Update(dataBuffer);
@@ -112,7 +206,7 @@ namespace RomRepoMgr.Core.Workers
{
if(_onlyKnown)
{
LastMessage = "Unknown file.";
_lastMessage = "Unknown file.";
return false;
}
@@ -232,13 +326,13 @@ namespace RomRepoMgr.Core.Workers
Stream zStream = null;
zStream = new LZipStream(outFs, CompressionMode.Compress);
SetProgressBounds?.Invoke(this, new ProgressBoundsEventArgs
SetProgressBounds2?.Invoke(this, new ProgressBoundsEventArgs
{
Minimum = 0,
Maximum = inFs.Length
});
SetMessage?.Invoke(this, new MessageEventArgs
SetMessage2?.Invoke(this, new MessageEventArgs
{
Message = "Compressing file..."
});
@@ -247,7 +341,7 @@ namespace RomRepoMgr.Core.Workers
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
{
SetProgress?.Invoke(this, new ProgressEventArgs
SetProgress2?.Invoke(this, new ProgressEventArgs
{
Value = inFs.Position
});
@@ -258,7 +352,7 @@ namespace RomRepoMgr.Core.Workers
buffer = new byte[inFs.Length - inFs.Position];
SetProgress?.Invoke(this, new ProgressEventArgs
SetProgress2?.Invoke(this, new ProgressEventArgs
{
Value = inFs.Position
});
@@ -266,9 +360,9 @@ namespace RomRepoMgr.Core.Workers
inFs.Read(buffer, 0, buffer.Length);
zStream.Write(buffer, 0, buffer.Length);
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
SetMessage?.Invoke(this, new MessageEventArgs
SetMessage2?.Invoke(this, new MessageEventArgs
{
Message = "Finishing..."
});
@@ -290,17 +384,17 @@ namespace RomRepoMgr.Core.Workers
}
catch(Exception e)
{
LastMessage = "Unhandled exception when importing file.";
_lastMessage = "Unhandled exception when importing file.";
return false;
}
}
public void SaveChanges()
void SaveChanges()
{
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
SetMessage?.Invoke(this, new MessageEventArgs
SetMessage2?.Invoke(this, new MessageEventArgs
{
Message = "Saving changes to database..."
});

View File

@@ -25,14 +25,13 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reactive;
using System.Threading.Tasks;
using Avalonia.Threading;
using JetBrains.Annotations;
using ReactiveUI;
using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Models;
using RomRepoMgr.Core.Workers;
using RomRepoMgr.Views;
@@ -69,7 +68,7 @@ namespace RomRepoMgr.ViewModels
_removeFilesChecked = false;
_knownOnlyChecked = true;
_recurseArchivesChecked = Settings.Settings.UnArUsable;
ImportResults = new ObservableCollection<ImportRomFolderItem>();
ImportResults = new ObservableCollection<ImportRomItem>();
CloseCommand = ReactiveCommand.Create(ExecuteCloseCommand);
StartCommand = ReactiveCommand.Create(ExecuteStartCommand);
IsReady = true;
@@ -203,7 +202,7 @@ namespace RomRepoMgr.ViewModels
[NotNull]
public string Title => "Import ROM files from folder...";
public ObservableCollection<ImportRomFolderItem> ImportResults { get; }
public ObservableCollection<ImportRomItem> ImportResults { get; }
public string ResultFilenameLabel => "Filename";
public string ResultStatusLabel => "Status";
public string CloseLabel => "Close";
@@ -230,104 +229,66 @@ namespace RomRepoMgr.ViewModels
{
IsReady = false;
ProgressVisible = true;
ProgressIsIndeterminate = true;
StatusMessage = "Enumerating files...";
IsImporting = true;
CanStart = false;
CanClose = false;
Task.Run(() =>
{
var watch = new Stopwatch();
string[] files = Directory.GetFiles(FolderPath, "*", SearchOption.AllDirectories);
Dispatcher.UIThread.Post(() =>
{
ProgressIsIndeterminate = false;
ProgressMinimum = 0;
ProgressMaximum = files.LongLength;
ProgressValue = 0;
Progress2Visible = true;
});
var worker = new FileImporter(KnownOnlyChecked, RemoveFilesChecked);
worker.SetIndeterminateProgress += OnWorkerOnSetIndeterminateProgress;
worker.SetMessage += OnWorkerOnSetMessage;
worker.SetProgress += OnWorkerOnSetProgress;
worker.SetProgressBounds += OnWorkerOnSetProgressBounds;
worker.SetIndeterminateProgress2 += OnWorkerOnSetIndeterminateProgress2;
worker.SetMessage2 += OnWorkerOnSetMessage2;
worker.SetProgress2 += OnWorkerOnSetProgress2;
worker.SetProgressBounds2 += OnWorkerOnSetProgressBounds2;
worker.Finished += OnWorkerOnFinished;
worker.ImportedRom += OnWorkerOnImportedRom;
long position = 0;
watch.Start();
foreach(string file in files)
{
Dispatcher.UIThread.Post(() =>
{
StatusMessage = string.Format("Importing {0}...", Path.GetFileName(file));
ProgressValue = position;
});
bool ret = worker.ImportRom(file);
Dispatcher.UIThread.Post(() =>
{
if(ret)
{
ImportResults.Add(new ImportRomFolderItem
{
Filename = Path.GetFileName(file),
Status = "OK"
});
}
else
{
ImportResults.Add(new ImportRomFolderItem
{
Filename = Path.GetFileName(file),
Status = string.Format("Error: {0}", worker.LastMessage)
});
}
});
position++;
Task.Run(() => worker.ProcessPath(FolderPath, true, false));
}
worker.SaveChanges();
void OnWorkerOnImportedRom(object? sender, ImportedRomItemEventArgs args) =>
Dispatcher.UIThread.Post(() => ImportResults.Add(args.Item));
watch.Stop();
Dispatcher.UIThread.Post(() =>
void OnWorkerOnFinished(object? sender, EventArgs args) => Dispatcher.UIThread.Post(() =>
{
ProgressVisible = false;
StatusMessage = "Finished!";
CanClose = true;
Progress2Visible = false;
Console.WriteLine($"Took {watch.Elapsed.TotalSeconds} seconds");
});
});
}
void OnWorkerOnSetProgressBounds(object sender, ProgressBoundsEventArgs args) => Dispatcher.UIThread.Post(() =>
{
ProgressIsIndeterminate = false;
ProgressMaximum = args.Maximum;
ProgressMinimum = args.Minimum;
});
void OnWorkerOnSetProgress(object sender, ProgressEventArgs args) =>
Dispatcher.UIThread.Post(() => ProgressValue = args.Value);
void OnWorkerOnSetMessage(object sender, MessageEventArgs args) =>
Dispatcher.UIThread.Post(() => StatusMessage = args.Message);
void OnWorkerOnSetIndeterminateProgress(object sender, EventArgs args) =>
Dispatcher.UIThread.Post(() => ProgressIsIndeterminate = true);
void OnWorkerOnSetProgressBounds2(object sender, ProgressBoundsEventArgs args) => Dispatcher.UIThread.Post(() =>
{
Progress2IsIndeterminate = false;
Progress2Maximum = args.Maximum;
Progress2Minimum = args.Minimum;
});
void OnWorkerOnSetProgress(object sender, ProgressEventArgs args) =>
void OnWorkerOnSetProgress2(object sender, ProgressEventArgs args) =>
Dispatcher.UIThread.Post(() => Progress2Value = args.Value);
void OnWorkerOnSetMessage(object sender, MessageEventArgs args) =>
void OnWorkerOnSetMessage2(object sender, MessageEventArgs args) =>
Dispatcher.UIThread.Post(() => Status2Message = args.Message);
void OnWorkerOnSetIndeterminateProgress(object sender, EventArgs args) =>
void OnWorkerOnSetIndeterminateProgress2(object sender, EventArgs args) =>
Dispatcher.UIThread.Post(() => Progress2IsIndeterminate = true);
}
public sealed class ImportRomFolderItem
{
public string Filename { get; set; }
public string Status { get; set; }
}
}