mirror of
https://github.com/SabreTools/MPF.git
synced 2026-02-04 05:35:52 +00:00
Extend logging with a new state (fixes #944)
This commit is contained in:
@@ -235,7 +235,7 @@ namespace MPF.CLI.Features
|
||||
Console.WriteLine($"Invoking {Options.InternalProgram} using '{paramStr}'");
|
||||
var dumpResult = env.Run(MediaType).GetAwaiter().GetResult();
|
||||
Console.WriteLine(dumpResult.Message);
|
||||
if (!dumpResult)
|
||||
if (dumpResult == false)
|
||||
return false;
|
||||
|
||||
// If it was not a dumping command
|
||||
|
||||
@@ -4,6 +4,23 @@ namespace MPF.Frontend.Test
|
||||
{
|
||||
public class ResultEventArgsTests
|
||||
{
|
||||
[Fact]
|
||||
public void EmptyNeutralTest()
|
||||
{
|
||||
var actual = ResultEventArgs.Neutral();
|
||||
Assert.Null((bool?)actual);
|
||||
Assert.Empty(actual.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CustomMessageNeutralTest()
|
||||
{
|
||||
string message = "Success!";
|
||||
var actual = ResultEventArgs.Neutral(message);
|
||||
Assert.Null((bool?)actual);
|
||||
Assert.Equal(message, actual.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptySuccessTest()
|
||||
{
|
||||
|
||||
@@ -10,7 +10,14 @@ namespace MPF.Frontend
|
||||
/// </summary>
|
||||
public static void ProgressUpdated(object? sender, ResultEventArgs value)
|
||||
{
|
||||
Console.WriteLine(value.Message);
|
||||
string prefix = (bool?)value switch
|
||||
{
|
||||
true => "SUCCESS: ",
|
||||
false => "FAILURE: ",
|
||||
_ => "",
|
||||
};
|
||||
|
||||
Console.WriteLine($"{prefix}{value.Message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -455,11 +455,11 @@ namespace MPF.Frontend
|
||||
|
||||
// Check that we have the basics for dumping
|
||||
ResultEventArgs result = IsValidForDump(mediaType);
|
||||
if (!result)
|
||||
if (result == false)
|
||||
return result;
|
||||
|
||||
// Execute internal tool
|
||||
progress?.Report(ResultEventArgs.Success($"Executing {_internalProgram}... please wait!"));
|
||||
progress?.Report(ResultEventArgs.Neutral($"Executing {_internalProgram}... please wait!"));
|
||||
|
||||
var directoryName = Path.GetDirectoryName(OutputPath);
|
||||
if (!string.IsNullOrEmpty(directoryName))
|
||||
@@ -507,7 +507,7 @@ namespace MPF.Frontend
|
||||
protectionProgress = temp;
|
||||
}
|
||||
|
||||
resultProgress.Report(ResultEventArgs.Success("Gathering submission information... please wait!"));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Gathering submission information... please wait!"));
|
||||
|
||||
// Get the output directory and filename separately
|
||||
var outputDirectory = Path.GetDirectoryName(OutputPath);
|
||||
@@ -530,7 +530,7 @@ namespace MPF.Frontend
|
||||
return ResultEventArgs.Failure("Could not determine the media type from output files...");
|
||||
|
||||
// Extract the information from the output files
|
||||
resultProgress.Report(ResultEventArgs.Success("Extracting output information from output files..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Extracting output information from output files..."));
|
||||
var submissionInfo = await SubmissionGenerator.ExtractOutputInformation(
|
||||
OutputPath,
|
||||
_drive,
|
||||
@@ -548,7 +548,7 @@ namespace MPF.Frontend
|
||||
// Inject seed submission info data, if necessary
|
||||
if (seedInfo is not null)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Injecting user-supplied information..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Injecting user-supplied information..."));
|
||||
submissionInfo = Builder.InjectSubmissionInformation(submissionInfo, seedInfo);
|
||||
resultProgress.Report(ResultEventArgs.Success("Information injection complete!"));
|
||||
}
|
||||
@@ -556,7 +556,7 @@ namespace MPF.Frontend
|
||||
// Get user-modifiable information if configured to
|
||||
if (_options.PromptForDiscInformation && processUserInfo is not null)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Waiting for additional media information..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Waiting for additional media information..."));
|
||||
bool? filledInfo = processUserInfo.Invoke(_options, ref submissionInfo);
|
||||
if (filledInfo == true)
|
||||
resultProgress.Report(ResultEventArgs.Success("Additional media information added!"));
|
||||
@@ -565,12 +565,12 @@ namespace MPF.Frontend
|
||||
}
|
||||
|
||||
// Process special fields for site codes
|
||||
resultProgress.Report(ResultEventArgs.Success("Processing site codes..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Processing site codes..."));
|
||||
Formatter.ProcessSpecialFields(submissionInfo!);
|
||||
resultProgress.Report(ResultEventArgs.Success("Processing complete!"));
|
||||
|
||||
// Format the information for the text output
|
||||
resultProgress.Report(ResultEventArgs.Success("Formatting information..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Formatting information..."));
|
||||
var formattedValues = Formatter.FormatOutputData(submissionInfo, _options.EnableRedumpCompatibility, out string? formatResult);
|
||||
if (formattedValues is null)
|
||||
resultProgress.Report(ResultEventArgs.Failure(formatResult));
|
||||
@@ -581,7 +581,7 @@ namespace MPF.Frontend
|
||||
var filenameSuffix = _options.AddFilenameSuffix ? Path.GetFileNameWithoutExtension(outputFilename) : null;
|
||||
|
||||
// Write the text output
|
||||
resultProgress.Report(ResultEventArgs.Success("Writing submission information file..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Writing submission information file..."));
|
||||
bool txtSuccess = WriteOutputData(outputDirectory, filenameSuffix, formattedValues, out string txtResult);
|
||||
if (txtSuccess)
|
||||
resultProgress.Report(ResultEventArgs.Success(txtResult));
|
||||
@@ -593,7 +593,7 @@ namespace MPF.Frontend
|
||||
{
|
||||
if (_options.ScanForProtection)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Writing protection information file..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Writing protection information file..."));
|
||||
bool scanSuccess = WriteProtectionData(outputDirectory, filenameSuffix, submissionInfo, _options.HideDriveLetters);
|
||||
if (scanSuccess)
|
||||
resultProgress.Report(ResultEventArgs.Success("Writing complete!"));
|
||||
@@ -605,7 +605,7 @@ namespace MPF.Frontend
|
||||
// Write the JSON output, if required
|
||||
if (_options.OutputSubmissionJSON)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success($"Writing submission information JSON file{(_options.IncludeArtifacts ? " with artifacts" : string.Empty)}..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral($"Writing submission information JSON file{(_options.IncludeArtifacts ? " with artifacts" : string.Empty)}..."));
|
||||
bool jsonSuccess = WriteOutputData(outputDirectory, filenameSuffix, submissionInfo, _options.IncludeArtifacts);
|
||||
if (jsonSuccess)
|
||||
resultProgress.Report(ResultEventArgs.Success("Writing complete!"));
|
||||
@@ -616,7 +616,7 @@ namespace MPF.Frontend
|
||||
// Compress the logs, if required
|
||||
if (_options.CompressLogFiles)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Compressing log files..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Compressing log files..."));
|
||||
#if NET40
|
||||
await Task.Factory.StartNew(() =>
|
||||
#else
|
||||
@@ -636,7 +636,7 @@ namespace MPF.Frontend
|
||||
// Delete unnecessary files, if required
|
||||
if (_options.DeleteUnnecessaryFiles)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Deleting unnecessary files..."));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Deleting unnecessary files..."));
|
||||
bool deleteSuccess = _processor.DeleteUnnecessaryFiles(mediaType, outputDirectory, outputFilename, out string deleteResult);
|
||||
if (deleteSuccess)
|
||||
resultProgress.Report(ResultEventArgs.Success(deleteResult));
|
||||
@@ -647,7 +647,7 @@ namespace MPF.Frontend
|
||||
// Create PS3 IRD, if required
|
||||
if (_options.CreateIRDAfterDumping && _system == RedumpSystem.SonyPlayStation3 && mediaType == MediaType.BluRay)
|
||||
{
|
||||
resultProgress.Report(ResultEventArgs.Success("Creating IRD... please wait!"));
|
||||
resultProgress.Report(ResultEventArgs.Neutral("Creating IRD... please wait!"));
|
||||
bool deleteSuccess = await IRDTool.WriteIRD(OutputPath, submissionInfo?.Extras?.DiscKey, submissionInfo?.Extras?.DiscID, submissionInfo?.Extras?.PIC, submissionInfo?.SizeAndChecksums.Layerbreak, submissionInfo?.SizeAndChecksums.CRC32);
|
||||
if (deleteSuccess)
|
||||
resultProgress.Report(ResultEventArgs.Success("IRD created!"));
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace MPF.Frontend
|
||||
/// </summary>
|
||||
public enum LogLevel
|
||||
{
|
||||
USER,
|
||||
USER_GENERIC,
|
||||
USER_SUCCESS,
|
||||
VERBOSE,
|
||||
ERROR,
|
||||
SECRET,
|
||||
|
||||
@@ -10,19 +10,30 @@ namespace MPF.Frontend
|
||||
/// <summary>
|
||||
/// Internal representation of success
|
||||
/// </summary>
|
||||
private readonly bool _success;
|
||||
private readonly bool? _success;
|
||||
|
||||
/// <summary>
|
||||
/// Optional message for the result
|
||||
/// </summary>
|
||||
public string Message { get; }
|
||||
|
||||
private ResultEventArgs(bool success, string message)
|
||||
private ResultEventArgs(bool? success, string message)
|
||||
{
|
||||
_success = success;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a default neutral result with no message
|
||||
/// </summary>
|
||||
public static ResultEventArgs Neutral() => new(null, string.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Create a neutral result with a custom message
|
||||
/// </summary>
|
||||
/// <param name="message">String to add as a message</param>
|
||||
public static ResultEventArgs Neutral(string? message) => new(null, message ?? string.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Create a default success result with no message
|
||||
/// </summary>
|
||||
@@ -49,7 +60,7 @@ namespace MPF.Frontend
|
||||
/// <summary>
|
||||
/// Results can be compared to boolean values based on the success value
|
||||
/// </summary>
|
||||
public static implicit operator bool(ResultEventArgs result) => result._success;
|
||||
public static implicit operator bool?(ResultEventArgs result) => result._success;
|
||||
|
||||
/// <summary>
|
||||
/// Results can be compared to boolean values based on the success value
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace MPF.Frontend.Tools
|
||||
// Run anti-modchip check, if necessary
|
||||
if (drive is not null && system.SupportsAntiModchipScans() && info.CopyProtection.AntiModchip == YesNo.NULL)
|
||||
{
|
||||
resultProgress?.Report(ResultEventArgs.Success("Checking for anti-modchip strings... this might take a while!"));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral("Checking for anti-modchip strings... this might take a while!"));
|
||||
info.CopyProtection.AntiModchip = await ProtectionTool.GetPlayStationAntiModchipDetected(drive?.Name) ? YesNo.Yes : YesNo.No;
|
||||
resultProgress?.Report(ResultEventArgs.Success("Anti-modchip string scan complete!"));
|
||||
}
|
||||
@@ -129,7 +129,7 @@ namespace MPF.Frontend.Tools
|
||||
// Run copy protection, if possible or necessary
|
||||
if (system.SupportsCopyProtectionScans())
|
||||
{
|
||||
resultProgress?.Report(ResultEventArgs.Success("Running copy protection scan... this might take a while!"));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral("Running copy protection scan... this might take a while!"));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -210,7 +210,7 @@ namespace MPF.Frontend.Tools
|
||||
List<int[]> foundIdSets = [];
|
||||
|
||||
// Loop through all of the hashdata to find matching IDs
|
||||
resultProgress?.Report(ResultEventArgs.Success("Finding disc matches on Redump..."));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral("Finding disc matches on Redump..."));
|
||||
var splitData = info.TracksAndWriteOffsets.ClrMameProData?.TrimEnd('\n')?.Split('\n');
|
||||
int trackCount = splitData?.Length ?? 0;
|
||||
foreach (string hashData in splitData ?? [])
|
||||
@@ -219,7 +219,7 @@ namespace MPF.Frontend.Tools
|
||||
if (string.IsNullOrEmpty(hashData))
|
||||
{
|
||||
trackCount--;
|
||||
resultProgress?.Report(ResultEventArgs.Success("Blank line found, skipping!"));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral("Blank line found, skipping!"));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace MPF.Frontend.Tools
|
||||
|| hashData.Contains("(Track AA.5).bin"))
|
||||
{
|
||||
trackCount--;
|
||||
resultProgress?.Report(ResultEventArgs.Success("Extra track found, skipping!"));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral("Extra track found, skipping!"));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace MPF.Frontend.Tools
|
||||
continue;
|
||||
|
||||
// Fill in the fields from the existing ID
|
||||
resultProgress?.Report(ResultEventArgs.Success($"Filling fields from existing ID {fullyMatchedIdsList[i]}..."));
|
||||
resultProgress?.Report(ResultEventArgs.Neutral($"Filling fields from existing ID {fullyMatchedIdsList[i]}..."));
|
||||
_ = await Builder.FillFromId(wc, info, fullyMatchedIdsList[i], options.PullAllInformation);
|
||||
resultProgress?.Report(ResultEventArgs.Success("Information filling complete!"));
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
#if !(NET20 || NET35 || NET40)
|
||||
using System;
|
||||
#endif
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
|
||||
@@ -1121,7 +1121,7 @@ namespace MPF.Frontend.ViewModels
|
||||
/// <param name="text">Text to write to the log</param>
|
||||
private void Log(string text)
|
||||
{
|
||||
_logger?.Invoke(LogLevel.USER, text);
|
||||
_logger?.Invoke(LogLevel.USER_GENERIC, text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1160,6 +1160,21 @@ namespace MPF.Frontend.ViewModels
|
||||
/// <param name="text">Text to write to the log</param>
|
||||
private void SecretLogLn(string text) => SecretLog(text + "\n");
|
||||
|
||||
/// <summary>
|
||||
/// Enqueue success text to the log
|
||||
/// </summary>
|
||||
/// <param name="text">Text to write to the log</param>
|
||||
private void SuccessLog(string text)
|
||||
{
|
||||
_logger?.Invoke(LogLevel.USER_SUCCESS, text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enqueue text with a newline to the log
|
||||
/// </summary>
|
||||
/// <param name="text">Text to write to the log</param>
|
||||
private void SuccessLogLn(string text) => SuccessLog(text + "\n");
|
||||
|
||||
/// <summary>
|
||||
/// Enqueue verbose text to the log
|
||||
/// </summary>
|
||||
@@ -1360,7 +1375,7 @@ namespace MPF.Frontend.ViewModels
|
||||
Status = result.Message;
|
||||
|
||||
// Enable or disable the button
|
||||
StartStopButtonEnabled = result && ShouldEnableDumpingButton();
|
||||
StartStopButtonEnabled = result == true && ShouldEnableDumpingButton();
|
||||
|
||||
// If we're in a type that doesn't support drive speeds
|
||||
DriveSpeedComboBoxEnabled = DumpEnvironment.DoesSupportDriveSpeed(CurrentMediaType);
|
||||
@@ -2231,7 +2246,7 @@ namespace MPF.Frontend.ViewModels
|
||||
// If we didn't execute a dumping command we cannot get submission output
|
||||
if (!_environment.IsDumpingCommand())
|
||||
{
|
||||
LogLn("No dumping command was run, submission information will not be gathered.");
|
||||
SuccessLogLn("No dumping command was run, submission information will not be gathered.");
|
||||
Status = "Execution complete!";
|
||||
|
||||
// Re-allow quick exiting
|
||||
@@ -2243,14 +2258,14 @@ namespace MPF.Frontend.ViewModels
|
||||
}
|
||||
|
||||
// Verify dump output and save it
|
||||
if (result)
|
||||
if (result == true)
|
||||
{
|
||||
result = await _environment.VerifyAndSaveDumpOutput(
|
||||
resultProgress: resultProgress,
|
||||
protectionProgress: protectionProgress,
|
||||
processUserInfo: _processUserInfo);
|
||||
|
||||
if (!result)
|
||||
if (result == false)
|
||||
ErrorLogLn(result.Message);
|
||||
}
|
||||
else
|
||||
@@ -2507,7 +2522,7 @@ namespace MPF.Frontend.ViewModels
|
||||
/// </summary>
|
||||
private void ProgressUpdated(object? sender, ResultEventArgs value)
|
||||
{
|
||||
var message = value?.Message;
|
||||
var message = value.Message;
|
||||
|
||||
// Update the label with only the first line of output
|
||||
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
||||
@@ -2520,9 +2535,11 @@ namespace MPF.Frontend.ViewModels
|
||||
Status = message ?? string.Empty;
|
||||
|
||||
// Log based on success or failure
|
||||
if (value is not null && value)
|
||||
VerboseLogLn(message ?? string.Empty);
|
||||
else if (value is not null && !value)
|
||||
if ((bool?)value is null)
|
||||
LogLn(message ?? string.Empty);
|
||||
else if (value == true)
|
||||
SuccessLogLn(message ?? string.Empty);
|
||||
else if (value == false)
|
||||
ErrorLogLn(message ?? string.Empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,15 +109,17 @@ namespace MPF.UI.UserControls
|
||||
/// <returns>Brush representing the color</returns>
|
||||
public Brush GetForegroundColor()
|
||||
{
|
||||
#pragma warning disable IDE0072
|
||||
return LogLevel switch
|
||||
{
|
||||
LogLevel.SECRET => Brushes.DarkGray,
|
||||
LogLevel.ERROR => Brushes.Red,
|
||||
LogLevel.VERBOSE => Brushes.Yellow,
|
||||
_ => Brushes.White,
|
||||
LogLevel.USER_SUCCESS => Brushes.ForestGreen,
|
||||
LogLevel.USER_GENERIC => Brushes.White,
|
||||
|
||||
// Make unmatched log levels obvious
|
||||
_ => Brushes.Pink,
|
||||
};
|
||||
#pragma warning restore IDE0072
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace MPF.UI.Windows
|
||||
private async void OnCheckDumpClick(object sender, EventArgs e)
|
||||
{
|
||||
var result = await CheckDumpViewModel.CheckDump(ShowMediaInformationWindow);
|
||||
if (result)
|
||||
if (result == true)
|
||||
{
|
||||
bool? checkAgain = DisplayUserMessage("Check Complete", "The dump has been processed successfully! Would you like to check another dump?", 2, false);
|
||||
if (checkAgain == false)
|
||||
|
||||
Reference in New Issue
Block a user