10 Commits

9 changed files with 313 additions and 189 deletions

View File

@@ -31,10 +31,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Philips.CodeAnalysis.MaintainabilityAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -33,7 +33,6 @@
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0"/>
<PackageVersion Include="Text.Analyzers" Version="4.14.0"/>
<PackageVersion Include="winfsp.net" Version="2.1.25156"/>
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="3.116.1" Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))'"/>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageVersion Include="SabreTools.Hashing" Version="1.2.3"/>

View File

@@ -0,0 +1,96 @@
using System;
using System.Text.Json.Serialization;
namespace RomRepoMgr.Core.Models;
[JsonSerializable(typeof(lsar))]
public partial class lsarJsonContext : JsonSerializerContext {}
public class lsar
{
public int lsarFormatVersion { get; set; }
public string lsarEncoding { get; set; }
public int lsarConfidence { get; set; }
public string lsarFormatName { get; set; }
public lsarProperties lsarProperties { get; set; }
public lsarContents[] lsarContents { get; set; }
public int lsarError { get; set; }
public string lsarInnerFormatName { get; set; }
public lsarProperties lsarInnerProperties { get; set; }
}
public class lsarProperties
{
public string[] XADVolumes { get; set; }
public string XADComment { get; set; }
public string XADArchiveName { get; set; }
public bool XADIsSolid { get; set; }
public DateTime XADCreationDate { get; set; }
public DateTime XADLastModificationDate { get; set; }
public string ARJOriginalArchiveName { get; set; }
}
public class lsarContents
{
public long XADCompressedSize { get; set; }
public long XADDataLength { get; set; }
public short ZipFlags { get; set; }
public short ZipFileAttributes { get; set; }
public long XADDataOffset { get; set; }
public long XADIndex { get; set; }
public string ZipOSName { get; set; }
public short XADPosixPermissions { get; set; }
public uint ZipCRC32 { get; set; }
public int ZipLocalDate { get; set; }
public short ZipOS { get; set; }
public short ZipCompressionMethod { get; set; }
public string XADCompressionName { get; set; }
public short ZipExtractVersion { get; set; }
public string XADFileName { get; set; }
public DateTime XADLastModificationDate { get; set; }
public short XADDOSFileAttributes { get; set; }
public long XADFileSize { get; set; }
public bool TARIsSparseFile { get; set; }
public long XADFirstSolidEntry { get; set; }
public string XADSolidObject { get; set; }
public long XADFirstSolidIndex { get; set; }
public short XADPosixUser { get; set; }
public short XADPosixGroup { get; set; }
public bool XADIsSolid { get; set; }
public DateTime XADLastAccessDate { get; set; }
public int ARJCRC32 { get; set; }
public int ARJMethod { get; set; }
public int ARJMinimumVersion { get; set; }
public int ARJFileType { get; set; }
public int ARJFlags { get; set; }
public string ARJOSName { get; set; }
public int ARJOS { get; set; }
public int ARJVersion { get; set; }
public int GzipExtraFlags { get; set; }
public string GzipFilename { get; set; }
public int GzipOS { get; set; }
public short LHAHeaderLevel { get; set; }
public string LHAExtFileNameData { get; set; }
public short LHACRC16 { get; set; }
public string LHAOSName { get; set; }
public int LHAOS { get; set; }
public string RAR5OSName { get; set; }
public int RAR5Attributes { get; set; }
public long RAR5DataLength { get; set; }
public long RAR5CompressionMethod { get; set; }
public long RAR5DictionarySize { get; set; }
public uint RAR5CRC32 { get; set; }
public int RAR5Flags { get; set; }
public int RAR5DataOffset { get; set; }
public int RAR5CompressionVersion { get; set; }
public int RAR5CompressionInformation { get; set; }
public int RAR5OS { get; set; }
public RAR5InputParts[] RAR5InputParts { get; set; }
}
public class RAR5InputParts
{
public uint CRC32 { get; set; }
public long InputLength { get; set; }
public long Offset { get; set; }
}

View File

