streaming rar support

This commit is contained in:
13xforever 2019-08-16 00:01:29 +05:00
parent 373a3d1800
commit d04e817ebf

View File

@ -4,8 +4,9 @@ using System.IO.Pipelines;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CompatApiClient.Utils; using CompatBot.Utils;
using SharpCompress.Archives.Rar; using SharpCompress.Archives.Rar;
using SharpCompress.Readers.Rar;
namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers
{ {
@ -21,9 +22,6 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers
if (header.Length >= Header.Length && header.Slice(0, Header.Length).SequenceEqual(Header) if (header.Length >= Header.Length && header.Slice(0, Header.Length).SequenceEqual(Header)
|| fileName.EndsWith(".rar", StringComparison.InvariantCultureIgnoreCase)) || fileName.EndsWith(".rar", StringComparison.InvariantCultureIgnoreCase))
{ {
if (fileSize > Config.AttachmentSizeLimit)
return (false, $"Log size is too large: {fileSize.AsStorageUnit()} (max allowed is {Config.AttachmentSizeLimit.AsStorageUnit()})");
var firstEntry = Encoding.ASCII.GetString(header); var firstEntry = Encoding.ASCII.GetString(header);
if (!firstEntry.Contains(".log", StringComparison.InvariantCultureIgnoreCase)) if (!firstEntry.Contains(".log", StringComparison.InvariantCultureIgnoreCase))
return (false, "Archive doesn't contain any logs."); return (false, "Archive doesn't contain any logs.");
@ -38,35 +36,32 @@ namespace CompatBot.EventHandlers.LogParsing.ArchiveHandlers
{ {
try try
{ {
using (var fileStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 16384, FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose)) using (var statsStream = new BufferCopyStream(sourceStream))
{ using (var rarReader = RarReader.Open(statsStream))
await sourceStream.CopyToAsync(fileStream, 16384, cancellationToken).ConfigureAwait(false); while (rarReader.MoveToNextEntry())
fileStream.Seek(0, SeekOrigin.Begin); if (!rarReader.Entry.IsDirectory
using (var rarArchive = RarArchive.Open(fileStream)) && rarReader.Entry.Key.EndsWith(".log", StringComparison.InvariantCultureIgnoreCase)
using (var rarReader = rarArchive.ExtractAllEntries()) && !rarReader.Entry.Key.Contains("tty.log", StringComparison.InvariantCultureIgnoreCase))
while (rarReader.MoveToNextEntry()) {
if (!rarReader.Entry.IsDirectory LogSize = rarReader.Entry.Size;
&& rarReader.Entry.Key.EndsWith(".log", StringComparison.InvariantCultureIgnoreCase) using (var rarStream = rarReader.OpenEntryStream())
&& !rarReader.Entry.Key.Contains("tty.log", StringComparison.InvariantCultureIgnoreCase))
{ {
LogSize = rarReader.Entry.Size; int read;
using (var rarStream = rarReader.OpenEntryStream()) FlushResult flushed;
do
{ {
int read; var memory = writer.GetMemory(Config.MinimumBufferSize);
FlushResult flushed; read = await rarStream.ReadAsync(memory, cancellationToken);
do writer.Advance(read);
{ SourcePosition = statsStream.Position;
var memory = writer.GetMemory(Config.MinimumBufferSize); flushed = await writer.FlushAsync(cancellationToken).ConfigureAwait(false);
read = await rarStream.ReadAsync(memory, cancellationToken); SourcePosition = statsStream.Position;
writer.Advance(read); } while (read > 0 && !(flushed.IsCompleted || flushed.IsCanceled || cancellationToken.IsCancellationRequested));
flushed = await writer.FlushAsync(cancellationToken).ConfigureAwait(false);
} while (read > 0 && !(flushed.IsCompleted || flushed.IsCanceled || cancellationToken.IsCancellationRequested));
}
writer.Complete();
return;
} }
Config.Log.Warn("No rar entries that match the log criteria"); writer.Complete();
} return;
}
Config.Log.Warn("No rar entries that match the log criteria");
} }
catch (Exception e) catch (Exception e)
{ {