Browse Source

update

pull/22922/head
SALİH ÖZKARA 1 year ago
parent
commit
42edab3381
  1. 1
      Directory.Packages.props
  2. 9
      modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
  3. 0
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/BackgroundJobs/DocumentPdfGenerateJob.cs
  4. 1
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/BackgroundJobs/DocumentPdfGenerateJobArgs.cs
  5. 3
      modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfAppService.cs
  6. 1
      modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj
  7. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/DocsProjectPdfGeneratorOptions.cs
  8. 4
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IHtmlToPdfRenderer.cs
  9. 6
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IText/ITextHtmlToPdfRenderer.cs
  10. 54
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/ProjectPdfGenerator.cs
  11. 38
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/Puppeteer/PuppeteerHtmlToPdfRenderer.cs

1
Directory.Packages.props

@ -113,6 +113,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="PuppeteerSharp" Version="20.1.3" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.12.0" />
<PackageVersion Include="Microsoft.IdentityModel.Tokens" Version="8.12.0" />

9
modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs

@ -32,6 +32,7 @@ using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Volo.Abp.Account;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.BlobStoring;
using Volo.Abp.BlobStoring.Database;
using Volo.Abp.PermissionManagement.HttpApi;
@ -62,7 +63,8 @@ namespace VoloDocs.Web
typeof(AbpPermissionManagementApplicationModule),
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule)
,typeof(AbpCachingStackExchangeRedisModule)
,typeof(AbpCachingStackExchangeRedisModule),
typeof(AbpBackgroundJobsModule)
)]
public class VoloDocsWebModule : AbpModule
{
@ -72,6 +74,11 @@ namespace VoloDocs.Web
{
options.AddAssemblyResource(typeof(DocsResource), typeof(VoloDocsWebModule).Assembly);
});
PreConfigure<AbpBackgroundJobWorkerOptions>(options =>
{
options.ApplicationName = context.Services.GetApplicationName()!;
});
}
public override void ConfigureServices(ServiceConfigurationContext context)

0
modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJob.cs → modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/BackgroundJobs/DocumentPdfGenerateJob.cs

1
modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJobArgs.cs → modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/BackgroundJobs/DocumentPdfGenerateJobArgs.cs

@ -1,4 +1,5 @@
using System;
using Volo.Abp.BackgroundJobs;
namespace Volo.Docs.Admin.BackgroundJobs;

3
modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfAppService.cs

@ -2,6 +2,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp.Content;
using Volo.Abp.Http;
using Volo.Docs.Projects;
using Volo.Docs.Projects.Pdf;
@ -37,7 +38,7 @@ public class DocumentPdfAppService : DocsCommonAppServiceBase, IDocumentPdfAppSe
if (fileStream != null)
{
return new RemoteStreamContent(fileStream, fileName, "application/pdf");
return new RemoteStreamContent(fileStream, fileName, MimeTypes.Application.Zip);
}
return null;

1
modules/docs/src/Volo.Docs.Domain/Volo.Docs.Domain.csproj

@ -25,6 +25,7 @@
<PackageReference Include="itext7" />
<PackageReference Include="itext7.pdfhtml" />
<PackageReference Include="Markdig.Signed" />
<PackageReference Include="PuppeteerSharp" />
</ItemGroup>
<ItemGroup>

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/DocsProjectPdfGeneratorOptions.cs

@ -30,7 +30,7 @@ public class DocsProjectPdfGeneratorOptions
/// <summary>
/// The function to calculate the PDF file name.
/// Default is "{project.ShortName}-{version}-{languageCode}.pdf".
/// Default is "{project.ShortName}-{version}-{languageCode}.zip".
/// </summary>
public Func<Project, string, string, string> CalculatePdfFileName { get; set; }
@ -108,6 +108,6 @@ public class DocsProjectPdfGeneratorOptions
width: 100%;
}";
CalculatePdfFileName = (project, version, languageCode) => $"{project.ShortName}-{version}-{languageCode}.pdf";
CalculatePdfFileName = (project, version, languageCode) => $"{project.ShortName}-{version}-{languageCode}.zip";
}
}

4
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IHtmlToPdfRenderer.cs

@ -6,7 +6,5 @@ namespace Volo.Docs.Projects.Pdf;
public interface IHtmlToPdfRenderer
{
Task<MemoryStream> RenderAsync(string title, string html, List<PdfDocument> documents);
Task<MemoryStream> MergePdfFilesAsync(List<MemoryStream> pdfFiles, string title, bool disposeStreams = true);
Task<Stream> RenderAsync(string title, string html, List<PdfDocument> documents);
}

6
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IText/ITextHtmlToPdfRenderer.cs

@ -12,7 +12,7 @@ using ITextDocument = iText.Layout.Document;
namespace Volo.Docs.Projects.Pdf.IText;
public class ITextHtmlToPdfRenderer : IHtmlToPdfRenderer ,ITransientDependency
public class ITextHtmlToPdfRenderer : IHtmlToPdfRenderer
{
protected IOptions<DocsProjectPdfGeneratorOptions> Options { get; }
@ -21,7 +21,7 @@ public class ITextHtmlToPdfRenderer : IHtmlToPdfRenderer ,ITransientDependency
Options = options;
}
public virtual Task<MemoryStream> RenderAsync(string title, string html, List<PdfDocument> documents)
public virtual Task<Stream> RenderAsync(string title, string html, List<PdfDocument> documents)
{
var pdfStream = new MemoryStream();
var pdfWrite = new PdfWriter(pdfStream);
@ -42,7 +42,7 @@ public class ITextHtmlToPdfRenderer : IHtmlToPdfRenderer ,ITransientDependency
textDocument.Close();
pdfStream.Position = 0;
return Task.FromResult(pdfStream);
return Task.FromResult<Stream>(pdfStream);
}
public virtual async Task<MemoryStream> MergePdfFilesAsync(List<MemoryStream> pdfFiles, string title, bool disposeStreams = true)

