2020-08-23 20:10:38 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2020-08-24 01:17:20 +01:00
|
|
|
using System.Diagnostics;
|
2020-08-23 20:10:38 +01:00
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2020-09-11 00:42:24 +01:00
|
|
|
using Microsoft.EntityFrameworkCore;
|
2020-08-24 01:17:20 +01:00
|
|
|
using Newtonsoft.Json;
|
2020-08-29 17:56:17 +01:00
|
|
|
using RomRepoMgr.Core.Aaru;
|
2020-08-23 20:10:38 +01:00
|
|
|
using RomRepoMgr.Core.EventArgs;
|
2020-08-23 22:17:49 +01:00
|
|
|
using RomRepoMgr.Core.Models;
|
2020-08-30 03:00:14 +01:00
|
|
|
using RomRepoMgr.Core.Resources;
|
2020-08-23 20:10:38 +01:00
|
|
|
using RomRepoMgr.Database;
|
|
|
|
|
using RomRepoMgr.Database.Models;
|
2020-12-20 23:17:18 +00:00
|
|
|
using SabreTools.FileTypes.Aaru;
|
|
|
|
|
using SabreTools.FileTypes.CHD;
|
2020-08-23 20:10:38 +01:00
|
|
|
using SharpCompress.Compressors;
|
|
|
|
|
using SharpCompress.Compressors.LZMA;
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
namespace RomRepoMgr.Core.Workers;
|
|
|
|
|
|
|
|
|
|
public class FileImporter
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
const long BUFFER_SIZE = 131072;
|
|
|
|
|
readonly Context _ctx;
|
|
|
|
|
readonly bool _deleteAfterImport;
|
|
|
|
|
readonly List<DbDisk> _newDisks;
|
|
|
|
|
readonly List<DbFile> _newFiles;
|
|
|
|
|
readonly List<DbMedia> _newMedias;
|
|
|
|
|
readonly bool _onlyKnown;
|
|
|
|
|
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 _lastMessage;
|
|
|
|
|
long _position;
|
|
|
|
|
long _totalFiles;
|
|
|
|
|
|
|
|
|
|
public FileImporter(bool onlyKnown, bool deleteAfterImport)
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
_pendingFiles = new Dictionary<string, DbFile>();
|
|
|
|
|
_pendingDisksByMd5 = new Dictionary<string, DbDisk>();
|
|
|
|
|
_pendingDisksBySha1 = new Dictionary<string, DbDisk>();
|
|
|
|
|
_pendingMediasBySha256 = new Dictionary<string, DbMedia>();
|
|
|
|
|
_pendingMediasBySha1 = new Dictionary<string, DbMedia>();
|
|
|
|
|
_pendingMediasByMd5 = new Dictionary<string, DbMedia>();
|
2024-11-12 06:39:06 +00:00
|
|
|
_newFiles = [];
|
|
|
|
|
_newDisks = [];
|
|
|
|
|
_newMedias = [];
|
2024-11-09 01:37:59 +00:00
|
|
|
_onlyKnown = onlyKnown;
|
|
|
|
|
_deleteAfterImport = deleteAfterImport;
|
|
|
|
|
_position = 0;
|
|
|
|
|
_ctx = Context.Create(Settings.Settings.Current.DatabasePath);
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
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 void ProcessPath(string path, bool rootPath, bool processArchives)
|
|
|
|
|
{
|
|
|
|
|
try
|
2020-08-23 22:17:49 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
SetIndeterminateProgress?.Invoke(this, System.EventArgs.Empty);
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.EnumeratingFiles
|
|
|
|
|
});
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories).OrderBy(p => p).ToArray();
|
|
|
|
|
_totalFiles += files.LongLength;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgressBounds?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = _totalFiles
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
foreach(string file in files)
|
|
|
|
|
{
|
|
|
|
|
try
|
2020-08-23 22:17:49 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = _position
|
|
|
|
|
});
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = string.Format(Localization.Importing, Path.GetFileName(file))
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string archiveFormat = null;
|
|
|
|
|
long archiveFiles = 0;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var fs = new FileStream(file, FileMode.Open, FileAccess.Read);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var aif = AaruFormat.Create(fs);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif != null)
|
|
|
|
|
{
|
|
|
|
|
fs.Close();
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ret = ImportMedia(file);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(ret)
|
|
|
|
|
{
|
|
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = Localization.OK
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
}
|
2024-11-09 01:37:59 +00:00
|
|
|
else
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = string.Format(Localization.ErrorWithMessage,
|
|
|
|
|
_lastMessage)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
_position++;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
fs.Position = 0;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var chd = CHDFile.Create(fs);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd != null)
|
|
|
|
|
{
|
2020-09-04 22:19:40 +01:00
|
|
|
fs.Close();
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ret = ImportDisk(file);
|
2020-08-29 17:56:17 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(ret)
|
2020-08-24 01:17:20 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = Localization.OK
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-08-24 01:17:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = string.Format(Localization.ErrorWithMessage,
|
|
|
|
|
_lastMessage)
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-08-24 01:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_position++;
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
fs.Close();
|
2020-08-23 22:17:49 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(processArchives)
|
|
|
|
|
{
|
|
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.CheckingIfFIleIsAnArchive
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
archiveFormat = GetArchiveFormat(file, out archiveFiles);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
// If a floppy contains only the archive, unar will recognize it, on its skipping of SFXs.
|
|
|
|
|
if(archiveFormat != null && FAT.Identify(file)) archiveFormat = null;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(archiveFormat == null)
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ret = ImportRom(file);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(ret)
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = Localization.OK
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = string.Format(Localization.ErrorWithMessage,
|
|
|
|
|
_lastMessage)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
2024-11-09 01:37:59 +00:00
|
|
|
else
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!Directory.Exists(Settings.Settings.Current.TemporaryFolder))
|
|
|
|
|
Directory.CreateDirectory(Settings.Settings.Current.TemporaryFolder);
|
|
|
|
|
|
|
|
|
|
string tmpFolder =
|
|
|
|
|
Path.Combine(Settings.Settings.Current.TemporaryFolder, Path.GetRandomFileName());
|
|
|
|
|
|
|
|
|
|
Directory.CreateDirectory(tmpFolder);
|
|
|
|
|
|
|
|
|
|
SetProgressBounds2?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = archiveFiles
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SetMessage?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.ExtractingArchive
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ExtractArchive(file, tmpFolder);
|
|
|
|
|
|
|
|
|
|
ProcessPath(tmpFolder, false, true);
|
|
|
|
|
|
|
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
|
|
|
|
|
|
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.RemovingTemporaryPath
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Directory.Delete(tmpFolder, true);
|
|
|
|
|
|
|
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = Localization.ExtractedContents
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
_position++;
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
2024-11-09 01:37:59 +00:00
|
|
|
catch(Exception)
|
|
|
|
|
{
|
|
|
|
|
ImportedRom?.Invoke(this,
|
|
|
|
|
new ImportedRomItemEventArgs
|
|
|
|
|
{
|
|
|
|
|
Item = new ImportRomItem
|
|
|
|
|
{
|
|
|
|
|
Filename = Path.GetFileName(file),
|
|
|
|
|
Status = Localization.UnhandledException
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
2024-11-09 01:37:59 +00:00
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!rootPath) return;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SaveChanges();
|
|
|
|
|
Finished?.Invoke(this, System.EventArgs.Empty);
|
|
|
|
|
}
|
|
|
|
|
catch(Exception)
|
|
|
|
|
{
|
|
|
|
|
// TODO: Send error back
|
|
|
|
|
if(rootPath) Finished?.Invoke(this, System.EventArgs.Empty);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ImportRom(string path)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var inFs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
byte[] buffer;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.HashingFile
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var checksumWorker = new Checksum();
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(inFs.Length > BUFFER_SIZE)
|
|
|
|
|
{
|
|
|
|
|
SetProgressBounds2?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = inFs.Length
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
long offset;
|
|
|
|
|
long remainder = inFs.Length % BUFFER_SIZE;
|
|
|
|
|
|
|
|
|
|
for(offset = 0; offset < inFs.Length - remainder; offset += (int)BUFFER_SIZE)
|
|
|
|
|
{
|
|
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = offset
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
buffer = new byte[BUFFER_SIZE];
|
|
|
|
|
inFs.Read(buffer, 0, (int)BUFFER_SIZE);
|
|
|
|
|
checksumWorker.Update(buffer);
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = offset
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
buffer = new byte[remainder];
|
|
|
|
|
inFs.Read(buffer, 0, (int)remainder);
|
|
|
|
|
checksumWorker.Update(buffer);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
|
|
|
|
buffer = new byte[inFs.Length];
|
|
|
|
|
inFs.Read(buffer, 0, (int)inFs.Length);
|
|
|
|
|
checksumWorker.Update(buffer);
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
Dictionary<ChecksumType, string> checksums = checksumWorker.End();
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var uSize = (ulong)inFs.Length;
|
|
|
|
|
var fileInDb = true;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool knownFile = _pendingFiles.TryGetValue(checksums[ChecksumType.Sha512], out DbFile dbFile);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbFile ??= _ctx.Files.FirstOrDefault(f => (f.Sha512 == checksums[ChecksumType.Sha512] ||
|
|
|
|
|
f.Sha384 == checksums[ChecksumType.Sha384] ||
|
|
|
|
|
f.Sha256 == checksums[ChecksumType.Sha256] ||
|
|
|
|
|
f.Sha1 == checksums[ChecksumType.Sha1] ||
|
|
|
|
|
f.Md5 == checksums[ChecksumType.Md5] ||
|
|
|
|
|
f.Crc32 == checksums[ChecksumType.Crc32]) &&
|
|
|
|
|
f.Size == uSize);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile == null)
|
|
|
|
|
{
|
|
|
|
|
if(_onlyKnown)
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
_lastMessage = Localization.UnknownFile;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbFile = new DbFile
|
|
|
|
|
{
|
|
|
|
|
Crc32 = checksums[ChecksumType.Crc32],
|
|
|
|
|
Md5 = checksums[ChecksumType.Md5],
|
|
|
|
|
Sha1 = checksums[ChecksumType.Sha1],
|
|
|
|
|
Sha256 = checksums[ChecksumType.Sha256],
|
|
|
|
|
Sha384 = checksums[ChecksumType.Sha384],
|
|
|
|
|
Sha512 = checksums[ChecksumType.Sha512],
|
|
|
|
|
Size = uSize,
|
|
|
|
|
CreatedOn = DateTime.UtcNow,
|
|
|
|
|
UpdatedOn = DateTime.UtcNow,
|
|
|
|
|
OriginalFileName = Path.GetFileName(path)
|
|
|
|
|
};
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
fileInDb = false;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownFile) _pendingFiles[checksums[ChecksumType.Sha512]] = dbFile;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var sha384Bytes = new byte[48];
|
|
|
|
|
string sha384 = checksums[ChecksumType.Sha384];
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 48; i++)
|
|
|
|
|
{
|
|
|
|
|
if(sha384[i * 2] >= 0x30 && sha384[i * 2] <= 0x39)
|
|
|
|
|
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x30) * 0x10);
|
|
|
|
|
else if(sha384[i * 2] >= 0x41 && sha384[i * 2] <= 0x46)
|
|
|
|
|
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x37) * 0x10);
|
|
|
|
|
else if(sha384[i * 2] >= 0x61 && sha384[i * 2] <= 0x66)
|
|
|
|
|
sha384Bytes[i] = (byte)((sha384[i * 2] - 0x57) * 0x10);
|
|
|
|
|
|
|
|
|
|
if(sha384[i * 2 + 1] >= 0x30 && sha384[i * 2 + 1] <= 0x39)
|
|
|
|
|
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x30);
|
|
|
|
|
else if(sha384[i * 2 + 1] >= 0x41 && sha384[i * 2 + 1] <= 0x46)
|
|
|
|
|
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x37);
|
|
|
|
|
else if(sha384[i * 2 + 1] >= 0x61 && sha384[i * 2 + 1] <= 0x66)
|
|
|
|
|
sha384Bytes[i] += (byte)(sha384[i * 2 + 1] - 0x57);
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string sha384B32 = Base32.ToBase32String(sha384Bytes);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string repoPath = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"files",
|
|
|
|
|
sha384B32[0].ToString(),
|
|
|
|
|
sha384B32[1].ToString(),
|
|
|
|
|
sha384B32[2].ToString(),
|
|
|
|
|
sha384B32[3].ToString(),
|
|
|
|
|
sha384B32[4].ToString());
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!Directory.Exists(repoPath)) Directory.CreateDirectory(repoPath);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
repoPath = Path.Combine(repoPath, sha384B32 + ".lz");
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Crc32 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Crc32 = checksums[ChecksumType.Crc32];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Md5 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Md5 = checksums[ChecksumType.Md5];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Sha1 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Sha1 = checksums[ChecksumType.Sha1];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Sha256 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Sha256 = checksums[ChecksumType.Sha256];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Sha384 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Sha384 = checksums[ChecksumType.Sha384];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbFile.Sha512 == null)
|
|
|
|
|
{
|
|
|
|
|
dbFile.Sha512 = checksums[ChecksumType.Sha512];
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(File.Exists(repoPath))
|
|
|
|
|
{
|
|
|
|
|
dbFile.IsInRepo = true;
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!fileInDb) _newFiles.Add(dbFile);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Position = 0;
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var outFs = new FileStream(repoPath, FileMode.CreateNew, FileAccess.Write);
|
|
|
|
|
Stream zStream = null;
|
|
|
|
|
zStream = new LZipStream(outFs, CompressionMode.Compress);
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgressBounds2?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = inFs.Length
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.CompressingFile
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
buffer = new byte[BUFFER_SIZE];
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
|
2020-08-23 20:10:38 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
zStream.Write(buffer, 0, buffer.Length);
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
buffer = new byte[inFs.Length - inFs.Position];
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
zStream.Write(buffer, 0, buffer.Length);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.Finishing
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
|
|
|
|
zStream.Close();
|
|
|
|
|
outFs.Dispose();
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbFile.IsInRepo = true;
|
|
|
|
|
dbFile.UpdatedOn = DateTime.UtcNow;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!fileInDb) _newFiles.Add(dbFile);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.UnhandledExceptionWhenImporting;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ImportDisk(string path)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var inFs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.HashingFile
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var chd = CHDFile.Create(path);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd == null)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.NotAChdFile;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd.MD5 == null && chd.SHA1 == null)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.NoChecksumsFound;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string md5 = null;
|
|
|
|
|
string sha1 = null;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd.MD5 != null)
|
|
|
|
|
{
|
|
|
|
|
var chdArray = new char[32];
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 16; i++)
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
int nibble1 = chd.MD5[i] >> 4;
|
|
|
|
|
int nibble2 = chd.MD5[i] & 0xF;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
nibble1 += nibble1 >= 0xA ? 0x37 : 0x30;
|
|
|
|
|
nibble2 += nibble2 >= 0xA ? 0x37 : 0x30;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
chdArray[i * 2] = (char)nibble1;
|
|
|
|
|
chdArray[i * 2 + 1] = (char)nibble2;
|
2020-09-04 18:16:18 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
md5 = new string(chdArray);
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd.SHA1 != null)
|
|
|
|
|
{
|
|
|
|
|
var chdArray = new char[40];
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 20; i++)
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
int nibble1 = chd.SHA1[i] >> 4;
|
|
|
|
|
int nibble2 = chd.SHA1[i] & 0xF;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
nibble1 += nibble1 >= 0xA ? 0x57 : 0x30;
|
|
|
|
|
nibble2 += nibble2 >= 0xA ? 0x57 : 0x30;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
chdArray[i * 2] = (char)nibble1;
|
|
|
|
|
chdArray[i * 2 + 1] = (char)nibble2;
|
2020-09-04 19:30:18 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
sha1 = new string(chdArray);
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var uSize = (ulong)inFs.Length;
|
|
|
|
|
var diskInDb = true;
|
|
|
|
|
DbDisk dbDisk = null;
|
|
|
|
|
var knownDisk = false;
|
|
|
|
|
var knownDiskWasBigger = false;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha1 != null) knownDisk = _pendingDisksBySha1.TryGetValue(sha1, out dbDisk);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownDisk && md5 != null) knownDisk = _pendingDisksByMd5.TryGetValue(md5, out dbDisk);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbDisk ??=
|
|
|
|
|
_ctx.Disks.FirstOrDefault(d => d.Sha1 != null && d.Sha1 == sha1 || d.Md5 != null && d.Md5 == sha1);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbDisk == null)
|
|
|
|
|
{
|
|
|
|
|
if(_onlyKnown)
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
_lastMessage = Localization.UnknownFile;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
2020-09-04 18:16:18 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbDisk = new DbDisk
|
|
|
|
|
{
|
|
|
|
|
Md5 = md5,
|
|
|
|
|
Sha1 = sha1,
|
|
|
|
|
Size = uSize,
|
|
|
|
|
CreatedOn = DateTime.UtcNow,
|
|
|
|
|
UpdatedOn = DateTime.UtcNow,
|
|
|
|
|
OriginalFileName = Path.GetFileName(path)
|
|
|
|
|
};
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
diskInDb = false;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownDisk)
|
|
|
|
|
{
|
|
|
|
|
if(sha1 != null)
|
|
|
|
|
_pendingDisksBySha1[sha1] = dbDisk;
|
|
|
|
|
else if(md5 != null) _pendingDisksByMd5[md5] = dbDisk;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string sha1B32 = null;
|
|
|
|
|
string md5B32 = null;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd.SHA1 != null) sha1B32 = Base32.ToBase32String(chd.SHA1);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(chd.MD5 != null) md5B32 = Base32.ToBase32String(chd.SHA1);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbDisk.Md5 == null && md5 != null)
|
|
|
|
|
{
|
|
|
|
|
dbDisk.Md5 = md5;
|
|
|
|
|
dbDisk.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbDisk.Sha1 == null && sha1 != null)
|
|
|
|
|
{
|
|
|
|
|
dbDisk.Sha1 = sha1;
|
|
|
|
|
dbDisk.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbDisk.Size > uSize)
|
|
|
|
|
{
|
|
|
|
|
knownDiskWasBigger = true;
|
|
|
|
|
dbDisk.Size = null;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbDisk.Size == null)
|
|
|
|
|
{
|
|
|
|
|
dbDisk.Size = uSize;
|
|
|
|
|
dbDisk.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string md5Path = null;
|
|
|
|
|
string sha1Path = null;
|
|
|
|
|
string repoPath = null;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(md5 != null)
|
|
|
|
|
{
|
|
|
|
|
md5Path = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"chd",
|
|
|
|
|
"md5",
|
|
|
|
|
md5B32[0].ToString(),
|
|
|
|
|
md5B32[1].ToString(),
|
|
|
|
|
md5B32[2].ToString(),
|
|
|
|
|
md5B32[3].ToString(),
|
|
|
|
|
md5B32[4].ToString());
|
|
|
|
|
|
|
|
|
|
repoPath = md5Path;
|
|
|
|
|
|
|
|
|
|
md5Path = Path.Combine(repoPath, md5B32 + ".chd");
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha1 != null)
|
|
|
|
|
{
|
|
|
|
|
sha1Path = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"chd",
|
|
|
|
|
"sha1",
|
|
|
|
|
sha1B32[0].ToString(),
|
|
|
|
|
sha1B32[1].ToString(),
|
|
|
|
|
sha1B32[2].ToString(),
|
|
|
|
|
sha1B32[3].ToString(),
|
|
|
|
|
sha1B32[4].ToString());
|
|
|
|
|
|
|
|
|
|
repoPath = sha1Path;
|
|
|
|
|
|
|
|
|
|
sha1Path = Path.Combine(repoPath, sha1B32 + ".chd");
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!Directory.Exists(repoPath)) Directory.CreateDirectory(repoPath);
|
|
|
|
|
|
|
|
|
|
if(File.Exists(md5Path) && sha1Path != null) File.Move(md5Path, sha1Path);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha1Path != null)
|
|
|
|
|
repoPath = sha1Path;
|
|
|
|
|
else if(md5Path != null) repoPath = md5Path;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(File.Exists(repoPath))
|
|
|
|
|
{
|
|
|
|
|
if(!knownDiskWasBigger)
|
|
|
|
|
File.Move(repoPath, repoPath + ".bak", true);
|
|
|
|
|
else
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
dbDisk.IsInRepo = true;
|
|
|
|
|
dbDisk.UpdatedOn = DateTime.UtcNow;
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!diskInDb) _newDisks.Add(dbDisk);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Position = 0;
|
|
|
|
|
var outFs = new FileStream(repoPath, FileMode.CreateNew, FileAccess.Write);
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgressBounds2?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = inFs.Length
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.CopyingFile
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var buffer = new byte[BUFFER_SIZE];
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
|
2020-09-04 18:16:18 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-09-04 18:16:18 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
outFs.Write(buffer, 0, buffer.Length);
|
2020-09-04 18:16:18 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
buffer = new byte[inFs.Length - inFs.Position];
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
outFs.Write(buffer, 0, buffer.Length);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.Finishing
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
|
|
|
|
outFs.Close();
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbDisk.IsInRepo = true;
|
|
|
|
|
dbDisk.UpdatedOn = DateTime.UtcNow;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!diskInDb) _newDisks.Add(dbDisk);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(knownDiskWasBigger) File.Delete(repoPath + ".bak");
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.UnhandledExceptionWhenImporting;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
bool ImportMedia(string path)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var inFs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.HashingFile
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var aif = AaruFormat.Create(path);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif == null)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.NotAnAaruFormatFile;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.MD5 == null && aif.SHA1 == null && aif.SHA256 == null)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.NoChecksumsFound;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string md5 = null;
|
|
|
|
|
string sha1 = null;
|
|
|
|
|
string sha256 = null;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.MD5 != null)
|
|
|
|
|
{
|
|
|
|
|
var chdArray = new char[32];
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
int nibble1 = aif.MD5[i] >> 4;
|
|
|
|
|
int nibble2 = aif.MD5[i] & 0xF;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
nibble1 += nibble1 >= 0xA ? 0x37 : 0x30;
|
|
|
|
|
nibble2 += nibble2 >= 0xA ? 0x37 : 0x30;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
chdArray[i * 2] = (char)nibble1;
|
|
|
|
|
chdArray[i * 2 + 1] = (char)nibble2;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
md5 = new string(chdArray);
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.SHA1 != null)
|
|
|
|
|
{
|
|
|
|
|
var chdArray = new char[40];
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 20; i++)
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
int nibble1 = aif.SHA1[i] >> 4;
|
|
|
|
|
int nibble2 = aif.SHA1[i] & 0xF;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
nibble1 += nibble1 >= 0xA ? 0x57 : 0x30;
|
|
|
|
|
nibble2 += nibble2 >= 0xA ? 0x57 : 0x30;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
chdArray[i * 2] = (char)nibble1;
|
|
|
|
|
chdArray[i * 2 + 1] = (char)nibble2;
|
2020-09-04 22:19:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
sha1 = new string(chdArray);
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.SHA256 != null)
|
|
|
|
|
{
|
|
|
|
|
var chdArray = new char[64];
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
for(var i = 0; i < 32; i++)
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
int nibble1 = aif.SHA256[i] >> 4;
|
|
|
|
|
int nibble2 = aif.SHA256[i] & 0xF;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
nibble1 += nibble1 >= 0xA ? 0x57 : 0x30;
|
|
|
|
|
nibble2 += nibble2 >= 0xA ? 0x57 : 0x30;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
chdArray[i * 2] = (char)nibble1;
|
|
|
|
|
chdArray[i * 2 + 1] = (char)nibble2;
|
2020-09-04 22:19:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
sha256 = new string(chdArray);
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var uSize = (ulong)inFs.Length;
|
|
|
|
|
var mediaInDb = true;
|
|
|
|
|
DbMedia dbMedia = null;
|
|
|
|
|
var knownMedia = false;
|
|
|
|
|
var knownMediaWasBigger = false;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha256 != null) knownMedia = _pendingMediasBySha256.TryGetValue(sha256, out dbMedia);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownMedia && sha1 != null) knownMedia = _pendingMediasBySha1.TryGetValue(sha1, out dbMedia);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownMedia && md5 != null) knownMedia = _pendingMediasByMd5.TryGetValue(md5, out dbMedia);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbMedia ??= _ctx.Medias.FirstOrDefault(d => d.Sha256 != null && d.Sha256 == sha256 ||
|
|
|
|
|
d.Sha1 != null && d.Sha1 == sha1 ||
|
|
|
|
|
d.Md5 != null && d.Md5 == sha1);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia == null)
|
|
|
|
|
{
|
|
|
|
|
if(_onlyKnown)
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
_lastMessage = Localization.UnknownFile;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
2020-09-04 22:19:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbMedia = new DbMedia
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
Md5 = md5,
|
|
|
|
|
Sha1 = sha1,
|
|
|
|
|
Sha256 = sha256,
|
|
|
|
|
Size = uSize,
|
|
|
|
|
CreatedOn = DateTime.UtcNow,
|
|
|
|
|
UpdatedOn = DateTime.UtcNow,
|
|
|
|
|
OriginalFileName = Path.GetFileName(path)
|
|
|
|
|
};
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
mediaInDb = false;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!knownMedia)
|
|
|
|
|
{
|
|
|
|
|
if(sha256 != null)
|
|
|
|
|
_pendingMediasBySha256[sha256] = dbMedia;
|
|
|
|
|
else if(sha1 != null)
|
|
|
|
|
_pendingMediasBySha1[sha1] = dbMedia;
|
|
|
|
|
else if(md5 != null) _pendingMediasByMd5[md5] = dbMedia;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string sha256B32 = null;
|
|
|
|
|
string sha1B32 = null;
|
|
|
|
|
string md5B32 = null;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.SHA256 != null) sha256B32 = Base32.ToBase32String(aif.SHA256);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.SHA1 != null) sha1B32 = Base32.ToBase32String(aif.SHA1);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(aif.MD5 != null) md5B32 = Base32.ToBase32String(aif.SHA1);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia.Md5 == null && md5 != null)
|
|
|
|
|
{
|
|
|
|
|
dbMedia.Md5 = md5;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia.Sha1 == null && sha1 != null)
|
|
|
|
|
{
|
|
|
|
|
dbMedia.Sha1 = sha1;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia.Sha256 == null && sha256 != null)
|
|
|
|
|
{
|
|
|
|
|
dbMedia.Sha256 = sha256;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia.Size > uSize)
|
|
|
|
|
{
|
|
|
|
|
knownMediaWasBigger = true;
|
|
|
|
|
dbMedia.Size = null;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(dbMedia.Size == null)
|
|
|
|
|
{
|
|
|
|
|
dbMedia.Size = uSize;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string md5Path = null;
|
|
|
|
|
string sha1Path = null;
|
|
|
|
|
string sha256Path = null;
|
|
|
|
|
string repoPath = null;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(md5 != null)
|
|
|
|
|
{
|
|
|
|
|
md5Path = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"aaru",
|
|
|
|
|
"md5",
|
|
|
|
|
md5B32[0].ToString(),
|
|
|
|
|
md5B32[1].ToString(),
|
|
|
|
|
md5B32[2].ToString(),
|
|
|
|
|
md5B32[3].ToString(),
|
|
|
|
|
md5B32[4].ToString());
|
|
|
|
|
|
|
|
|
|
repoPath = md5Path;
|
|
|
|
|
|
|
|
|
|
md5Path = Path.Combine(repoPath, md5B32 + ".aif");
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha1 != null)
|
|
|
|
|
{
|
|
|
|
|
sha1Path = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"aaru",
|
|
|
|
|
"sha1",
|
|
|
|
|
sha1B32[0].ToString(),
|
|
|
|
|
sha1B32[1].ToString(),
|
|
|
|
|
sha1B32[2].ToString(),
|
|
|
|
|
sha1B32[3].ToString(),
|
|
|
|
|
sha1B32[4].ToString());
|
|
|
|
|
|
|
|
|
|
repoPath = sha1Path;
|
|
|
|
|
|
|
|
|
|
sha1Path = Path.Combine(repoPath, sha1B32 + ".aif");
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha256 != null)
|
|
|
|
|
{
|
|
|
|
|
sha256Path = Path.Combine(Settings.Settings.Current.RepositoryPath,
|
|
|
|
|
"aaru",
|
|
|
|
|
"sha256",
|
|
|
|
|
sha256B32[0].ToString(),
|
|
|
|
|
sha256B32[1].ToString(),
|
|
|
|
|
sha256B32[2].ToString(),
|
|
|
|
|
sha256B32[3].ToString(),
|
|
|
|
|
sha256B32[4].ToString());
|
|
|
|
|
|
|
|
|
|
repoPath = sha256Path;
|
|
|
|
|
|
|
|
|
|
sha256Path = Path.Combine(repoPath, sha256B32 + ".aif");
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!Directory.Exists(repoPath)) Directory.CreateDirectory(repoPath);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(File.Exists(md5Path))
|
|
|
|
|
{
|
|
|
|
|
if(sha256Path != null)
|
|
|
|
|
File.Move(md5Path, sha256Path);
|
|
|
|
|
else if(sha1Path != null) File.Move(md5Path, sha1Path);
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(File.Exists(sha1Path) && sha256Path != null) File.Move(sha1Path, sha256Path);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(sha256Path != null)
|
|
|
|
|
repoPath = sha256Path;
|
|
|
|
|
else if(sha1Path != null)
|
|
|
|
|
repoPath = sha1Path;
|
|
|
|
|
else if(md5Path != null) repoPath = md5Path;
|
|
|
|
|
|
|
|
|
|
if(File.Exists(repoPath))
|
|
|
|
|
{
|
|
|
|
|
if(!knownMediaWasBigger)
|
|
|
|
|
File.Move(repoPath, repoPath + ".bak", true);
|
|
|
|
|
else
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
dbMedia.IsInRepo = true;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!mediaInDb) _newMedias.Add(dbMedia);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Position = 0;
|
|
|
|
|
var outFs = new FileStream(repoPath, FileMode.CreateNew, FileAccess.Write);
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgressBounds2?.Invoke(this,
|
|
|
|
|
new ProgressBoundsEventArgs
|
|
|
|
|
{
|
|
|
|
|
Minimum = 0,
|
|
|
|
|
Maximum = inFs.Length
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.CopyingFile
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
var buffer = new byte[BUFFER_SIZE];
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
while(inFs.Position + BUFFER_SIZE <= inFs.Length)
|
2020-09-04 22:19:40 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-09-04 22:19:40 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
outFs.Write(buffer, 0, buffer.Length);
|
2020-09-04 22:19:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
buffer = new byte[inFs.Length - inFs.Position];
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = inFs.Position
|
|
|
|
|
});
|
2020-08-23 20:10:38 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Read(buffer, 0, buffer.Length);
|
|
|
|
|
outFs.Write(buffer, 0, buffer.Length);
|
2020-09-20 17:59:22 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
2020-09-20 17:59:22 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.Finishing
|
|
|
|
|
});
|
2020-09-20 17:59:22 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
inFs.Close();
|
|
|
|
|
outFs.Close();
|
2020-09-11 00:42:24 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
dbMedia.IsInRepo = true;
|
|
|
|
|
dbMedia.UpdatedOn = DateTime.UtcNow;
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!mediaInDb) _newMedias.Add(dbMedia);
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(_deleteAfterImport) File.Delete(path);
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(knownMediaWasBigger) File.Delete(repoPath + ".bak");
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception e)
|
|
|
|
|
{
|
|
|
|
|
_lastMessage = Localization.UnhandledExceptionWhenImporting;
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
void SaveChanges()
|
|
|
|
|
{
|
|
|
|
|
SetIndeterminateProgress2?.Invoke(this, System.EventArgs.Empty);
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = Localization.SavingChangesToDatabase
|
|
|
|
|
});
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
_ctx.SaveChanges();
|
|
|
|
|
|
|
|
|
|
_ctx.Files.AddRange(_newFiles);
|
|
|
|
|
_ctx.Disks.AddRange(_newDisks);
|
|
|
|
|
_ctx.Medias.AddRange(_newMedias);
|
|
|
|
|
|
|
|
|
|
_ctx.SaveChanges();
|
|
|
|
|
|
|
|
|
|
_ctx.Database.ExecuteSqlRaw("DELETE FROM \"RomSetStats\"");
|
|
|
|
|
|
|
|
|
|
_ctx.RomSetStats.AddRange(_ctx.RomSets.OrderBy(r => r.Id)
|
|
|
|
|
.Select(r => new RomSetStat
|
|
|
|
|
{
|
|
|
|
|
RomSetId = r.Id,
|
|
|
|
|
TotalMachines = r.Machines.Count,
|
|
|
|
|
CompleteMachines =
|
|
|
|
|
r.Machines.Count(m => m.Files.Count > 0 &&
|
|
|
|
|
m.Disks.Count == 0 &&
|
|
|
|
|
m.Files.All(f => f.File.IsInRepo)) +
|
|
|
|
|
r.Machines.Count(m => m.Disks.Count > 0 &&
|
|
|
|
|
m.Files.Count == 0 &&
|
|
|
|
|
m.Disks.All(f => f.Disk.IsInRepo)) +
|
|
|
|
|
r.Machines.Count(m => m.Files.Count > 0 &&
|
|
|
|
|
m.Disks.Count > 0 &&
|
|
|
|
|
m.Files.All(f => f.File.IsInRepo) &&
|
|
|
|
|
m.Disks.All(f => f.Disk.IsInRepo)),
|
|
|
|
|
IncompleteMachines =
|
|
|
|
|
r.Machines.Count(m => m.Files.Count > 0 &&
|
|
|
|
|
m.Disks.Count == 0 &&
|
|
|
|
|
m.Files.Any(f => !f.File.IsInRepo)) +
|
|
|
|
|
r.Machines.Count(m => m.Disks.Count > 0 &&
|
|
|
|
|
m.Files.Count == 0 &&
|
|
|
|
|
m.Disks.Any(f => !f.Disk.IsInRepo)) +
|
|
|
|
|
r.Machines.Count(m => m.Files.Count > 0 &&
|
|
|
|
|
m.Disks.Count > 0 &&
|
|
|
|
|
(m.Files.Any(f => !f.File.IsInRepo) ||
|
|
|
|
|
m.Disks.Any(f => !f.Disk.IsInRepo))),
|
|
|
|
|
TotalRoms =
|
|
|
|
|
r.Machines.Sum(m => m.Files.Count) +
|
|
|
|
|
r.Machines.Sum(m => m.Disks.Count) +
|
|
|
|
|
r.Machines.Sum(m => m.Medias.Count),
|
|
|
|
|
HaveRoms = r.Machines.Sum(m => m.Files.Count(f => f.File.IsInRepo)) +
|
|
|
|
|
r.Machines.Sum(m => m.Disks.Count(f => f.Disk.IsInRepo)) +
|
|
|
|
|
r.Machines.Sum(m => m.Medias.Count(f => f.Media.IsInRepo)),
|
|
|
|
|
MissRoms = r.Machines.Sum(m => m.Files.Count(f => !f.File.IsInRepo)) +
|
|
|
|
|
r.Machines.Sum(m => m.Disks.Count(f => !f.Disk.IsInRepo)) +
|
|
|
|
|
r.Machines.Sum(m => m.Medias.Count(f => !f.Media.IsInRepo))
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// TODO: Refresh main view
|
|
|
|
|
|
|
|
|
|
_ctx.SaveChanges();
|
|
|
|
|
|
|
|
|
|
_newFiles.Clear();
|
|
|
|
|
_newDisks.Clear();
|
|
|
|
|
_newMedias.Clear();
|
|
|
|
|
}
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
string GetArchiveFormat(string path, out long counter)
|
|
|
|
|
{
|
|
|
|
|
counter = 0;
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
if(!File.Exists(path)) return null;
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
try
|
2020-08-24 01:17:20 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
string unarFolder = Path.GetDirectoryName(Settings.Settings.Current.UnArchiverPath);
|
|
|
|
|
string extension = Path.GetExtension(Settings.Settings.Current.UnArchiverPath);
|
|
|
|
|
string unarFilename = Path.GetFileNameWithoutExtension(Settings.Settings.Current.UnArchiverPath);
|
|
|
|
|
string lsarFilename = unarFilename?.Replace("unar", "lsar");
|
|
|
|
|
string lsarPath = Path.Combine(unarFolder, lsarFilename + extension);
|
|
|
|
|
|
|
|
|
|
var lsarProcess = new Process
|
2020-08-24 01:17:20 +01:00
|
|
|
{
|
|
|
|
|
StartInfo =
|
|
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
FileName = lsarPath,
|
2020-08-24 01:17:20 +01:00
|
|
|
CreateNoWindow = true,
|
|
|
|
|
RedirectStandardOutput = true,
|
|
|
|
|
UseShellExecute = false,
|
|
|
|
|
ArgumentList =
|
|
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
"-j",
|
|
|
|
|
path
|
2020-08-24 01:17:20 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
lsarProcess.Start();
|
|
|
|
|
string lsarOutput = lsarProcess.StandardOutput.ReadToEnd();
|
|
|
|
|
lsarProcess.WaitForExit();
|
|
|
|
|
string format = null;
|
|
|
|
|
var jsReader = new JsonTextReader(new StringReader(lsarOutput));
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
while(jsReader.Read())
|
2020-08-24 01:17:20 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
switch(jsReader.TokenType)
|
2020-08-24 01:17:20 +01:00
|
|
|
{
|
2024-11-09 01:37:59 +00:00
|
|
|
case JsonToken.PropertyName
|
|
|
|
|
when jsReader.Value != null && jsReader.Value.ToString() == "XADFileName":
|
|
|
|
|
counter++;
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
break;
|
|
|
|
|
case JsonToken.PropertyName
|
|
|
|
|
when jsReader.Value != null && jsReader.Value.ToString() == "lsarFormatName":
|
|
|
|
|
jsReader.Read();
|
|
|
|
|
|
|
|
|
|
if(jsReader.TokenType == JsonToken.String && jsReader.Value != null)
|
|
|
|
|
format = jsReader.Value.ToString();
|
2020-08-24 01:17:20 +01:00
|
|
|
|
2024-11-09 01:37:59 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return counter == 0 ? null : format;
|
2020-08-24 01:17:20 +01:00
|
|
|
}
|
2024-11-09 01:37:59 +00:00
|
|
|
catch(Exception)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ExtractArchive(string archivePath, string outPath)
|
|
|
|
|
{
|
|
|
|
|
var unarProcess = new Process
|
|
|
|
|
{
|
|
|
|
|
StartInfo =
|
|
|
|
|
{
|
|
|
|
|
FileName = Settings.Settings.Current.UnArchiverPath,
|
|
|
|
|
CreateNoWindow = true,
|
|
|
|
|
RedirectStandardOutput = true,
|
|
|
|
|
UseShellExecute = false,
|
|
|
|
|
ArgumentList =
|
|
|
|
|
{
|
|
|
|
|
"-o",
|
|
|
|
|
outPath,
|
|
|
|
|
"-r",
|
|
|
|
|
"-D",
|
|
|
|
|
"-k",
|
|
|
|
|
"hidden",
|
|
|
|
|
archivePath
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
long counter = 0;
|
|
|
|
|
|
|
|
|
|
unarProcess.OutputDataReceived += (sender, e) =>
|
|
|
|
|
{
|
|
|
|
|
counter++;
|
|
|
|
|
|
|
|
|
|
SetMessage2?.Invoke(this,
|
|
|
|
|
new MessageEventArgs
|
|
|
|
|
{
|
|
|
|
|
Message = e.Data
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
SetProgress2?.Invoke(this,
|
|
|
|
|
new ProgressEventArgs
|
|
|
|
|
{
|
|
|
|
|
Value = counter
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
unarProcess.Start();
|
|
|
|
|
unarProcess.BeginOutputReadLine();
|
|
|
|
|
unarProcess.WaitForExit();
|
|
|
|
|
unarProcess.Close();
|
2020-08-23 20:10:38 +01:00
|
|
|
}
|
|
|
|
|
}
|