@@ -1,9 +1,12 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using RomRepoMgr.Core.Aaru;
@@ -14,24 +17,28 @@ using RomRepoMgr.Database;
using RomRepoMgr.Database.Models;
using SabreTools.FileTypes.Aaru;
using SabreTools.FileTypes.CHD;
using SharpCompress.Compressors;
using SharpCompress.Compressors.LZMA;
using CompressionMode = SharpCompress.Compressors.CompressionMode;
namespace RomRepoMgr.Core.Workers;
public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
public sealed class FileImporter
(
Context _ctx,
ConcurrentBag<DbFile> _newFiles,
ConcurrentBag<DbDisk> _newDisks,
ConcurrentBag<DbMedia> _newMedias,
bool onlyKnown,
bool deleteAfterImport
)
{
const long BUFFER_SIZE = 131072;
static readonly Lock DbLock = new();
readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath);
readonly List<DbDisk> _newDisks = [];
readonly List<DbFile> _newFiles = [];
readonly List<DbMedia> _newMedias = [];
readonly Dictionary<string, DbDisk> _pendingDisksByMd5 = [];
readonly Dictionary<string, DbDisk> _pendingDisksBySha1 = [];
readonly Dictionary<string, DbFile> _pendingFiles = [];
readonly Dictionary<string, DbMedia> _pendingMediasByMd5 = [];
readonly Dictionary<string, DbMedia> _pendingMediasBySha1 = [];
const long BUFFER_SIZE = 131072;
static readonly Lock DbLock = new();
readonly Dictionary<string, DbDisk> _pendingDisksByMd5 = [];
readonly Dictionary<string, DbDisk> _pendingDisksBySha1 = [];
readonly Dictionary<string, DbFile> _pendingFiles = [];
readonly Dictionary<string, DbMedia> _pendingMediasByMd5 = [];
readonly Dictionary<string, DbMedia> _pendingMediasBySha1 = [];
readonly Dictionary<string, DbMedia> _pendingMediasBySha256 = [];
string _archiveFolder;
string _lastMessage;
@@ -83,57 +90,61 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
Maximum = Files.Count
});
List<string> files = [];
Archives = [];
ConcurrentBag<string> files = [];
ConcurrentBag<string> archives = [];
foreach(string file in Files)
{
try
{
SetProgress?.Invoke(this,
new ProgressEventArgs
{
Value = _position
});
Parallel.ForEach(Files,
file =>
{
try
{
SetProgress?.Invoke(this,
new ProgressEventArgs
{
Value = _position
});
SetMessage?.Invoke(this,
new MessageEventArgs
{
Message = "Checking archives. Found " +
Archives.Count +
" archives and " +
files.Count +
" files."
});
SetMessage?.Invoke(this,
new MessageEventArgs
{
Message = "Checking archives. Found " +
archives.Count +
" archives and " +
files.Count +
" files."
});
SetMessage2?.Invoke(this,
new MessageEventArgs
{
Message = string.Format("Checking if file {0} is an archive...",
Path.GetFileName(file))
});
SetMessage2?.Invoke(this,
new MessageEventArgs
{
Message =
$"Checking if file {Path.GetFileName(file)} is an archive..."
});
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
string archiveFormat = GetArchiveFormat(file, out _);
string archiveFormat = GetArchiveFormat(file, out _);
// If a floppy contains only the archive, unar will recognize it, on its skipping of SFXs.
if(archiveFormat != null && FAT.Identify(file)) archiveFormat = null;
// If a floppy contains only the archive, unar will recognize it, on its skipping of SFXs.
if(archiveFormat != null && FAT.Identify(file)) archiveFormat = null;
if(archiveFormat != null)
Archives.Add(file);
else
files.Add(file);
if(archiveFormat != null)
archives.Add(file);
else
files.Add(file);
_position++;
}
catch(Exception ex)
{
Console.WriteLine("Exception while checking file {0}: {1}", Path.GetFileName(file), ex.Message);
}
}
Interlocked.Increment(ref _position);
}
catch(Exception ex)
{
Console.WriteLine("Exception while checking file {0}: {1}",
Path.GetFileName(file),
ex.Message);
}
});
Files = files;
Files = files.Order().ToList();
Archives = archives.Order().ToList();
SetMessage?.Invoke(this,
new MessageEventArgs
@@ -304,7 +315,10 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
Message = Localization.ExtractingArchive
});
ExtractArchive(archive, _archiveFolder);
if(archiveFormat is "Zip")
ZipFile.ExtractToDirectory(archive, _archiveFolder);
else
ExtractArchive(archive, _archiveFolder);
Files = Directory.GetFiles(_archiveFolder, "*", SearchOption.AllDirectories).Order().ToList();
@@ -461,8 +475,8 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
Dictionary<ChecksumType, string> checksums = checksumWorker.End();
var uSize = (ulong)inFs.Length;
var fileInDb = true;
ulong uSize = (ulong)inFs.Length;
bool fileInDb = true;
bool knownFile = _pendingFiles.TryGetValue(checksums[ChecksumType.Sha512], out DbFile dbFile);
@@ -505,10 +519,10 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(!knownFile) _pendingFiles[checksums[ChecksumType.Sha512]] = dbFile;
var sha384Bytes = new byte[48];
byte[] sha384Bytes = new byte[48];
string sha384 = checksums[ChecksumType.Sha384];
for(var i = 0; i < 48; i++)
for(int i = 0; i < 48; i++)
{
if(sha384[i * 2] >= 0x30 && sha384[i * 2] <= 0x39)
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10);
@@ -696,9 +710,9 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(chd.MD5 != null)
{
var chdArray = new char[32];
char[] chdArray = new char[32];
for(var i = 0; i < 16; i++)
for(int i = 0; i < 16; i++)
{
int nibble1 = chd.MD5[i] >> 4;
int nibble2 = chd.MD5[i] & 0xF;
@@ -715,9 +729,9 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(chd.SHA1 != null)
{
var chdArray = new char[40];
char[] chdArray = new char[40];
for(var i = 0; i < 20; i++)
for(int i = 0; i < 20; i++)
{
int nibble1 = chd.SHA1[i] >> 4;
int nibble2 = chd.SHA1[i] & 0xF;
@@ -732,11 +746,11 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
sha1 = new string(chdArray);
}
var uSize = (ulong)inFs.Length;
var diskInDb = true;
ulong uSize = (ulong)inFs.Length;
bool diskInDb = true;
DbDisk dbDisk = null;
var knownDisk = false;
var knownDiskWasBigger = false;
bool knownDisk = false;
bool knownDiskWasBigger = false;
if(sha1 != null) knownDisk = _pendingDisksBySha1.TryGetValue(sha1, out dbDisk);
@@ -887,7 +901,7 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
Message = Localization.CopyingFile
});
var buffer = new byte[BUFFER_SIZE];
byte[] buffer = new byte[BUFFER_SIZE];
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
{
@@ -978,9 +992,9 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(aif.MD5 != null)
{
var chdArray = new char[32];
char[] chdArray = new char[32];
for(var i = 0; i < 16; i++)
for(int i = 0; i < 16; i++)
{
int nibble1 = aif.MD5[i] >> 4;
int nibble2 = aif.MD5[i] & 0xF;
@@ -997,9 +1011,9 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(aif.SHA1 != null)
{
var chdArray = new char[40];
char[] chdArray = new char[40];
for(var i = 0; i < 20; i++)
for(int i = 0; i < 20; i++)
{
int nibble1 = aif.SHA1[i] >> 4;
int nibble2 = aif.SHA1[i] & 0xF;
@@ -1016,9 +1030,9 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
if(aif.SHA256 != null)
{
var chdArray = new char[64];
char[] chdArray = new char[64];
for(var i = 0; i < 32; i++)
for(int i = 0; i < 32; i++)
{
int nibble1 = aif.SHA256[i] >> 4;
int nibble2 = aif.SHA256[i] & 0xF;
@@ -1033,11 +1047,11 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
sha256 = new string(chdArray);
}
var uSize = (ulong)inFs.Length;
var mediaInDb = true;
ulong uSize = (ulong)inFs.Length;
bool mediaInDb = true;
DbMedia dbMedia = null;
var knownMedia = false;
var knownMediaWasBigger = false;
bool knownMedia = false;
bool knownMediaWasBigger = false;
if(sha256 != null) knownMedia = _pendingMediasBySha256.TryGetValue(sha256, out dbMedia);
@@ -1229,7 +1243,7 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
Message = Localization.CopyingFile
});
var buffer = new byte[BUFFER_SIZE];
byte[] buffer = new byte[BUFFER_SIZE];
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
{
@@ -1288,13 +1302,13 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
public void SaveChanges()
{
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
SetMessage2?.Invoke(this,
new MessageEventArgs
{
Message = Localization.SavingChangesToDatabase
});
SetMessage?.Invoke(this,
new MessageEventArgs
{
Message = Localization.SavingChangesToDatabase
});
lock(DbLock)
{
@@ -1351,28 +1365,19 @@ public sealed class FileImporter(bool onlyKnown, bool deleteAfterImport)
lsarProcess.Start();
string lsarOutput = lsarProcess.StandardOutput.ReadToEnd();
lsarProcess.WaitForExit();
string format = null;
var jsReader = new JsonTextReader(new StringReader(lsarOutput));
while(jsReader.Read())
lsar lsar = JsonConvert.DeserializeObject<lsar>(lsarOutput);
if(lsar is null)
{
switch(jsReader.TokenType)
{
case JsonToken.PropertyName when jsReader.Value?.ToString() == "XADFileName":
counter++;
counter = 0;
break;
case JsonToken.PropertyName when jsReader.Value?.ToString() == "lsarFormatName":
jsReader.Read();
if(jsReader.TokenType == JsonToken.String && jsReader.Value != null)
format = jsReader.Value.ToString();
break;
}
return null;
}
return counter == 0 ? null : format;
counter = lsar.lsarContents.Length;
return lsar.lsarFormatName;
}
catch
{

View File

@@ -1,5 +1,4 @@
using System;
using System.Threading.Tasks;
using Avalonia.Media;
using ReactiveUI;
using RomRepoMgr.Core.EventArgs;
@@ -12,6 +11,7 @@ public class RomImporter : ReactiveObject
double _maximum;
double _minimum;
double _progress;
bool _progressVisible = true;
Color _statusColor;
string _statusMessage;
public string Filename { get; internal init; }
@@ -53,6 +53,12 @@ public class RomImporter : ReactiveObject
set => this.RaiseAndSetIfChanged(ref _statusColor, value);
}
public bool ProgressVisible
{
get => _progressVisible;
set => this.RaiseAndSetIfChanged(ref _progressVisible, value);
}
internal void OnErrorOccurred(object sender, ErrorEventArgs e)
{
StatusMessage = e.Message;
@@ -88,21 +94,23 @@ public class RomImporter : ReactiveObject
internal void OnWorkFinished(object sender, MessageEventArgs e)
{
Indeterminate = false;
Maximum = 1;
Minimum = 0;
Progress = 1;
StatusMessage = e.Message;
Running = false;
Indeterminate = false;
Maximum = 1;
Minimum = 0;
Progress = 1;
StatusMessage = e.Message;
Running = false;
ProgressVisible = false;
}
public void OnImportedRom(object sender, ImportedRomItemEventArgs e)
{
Indeterminate = false;
Maximum = 1;
Minimum = 0;
Progress = 1;
StatusMessage = e.Item.Status;
Running = false;
Indeterminate = false;
Maximum = 1;
Minimum = 0;
Progress = 1;
StatusMessage = e.Item.Status;
Running = false;
ProgressVisible = false;
}
}

View File

@@ -31,7 +31,6 @@
<PackageReference Include="Roslynator.Analyzers"/>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers"/>
<PackageReference Include="Roslynator.Formatting.Analyzers"/>
<PackageReference Include="SkiaSharp.NativeAssets.Linux"/>
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer"/>
<PackageReference Include="Text.Analyzers"/>
</ItemGroup>

View File

@@ -12,6 +12,8 @@ using Avalonia.Threading;
using ReactiveUI;
using RomRepoMgr.Core.EventArgs;
using RomRepoMgr.Core.Workers;
using RomRepoMgr.Database;
using RomRepoMgr.Database.Models;
using RomRepoMgr.Models;
using RomRepoMgr.Resources;
@@ -19,31 +21,36 @@ namespace RomRepoMgr.ViewModels;
public class ImportRomFolderViewModel : ViewModelBase
{
bool _canClose;
bool _canStart;
string _folderPath;
bool _isImporting;
bool _isReady;
bool _knownOnlyChecked;
int _listPosition;
bool _progress2IsIndeterminate;
double _progress2Maximum;
double _progress2Minimum;
double _progress2Value;
bool _progress2Visible;
bool _progressIsIndeterminate;
double _progressMaximum;
double _progressMinimum;
double _progressValue;
bool _progressVisible;
bool _recurseArchivesChecked;
bool _removeFilesChecked;
bool _removeFilesEnabled;
FileImporter _rootImporter;
string _statusMessage;
string _statusMessage2;
bool _statusMessage2Visible;
readonly Stopwatch _stopwatch = new();
readonly Context _ctx = Context.Create(Settings.Settings.Current.DatabasePath);
readonly ConcurrentBag<DbDisk> _newDisks = [];
readonly ConcurrentBag<DbFile> _newFiles = [];
readonly ConcurrentBag<DbMedia> _newMedias = [];
readonly Stopwatch _stopwatch = new();
bool _canClose;
bool _canStart;
string _folderPath;
bool _isImporting;
bool _isReady;
bool _knownOnlyChecked;
int _listPosition;
bool _progress2IsIndeterminate;
double _progress2Maximum;
double _progress2Minimum;
double _progress2Value;
bool _progress2Visible;
bool _progressIsIndeterminate;
double _progressMaximum;
double _progressMinimum;
double _progressValue;
bool _progressVisible;
bool _recurseArchivesChecked;
bool _removeFilesChecked;
bool _removeFilesEnabled;
FileImporter _rootImporter;
string _statusMessage;
string _statusMessage2;
bool _statusMessage2Visible;
public ImportRomFolderViewModel()
{
@@ -207,17 +214,17 @@ public class ImportRomFolderViewModel : ViewModelBase
void Start()
{
_rootImporter = new FileImporter(KnownOnlyChecked, RemoveFilesChecked);
_rootImporter.SetMessage += SetMessage;
_rootImporter = new FileImporter(_ctx, _newFiles, _newDisks, _newMedias, KnownOnlyChecked, RemoveFilesChecked);
_rootImporter.SetMessage += SetMessage;
_rootImporter.SetIndeterminateProgress += SetIndeterminateProgress;
_rootImporter.SetProgress += SetProgress;
_rootImporter.SetProgressBounds += SetProgressBounds;
_rootImporter.Finished += EnumeratingFilesFinished;
ProgressIsIndeterminate = true;
ProgressVisible = true;
CanClose = false;
CanStart = false;
IsImporting = true;
_rootImporter.SetProgress += SetProgress;
_rootImporter.SetProgressBounds += SetProgressBounds;
_rootImporter.Finished += EnumeratingFilesFinished;
ProgressIsIndeterminate = true;
ProgressVisible = true;
CanClose = false;
CanStart = false;
IsImporting = true;
_ = Task.Run(() => _rootImporter.FindFiles(FolderPath));
}
@@ -310,7 +317,13 @@ public class ImportRomFolderViewModel : ViewModelBase
Indeterminate = true
};
var worker = new FileImporter(KnownOnlyChecked, RemoveFilesChecked);
var worker = new FileImporter(_ctx,
_newFiles,
_newDisks,
_newMedias,
KnownOnlyChecked,
RemoveFilesChecked);
worker.SetIndeterminateProgress2 += model.OnSetIndeterminateProgress;
worker.SetMessage2 += model.OnSetMessage;
worker.SetProgress2 += model.OnSetProgress;
@@ -322,13 +335,14 @@ public class ImportRomFolderViewModel : ViewModelBase
worker.ImportFile(file);
worker.SaveChanges();
Interlocked.Increment(ref _listPosition);
});
_stopwatch.Stop();
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process files.");
_rootImporter.SaveChanges();
_rootImporter.UpdateRomStats();
_listPosition = 0;
@@ -351,32 +365,35 @@ public class ImportRomFolderViewModel : ViewModelBase
ProgressMinimum = 0;
ProgressValue = 0;
ProgressIsIndeterminate = false;
Progress2Visible = true;
StatusMessage2Visible = true;
Progress2Visible = false;
StatusMessage2Visible = false;
_listPosition = 0;
_stopwatch.Restart();
foreach(string archive in _rootImporter.Archives)
{
StatusMessage = "Processing archive: " + Path.GetFileName(archive);
ProgressValue = _listPosition++;
Parallel.ForEach(_rootImporter.Archives,
archive =>
{
Dispatcher.UIThread.Post(() =>
{
StatusMessage = "Processing archive: " + Path.GetFileName(archive);
ProgressValue = _listPosition;
});
// Create FileImporter
var archiveImporter = new FileImporter(KnownOnlyChecked, RemoveFilesChecked);
// Create FileImporter
var archiveImporter = new FileImporter(_ctx,
_newFiles,
_newDisks,
_newMedias,
KnownOnlyChecked,
RemoveFilesChecked);
archiveImporter.SetIndeterminateProgress2 += SetIndeterminateProgress2;
archiveImporter.SetMessage2 += SetMessage2;
archiveImporter.SetProgress2 += SetProgress2;
archiveImporter.SetProgressBounds2 += SetProgress2Bounds;
// Extract archive
bool ret = archiveImporter.ExtractArchive(archive);
// Extract archive
bool ret = archiveImporter.ExtractArchive(archive);
if(!ret) return;
if(!ret) continue;
// Process files in archive
Parallel.ForEach(archiveImporter.Files,
file =>
// Process files in archive
foreach(string file in archiveImporter.Files)
{
var model = new RomImporter
{
@@ -384,7 +401,13 @@ public class ImportRomFolderViewModel : ViewModelBase
Indeterminate = true
};
var worker = new FileImporter(KnownOnlyChecked, RemoveFilesChecked);
var worker = new FileImporter(_ctx,
_newFiles,
_newDisks,
_newMedias,
KnownOnlyChecked,
RemoveFilesChecked);
worker.SetIndeterminateProgress2 += model.OnSetIndeterminateProgress;
worker.SetMessage2 += model.OnSetMessage;
worker.SetProgress2 += model.OnSetProgress;
@@ -396,17 +419,14 @@ public class ImportRomFolderViewModel : ViewModelBase
worker.ImportFile(file);
worker.SaveChanges();
worker.Files.Clear();
});
}
// Remove temporary files
archiveImporter.CleanupExtractedArchive();
// Remove temporary files
archiveImporter.CleanupExtractedArchive();
// Save database changes
archiveImporter.SaveChanges();
}
Interlocked.Increment(ref _listPosition);
});
_stopwatch.Stop();
Console.WriteLine("Took " + _stopwatch.Elapsed.TotalSeconds + " seconds to process archives.");

View File

@@ -105,7 +105,8 @@
<ProgressBar Minimum="{Binding Minimum, Mode=OneWay}"
Maximum="{Binding Maximum, Mode=OneWay}"
Value="{Binding Progress, Mode=OneWay}"
IsIndeterminate="{Binding Indeterminate, Mode=OneWay}" />
IsIndeterminate="{Binding Indeterminate, Mode=OneWay}"
IsVisible="{Binding ProgressVisible, Mode=OneWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

View File

@@ -2,7 +2,7 @@ using Avalonia.Controls;
namespace RomRepoMgr.Views;
public class ImportRomFolder : Window
public partial class ImportRomFolder : Window
{
public ImportRomFolder()
{