Files
QuestPDF/QuestPDF/Previewer/PreviewerService.cs
T
2022-03-31 23:11:34 +02:00

141 lines
4.2 KiB
C#

#if NET6_0_OR_GREATER
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using QuestPDF.Drawing;
namespace QuestPDF.Previewer
{
internal class PreviewerService
{
private HttpClient HttpClient { get; init; }
public PreviewerService(int port)
{
HttpClient = new()
{
BaseAddress = new Uri($"http://localhost:{port}/"),
Timeout = TimeSpan.FromMilliseconds(250)
};
}
public async Task Connect()
{
var isAvailable = await IsPreviewerAvailable();
if (!isAvailable)
{
StartPreviewer();
await WaitForConnection();
}
var previewerVersion = await GetPreviewerVersion();
CheckVersionCompatibility(previewerVersion);
}
private async Task<bool> IsPreviewerAvailable()
{
try
{
var result = await HttpClient.GetAsync("/ping");
return result.IsSuccessStatusCode;
}
catch
{
return false;
}
}
private async Task<Version> GetPreviewerVersion()
{
var result = await HttpClient.GetAsync("/version");
return await result.Content.ReadFromJsonAsync<Version>();
}
private static void StartPreviewer()
{
try
{
var process = new Process
{
StartInfo = new()
{
UseShellExecute = false,
FileName = "questpdf-previewer",
CreateNoWindow = true
}
};
process.Start();
}
catch
{
throw new Exception("Cannot start the QuestPDF Previewer tool. " +
"Please install it by executing in terminal the following command: 'dotnet tool install --global QuestPDF.Previewer'.");
}
}
private void CheckVersionCompatibility(Version version)
{
if (version.Major == 2022 && version.Minor == 4)
return;
throw new Exception($"Previewer version is not compatible. Possible solutions: " +
$"1) Update the QuestPDF library to newer version. " +
$"2) Update the QuestPDF previewer tool using the following command: 'dotnet tool update --global QuestPDF.Previewer --version 2022.4'");
}
private async Task WaitForConnection()
{
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(1));
var isConnected = await IsPreviewerAvailable();
if (isConnected)
break;
}
}
public async Task RefreshPreview(ICollection<PreviewerPicture> pictures)
{
var multipartContent = new MultipartFormDataContent();
var pages = new List<PreviewerRefreshCommand.Page>();
foreach (var picture in pictures)
{
var page = new PreviewerRefreshCommand.Page
{
Width = picture.Size.Width,
Height = picture.Size.Height
};
pages.Add(page);
var pictureStream = picture.Picture.Serialize().AsStream();
multipartContent.Add(new StreamContent(pictureStream), page.Id, page.Id);
}
var command = new PreviewerRefreshCommand
{
Pages = pages
};
multipartContent.Add(JsonContent.Create(command), "command");
await HttpClient.PostAsync("/update/preview", multipartContent);
foreach (var picture in pictures)
picture.Picture.Dispose();
}
}
}
#endif