54
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/ProjectPdfGenerator.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -31,7 +32,7 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
protected Project Project { get; set; }
protected List<PdfDocument> AllPdfDocuments { get; } = [];
protected int ChunkSize { get; set; } = 10;
protected int ChunkSize { get; set; } = 60;
public ProjectPdfGenerator(
IDocumentSourceFactory documentStoreFactory,
@ -63,7 +64,7 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
await SetAllPdfDocumentsAsync(navigation.Items, project, version, languageCode);
var title = Options.Value.CalculatePdfFileTitle?.Invoke(project) ?? project.Name;
var tempStreams = new List<MemoryStream>();
var tempStreams = new List<Stream>();
try
{
@ -72,21 +73,28 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
foreach (var (chunk, index) in documentChunks.Select((chunk, index) => (chunk, index)))
{
try
{
Logger.LogInformation("Processing chunk {Index}/{Total}", index + 1, documentChunks.Count);
Logger.LogInformation("Processing chunk {Index}/{Total}", index + 1, documentChunks.Count);
var chunkHtml = await BuildHtmlAsync(chunk);
var chunkHtml = await BuildHtmlAsync(chunk);
var pdfStream = await HtmlToPdfRenderer.RenderAsync($"{title} - Part {index + 1}", chunkHtml, chunk);
var pdfStream = await HtmlToPdfRenderer.RenderAsync($"{title} - Part {index + 1}", chunkHtml, chunk);
Logger.LogInformation("Chunk {Index} rendered to PDF", index + 1);
Logger.LogInformation("Chunk {Index} rendered to PDF", index + 1);
tempStreams.Add(pdfStream);
tempStreams.Add(pdfStream);
}
catch (Exception e)
{
Logger.LogError(e, "Error processing chunk {Index} for project {ProjectName}", index + 1, project.Name);
}
}
Logger.LogInformation("All chunks processed, merging PDF files");
using var mergedPdfStream = await MergePdfFilesAsync(tempStreams, title, disposeStreams: true);
var mergedPdfStream = await MergePdfFilesAsync(tempStreams, title, disposeStreams: true);
await ProjectPdfFileStore.SetAsync(project, version, languageCode, mergedPdfStream);
}
catch(Exception e)
@ -174,15 +182,41 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
return contentBuilder.ToString();
}
protected virtual async Task<MemoryStream> MergePdfFilesAsync(List<MemoryStream> pdfFiles, string title, bool disposeStreams = true)
protected virtual async Task<MemoryStream> MergePdfFilesAsync(List<Stream> pdfFiles, string title, bool disposeStreams = true)
{
if (pdfFiles.Count == 0)
{
throw new ArgumentException("No PDF files to merge", nameof(pdfFiles));
}
return await HtmlToPdfRenderer.MergePdfFilesAsync(pdfFiles, title, disposeStreams);
var zipStream = new MemoryStream();
{
using var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true);
var index = 0;
foreach (var pdfFile in pdfFiles)
{
if (pdfFile.CanSeek)
pdfFile.Position = 0;
var entry = zipArchive.CreateEntry($"{title}_{index}.pdf", CompressionLevel.Fastest);
await using var entryStream = entry.Open();
await pdfFile.CopyToAsync(entryStream);
if (disposeStreams)
{
await pdfFile.DisposeAsync();
}
index++;
}
}
zipStream.Position = 0;
return zipStream;
}
protected virtual IDocumentToHtmlConverter<PdfDocumentToHtmlConverterContext> GetDocumentToHtmlConverter(Project project, PdfDocument pdfDocument)
{

38
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/Puppeteer/PuppeteerHtmlToPdfRenderer.cs

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using PuppeteerSharp;
using PuppeteerSharp.Media;
using Volo.Abp.DependencyInjection;
namespace Volo.Docs.Projects.Pdf.Puppeteer;
public class PuppeteerHtmlToPdfRenderer : IHtmlToPdfRenderer, ITransientDependency
{
public async Task<Stream> RenderAsync(string title, string html, List<PdfDocument> documents)
{
await new BrowserFetcher()
{
Browser = SupportedBrowser.Chromium
}.DownloadAsync();
await using var browser = await PuppeteerSharp.Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, Timeout = 600000, Browser = SupportedBrowser.Chromium });
await using var page = await browser.NewPageAsync();
await page.SetContentAsync(html, new NavigationOptions
{
Timeout = 600000,
});
var pdfOptions = new PdfOptions
{
Format = PaperFormat.A4,
MarginOptions = new MarginOptions { Top = "20mm", Bottom = "20mm", Left = "15mm", Right = "15mm" },
};
var stream = await page.PdfStreamAsync(pdfOptions);
await page.CloseAsync();
await browser.CloseAsync();
return stream;
}
}
Loading…
Cancel
Save