Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static IHostBuilder CreateHostBuilder(string[] args) =>
config.AddJsonFile("appsettings.json", optional: false);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
config.AddJsonFile("appSettings.linux.json", optional: false);
config.AddJsonFile("appsettings.linux.json", optional: false);
Comment thread
ociaw marked this conversation as resolved.
}
})
.ConfigureLogging(logging =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
namespace MakeMkv;

/// <summary>
/// Iterates over comma separated values in a single line of text.
/// </summary>
public sealed class CsvEnumerator
{
private readonly String _span;

private readonly Boolean _isInitialized;

private Int32 _currentStart;
private Int32 _currentEnd;

/// <inheritdoc cref="IEnumerator{T}.Current" />
public ReadOnlySpan<Char> Current => _span.AsSpan()[_currentStart.._currentEnd];

/// <summary>
/// Creates a new <see cref="CsvEnumerator"/> over a span of characters.
/// </summary>
public CsvEnumerator(String span)
{
_isInitialized = true;
_span = span;
_currentStart = 0;
_currentEnd = -1;
}

/// <inheritdoc cref="IEnumerator{T}.MoveNext" />
public Boolean MoveNext()
{
Int32 start = _currentEnd + 1;
if (!_isInitialized || start > _span.Length)
{
return false;
}

var slice = _span[start..];
_currentStart = start;

Boolean quoted = false;
Boolean escaped = false;
Int32 i;
for (i = 0; i < slice.Length; i++)
{
Char curChar = slice[i];
if (curChar == '\\')
{
if (!escaped)
{
escaped = true;
continue;
}
}
else if (curChar == '"')
{
if (!escaped)
{
quoted = !quoted;
}
}
else if (curChar == ',')
{
if (!quoted)
{
break;
}
}

escaped = false;
}

Int32 elementLength = i;

_currentEnd = _currentStart + elementLength;
return true;
}

/// <summary>
/// Returns an enumerator suitable for use in foreach loops.
/// </summary>
public CsvEnumerator GetEnumerator() => this;

/// <summary>
/// Attempts to advance the enumerator and parse the value as an <see cref="int"/>.
/// </summary>
/// <returns>The parsed value, or the <see langword="default"/> value if enumeration or parsing failed.</returns>
public int TryParseInt()
{
if (MoveNext())
{
if (Int32.TryParse(Current, out int val))
{
return val;
}
}

return default;
}

/// <summary>
/// Attempts to advance the enumerator and parse the value as a <see cref="bool"/>.
/// </summary>
/// <returns>The parsed value, or <see langword="false"/> if enumeration or parsing failed.</returns>
public bool TryParseBoolean()
{
if (MoveNext())
{
if (Int32.TryParse(Current, out int val))
{
return val != 256 && val != 999 && val > 0;
}
}

return default;
}

/// <summary>
/// Attempts to advance the enumerator and parse the value as a <see cref="long"/>.
/// </summary>
/// <returns>The parsed value, or <see langword="null"/> if enumeration or parsing failed.</returns>
public string? GetString()
{
if (MoveNext())
{
return Current.ToString().Replace("\"", string.Empty);
}

return default;
}

/// <summary>
/// Attempts to advance the enumerator and parse the value as a <see cref="DateTime"/>.
/// </summary>
/// <returns>The parsed value, or the <see langword="default"/> value if enumeration or parsing failed.</returns>
public DateTime TryParseDateTime()
{
if (MoveNext())
{
if (DateTime.TryParse(Current, out DateTime val))
{
return val;
}
}

return default;
}

/// <summary>
/// Attempts to advance the enumerator and parse the value as a <see cref="long"/>.
/// </summary>
/// <returns>The parsed value, or the <see langword="default"/> value if enumeration or parsing failed.</returns>
public long TryParseLong()
{
if (MoveNext())
{
if (Int64.TryParse(Current, out long val))
{
return val;
}
}

return default;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ protected static int TryParseInt(int index, string[] parts)
{
if (index < parts.Length)
{
if(Int32.TryParse(parts[index], out int val))
if (Int32.TryParse(parts[index], out int val))
{
return val;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,21 @@ public MessageLogLine() : base("MSG")

public static MessageLogLine Parse(string line)
{
string[] parts = line.Substring(4).Split(',');
var enumerator = new CsvEnumerator(line[4..]);

var result = new MessageLogLine
{
Code = GetString(0, parts),
Flags = GetString(1, parts),
ParamCount = TryParseInt(2, parts),
Message = GetString(3, parts),
MessageTemplate = GetString(4, parts),
Code = enumerator.GetString(),
Flags = enumerator.GetString(),
ParamCount = enumerator.TryParseInt(),
Message = enumerator.GetString(),
MessageTemplate = enumerator.GetString(),
OriginalLine = line
};

for (int i = 5; i < parts.Length; i++)
while (enumerator.GetString() is { } val)
{
string? val = GetString(i, parts);
if (val != null)
{
result.Params.Add(val);
}
result.Params.Add(val);
}

return result;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace TheDiscDb.Tools.MakeMkv
using MakeMkv;

namespace TheDiscDb.Tools.MakeMkv
{
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -42,7 +44,7 @@ public async Task WriteLogs(int driveIndex, string path, bool cleanLogs = true)
await Task.Delay(200); // wait for file handle to be released
try
{
await CleanLogs(path);
await CleanLogs(driveIndex, path);
}
catch (IOException e)
{
Expand All @@ -51,19 +53,77 @@ public async Task WriteLogs(int driveIndex, string path, bool cleanLogs = true)
}
}

public async Task CleanLogs(string path, CancellationToken cancellationToken = default)
public async Task CleanLogs(int driveIndex, string path, CancellationToken cancellationToken = default)
{
var output = new List<string>();
var lines = await this.fileSystem.File.ReadAllLines(path, cancellationToken);
bool fileChanged = false;
foreach (var line in lines)
foreach (var originalLine in lines)
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("MSG") || line.StartsWith("DRV"))
// Remove empty lines from the output
if (originalLine == string.Empty)
{
fileChanged = true;
continue;
}

string? line = null;
if (originalLine.StartsWith("MSG"))
{
var msgLine = MessageLogLine.Parse(originalLine);
var (toRedact, replacement) = msgLine.Code switch
{
// The debug file path is usually in the user's home directory
"1004" => (msgLine.Params[0], "***"),
// The drive name can sometimes contain a serial number
"2003" => (msgLine.Params[1], "***"),
// The .MakeMKV folder is usually in the user's home directory
"3338" => (msgLine.Params[1], "***"),
// No other messages are known to contain sensitive information
_ => (null, ""),
};

if (toRedact is not null)
{
line = originalLine.Replace(toRedact, replacement);
}
}
else if (originalLine.StartsWith("DRV"))
{
// DRV:1,2,999,12,"BD-ROM HL-DT-ST BDDVDRW UH12NS30 1.03","42","E:"
// becomes
// DRV:1,2,999,12,"redacted by ImportBuddy","42","/redacted/by/ImportBuddy"
var driveLine = DriveScanLogLine.Parse(originalLine);
if (!string.IsNullOrEmpty(driveLine.DriveName))
{
// Always redact the drive name, since it could contain a serial number
line = originalLine.Replace(driveLine.DriveName, "***");

// Only keep the disc name for the active drive
if (driveLine.Index != driveIndex && !string.IsNullOrEmpty(driveLine.DiscName))
{
line = line.Replace(driveLine.DiscName, "***");
}

// Always redact the drive letter or path
if (!string.IsNullOrEmpty(driveLine.DriveLetter))
{
line = line.Replace(driveLine.DriveLetter, "***");
}
}
}

if (line is null)
{
// This line wasn't modified, use the original line
line = originalLine;
}
else
{
// Something was changed, ensure the file is overwritten
fileChanged = true;
Comment thread
lfoust marked this conversation as resolved.
}

output.Add(line);
}

Expand Down