Fixed Docker not being able to parse PDF Images (#418)

* Fixed an issue with downloading pdf files

* Bumped sentry version to latest

* Refactored PDF Page to image extraction to a private method. Bumped Sentry version in backend.

* Fixed issue with PDFs not being parsable (image) within Docker due to libgdiplus not being installed.
This commit is contained in:
Joseph Milazzo 2021-07-23 10:35:26 -05:00 committed by GitHub
parent b0df67cdda
commit 199ab7946c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 139 deletions

View File

@ -48,12 +48,12 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.4" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.0.0" />
<PackageReference Include="NetVips" Version="2.0.0" />
<PackageReference Include="NetVips.Native" Version="8.10.6" />
<PackageReference Include="NetVips" Version="2.0.1" />
<PackageReference Include="NetVips.Native" Version="8.11.0" />
<PackageReference Include="NReco.Logging.File" Version="1.1.1" />
<PackageReference Include="Sentry.AspNetCore" Version="3.7.0" />
<PackageReference Include="Sentry.AspNetCore" Version="3.8.2" />
<PackageReference Include="SharpCompress" Version="0.28.3" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.25.0.33663">
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.26.0.34506">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -85,6 +85,7 @@ namespace API.Controllers
".epub" => "application/epub+zip",
".7z" => "application/x-7z-compressed",
".7zip" => "application/x-7z-compressed",
".pdf" => "application/pdf",
_ => contentType
};
}

View File

@ -14,6 +14,7 @@ using API.Interfaces.Services;
using API.Parser;
using Docnet.Core;
using Docnet.Core.Models;
using Docnet.Core.Readers;
using ExCSS;
using HtmlAgilityPack;
using Microsoft.Extensions.Logging;
@ -375,22 +376,7 @@ namespace API.Services
for (var pageNumber = 0; pageNumber < pages; pageNumber++)
{
using var pageReader = docReader.GetPageReader(pageNumber);
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
using var doc = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
AddBytesToBitmap(bmp, rawBytes);
for (int y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(bmp.Width - 1, y, bmp.GetPixel(bmp.Width - 2, y));
}
var g = Graphics.FromImage(doc);
g.FillRegion(Brushes.White, new Region(new Rectangle(0, 0, width, height)));
g.DrawImage(bmp, new Point(0, 0));
g.Save();
using var stream = new MemoryStream();
doc.Save(stream, ImageFormat.Jpeg);
using var stream = GetPdfPage(docReader, pageNumber);
File.WriteAllBytes(Path.Combine(targetDirectory, "Page-" + pageNumber + ".png"), stream.ToArray());
}
}
@ -417,15 +403,12 @@ namespace API.Services
if (coverImageContent == null) return Array.Empty<byte>();
if (createThumbnail)
{
using var stream = new MemoryStream(coverImageContent.ReadContent());
if (!createThumbnail) return coverImageContent.ReadContent();
using var thumbnail = Image.ThumbnailStream(stream, MetadataService.ThumbnailWidth);
return thumbnail.WriteToBuffer(".jpg");
}
using var stream = new MemoryStream(coverImageContent.ReadContent());
using var thumbnail = Image.ThumbnailStream(stream, MetadataService.ThumbnailWidth);
return thumbnail.WriteToBuffer(".jpg");
return coverImageContent.ReadContent();
}
catch (Exception ex)
{
@ -442,32 +425,14 @@ namespace API.Services
using var docReader = DocLib.Instance.GetDocReader(fileFilePath, new PageDimensions(1080, 1920));
if (docReader.GetPageCount() == 0) return Array.Empty<byte>();
using var pageReader = docReader.GetPageReader(0);
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
using var doc = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
AddBytesToBitmap(bmp, rawBytes);
for (int y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(bmp.Width - 1, y, bmp.GetPixel(bmp.Width - 2, y));
}
var g = Graphics.FromImage(doc);
g.FillRegion(Brushes.White, new Region(new Rectangle(0, 0, width, height)));
g.DrawImage(bmp, new Point(0, 0));
g.Save();
using var stream = new MemoryStream();
doc.Save(stream, ImageFormat.Jpeg);
using var stream = GetPdfPage(docReader, 0);
stream.Seek(0, SeekOrigin.Begin);
if (createThumbnail)
{
using var thumbnail = Image.ThumbnailStream(stream, MetadataService.ThumbnailWidth);
return thumbnail.WriteToBuffer(".png");
}
if (!createThumbnail) return stream.ToArray();
using var thumbnail = Image.ThumbnailStream(stream, MetadataService.ThumbnailWidth);
return thumbnail.WriteToBuffer(".png");
return stream.ToArray();
}
catch (Exception ex)
{
@ -479,6 +444,29 @@ namespace API.Services
return Array.Empty<byte>();
}
private static MemoryStream GetPdfPage(IDocReader docReader, int pageNumber)
{
using var pageReader = docReader.GetPageReader(pageNumber);
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
using var doc = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
AddBytesToBitmap(bmp, rawBytes);
for (int y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(bmp.Width - 1, y, bmp.GetPixel(bmp.Width - 2, y));
}
using var g = Graphics.FromImage(doc);
g.FillRegion(Brushes.White, new Region(new Rectangle(0, 0, width, height)));
g.DrawImage(bmp, new Point(0, 0));
g.Save();
var stream = new MemoryStream();
doc.Save(stream, ImageFormat.Jpeg);
return stream;
}
private static string RemoveWhiteSpaceFromStylesheets(string body)
{
body = Regex.Replace(body, @"[a-zA-Z]+#", "#");

View File

@ -20,7 +20,7 @@ COPY --from=copytask /files/wwwroot /kavita/wwwroot
#Installs program dependencies
RUN apt-get update \
&& apt-get install -y libicu-dev libssl1.1 pwgen \
&& apt-get install -y libicu-dev libssl1.1 pwgen libgdiplus \
&& rm -rf /var/lib/apt/lists/*
#Creates the data directory

View File

@ -11,7 +11,11 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Sentry" Version="3.7.0" />
<PackageReference Include="Sentry" Version="3.8.2" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.26.0.34506">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

168
UI/Web/package-lock.json generated
View File

@ -22,8 +22,8 @@
"@ng-bootstrap/ng-bootstrap": "^9.1.0",
"@ngx-lite/nav-drawer": "^0.4.6",
"@ngx-lite/util": "0.0.0",
"@sentry/angular": "^6.4.1",
"@sentry/integrations": "^6.4.1",
"@sentry/angular": "^6.10.0",
"@sentry/integrations": "^6.10.0",
"@types/file-saver": "^2.0.1",
"angular-ng-autocomplete": "^2.0.5",
"bootstrap": "^4.5.0",
@ -3140,13 +3140,13 @@
}
},
"node_modules/@sentry/angular": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-6.4.1.tgz",
"integrity": "sha512-lpbc1nA19SYKzaaYd/kn/xqvxI8oRForAR+lM1iE0yru/56ZrFKoUreqQQjCgtMD5aKfI9cT4VrtIq5PVkfOeA==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-6.10.0.tgz",
"integrity": "sha512-SSnsz4sVu9LJh7RM+z9FopWytl2yYNZQ2nK/zv/6iQKIBOqvnCqUIPjVjq1rFYXOe0jOJKsn0QlQLKp4MajYMg==",
"dependencies": {
"@sentry/browser": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/browser": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"rxjs": "^6.6.0",
"tslib": "^1.9.3"
},
@ -3165,13 +3165,13 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/browser": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.4.1.tgz",
"integrity": "sha512-3cDud6GWutnJqcnheIq0lPNTsUJbrRLevQ+g1YfawVXFUxfmmY2bOsGd/Mxq17LxYeBHgKTitXv3DU1bsQ+WBQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.10.0.tgz",
"integrity": "sha512-H0Blgp8f8bomebkkGWIgxHVjabtQAlsKJDiFXBg7gIc75YcarRxwH0R3hMog1/h8mmv4CGGUsy5ljYW6jsNnvA==",
"dependencies": {
"@sentry/core": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/core": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"engines": {
@ -3184,14 +3184,14 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/core": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.4.1.tgz",
"integrity": "sha512-Lx13oTiP+Tjvm5VxulcCszNVd2S1wY4viSnr+ygq62ySVERR+t7uOZDSARZ0rZ259GwW6nkbMh9dDmD0d6VCGQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.10.0.tgz",
"integrity": "sha512-5KlxHJlbD7AMo+b9pMGkjxUOfMILtsqCtGgI7DMvZNfEkdohO8QgUY+hPqr540kmwArFS91ipQYWhqzGaOhM3Q==",
"dependencies": {
"@sentry/hub": "6.4.1",
"@sentry/minimal": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/hub": "6.10.0",
"@sentry/minimal": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"engines": {
@ -3204,12 +3204,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/hub": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.4.1.tgz",
"integrity": "sha512-7IZRP5buDE6s/c3vWzzPR/ySE+8GUuHPgTEPiDCPOCWwUN11zXDafJDKkJqY3muJfebUKmC/JG67RyBx+XlnlQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.10.0.tgz",
"integrity": "sha512-MV8wjhWiFAXZAhmj7Ef5QdBr2IF93u8xXiIo2J+dRZ7eVa4/ZszoUiDbhUcl/TPxczaw4oW2a6tINBNFLzXiig==",
"dependencies": {
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"engines": {
@ -3222,12 +3222,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/integrations": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.4.1.tgz",
"integrity": "sha512-3kw6NcrFGXW+qlfT112EkYt7jdFX55m9yJN5eCt7Iad59YzA8ji8Pio5ohy9Pl+OfYXlKRFOvnYPpZZn80UjlQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.10.0.tgz",
"integrity": "sha512-NMtB0jjFYFZRxyjYu2dWLThk9YPIwqhi4hYywmWkbv4/ILzi5Rwnh+aqNW6yrj8qG4b9itNMh3YvEzmf0aqauw==",
"dependencies": {
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"localforage": "^1.8.1",
"tslib": "^1.9.3"
},
@ -3241,12 +3241,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/minimal": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.4.1.tgz",
"integrity": "sha512-4x/PRbDZACCKJqjta9EkhiIMyGMf7VgBX13EEWEDVWLP7ymFukBuTr4ap/Tz9429kB/yXZuDGGMIZp/G618H3g==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.10.0.tgz",
"integrity": "sha512-yarm046UgUFIBoxqnBan2+BEgaO9KZCrLzsIsmALiQvpfW92K1lHurSawl5W6SR7wCYBnNn7CPvPE/BHFdy4YA==",
"dependencies": {
"@sentry/hub": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/hub": "6.10.0",
"@sentry/types": "6.10.0",
"tslib": "^1.9.3"
},
"engines": {
@ -3259,19 +3259,19 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/types": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.4.1.tgz",
"integrity": "sha512-sTu/GaLsLYk1AkAqpkMT4+4q665LtZjhV0hkgiTD4N3zPl5uSf1pCIzxPRYjOpe7NEANmWv8U4PaGKGtc2eMfA==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.10.0.tgz",
"integrity": "sha512-M7s0JFgG7/6/yNVYoPUbxzaXDhnzyIQYRRJJKRaTD77YO4MHvi4Ke8alBWqD5fer0cPIfcSkBqa9BLdqRqcMWw==",
"engines": {
"node": ">=6"
}
},
"node_modules/@sentry/utils": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.4.1.tgz",
"integrity": "sha512-xJ1uVa5fvg23pXQfulvCIBb9pQ3p1awyd1PapK2AYi+wKjTuYl4B9edmhjRREEQEExznl/d2OVm78fRXLq7M9Q==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.10.0.tgz",
"integrity": "sha512-F9OczOcZMFtazYVZ6LfRIe65/eOfQbiAedIKS0li4npuMz0jKYRbxrjd/U7oLiNQkPAp4/BujU4m1ZIwq6a+tg==",
"dependencies": {
"@sentry/types": "6.4.1",
"@sentry/types": "6.10.0",
"tslib": "^1.9.3"
},
"engines": {
@ -22898,13 +22898,13 @@
}
},
"@sentry/angular": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-6.4.1.tgz",
"integrity": "sha512-lpbc1nA19SYKzaaYd/kn/xqvxI8oRForAR+lM1iE0yru/56ZrFKoUreqQQjCgtMD5aKfI9cT4VrtIq5PVkfOeA==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/angular/-/angular-6.10.0.tgz",
"integrity": "sha512-SSnsz4sVu9LJh7RM+z9FopWytl2yYNZQ2nK/zv/6iQKIBOqvnCqUIPjVjq1rFYXOe0jOJKsn0QlQLKp4MajYMg==",
"requires": {
"@sentry/browser": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/browser": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"rxjs": "^6.6.0",
"tslib": "^1.9.3"
},
@ -22917,13 +22917,13 @@
}
},
"@sentry/browser": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.4.1.tgz",
"integrity": "sha512-3cDud6GWutnJqcnheIq0lPNTsUJbrRLevQ+g1YfawVXFUxfmmY2bOsGd/Mxq17LxYeBHgKTitXv3DU1bsQ+WBQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.10.0.tgz",
"integrity": "sha512-H0Blgp8f8bomebkkGWIgxHVjabtQAlsKJDiFXBg7gIc75YcarRxwH0R3hMog1/h8mmv4CGGUsy5ljYW6jsNnvA==",
"requires": {
"@sentry/core": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/core": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"dependencies": {
@ -22935,14 +22935,14 @@
}
},
"@sentry/core": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.4.1.tgz",
"integrity": "sha512-Lx13oTiP+Tjvm5VxulcCszNVd2S1wY4viSnr+ygq62ySVERR+t7uOZDSARZ0rZ259GwW6nkbMh9dDmD0d6VCGQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.10.0.tgz",
"integrity": "sha512-5KlxHJlbD7AMo+b9pMGkjxUOfMILtsqCtGgI7DMvZNfEkdohO8QgUY+hPqr540kmwArFS91ipQYWhqzGaOhM3Q==",
"requires": {
"@sentry/hub": "6.4.1",
"@sentry/minimal": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/hub": "6.10.0",
"@sentry/minimal": "6.10.0",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"dependencies": {
@ -22954,12 +22954,12 @@
}
},
"@sentry/hub": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.4.1.tgz",
"integrity": "sha512-7IZRP5buDE6s/c3vWzzPR/ySE+8GUuHPgTEPiDCPOCWwUN11zXDafJDKkJqY3muJfebUKmC/JG67RyBx+XlnlQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.10.0.tgz",
"integrity": "sha512-MV8wjhWiFAXZAhmj7Ef5QdBr2IF93u8xXiIo2J+dRZ7eVa4/ZszoUiDbhUcl/TPxczaw4oW2a6tINBNFLzXiig==",
"requires": {
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"tslib": "^1.9.3"
},
"dependencies": {
@ -22971,12 +22971,12 @@
}
},
"@sentry/integrations": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.4.1.tgz",
"integrity": "sha512-3kw6NcrFGXW+qlfT112EkYt7jdFX55m9yJN5eCt7Iad59YzA8ji8Pio5ohy9Pl+OfYXlKRFOvnYPpZZn80UjlQ==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.10.0.tgz",
"integrity": "sha512-NMtB0jjFYFZRxyjYu2dWLThk9YPIwqhi4hYywmWkbv4/ILzi5Rwnh+aqNW6yrj8qG4b9itNMh3YvEzmf0aqauw==",
"requires": {
"@sentry/types": "6.4.1",
"@sentry/utils": "6.4.1",
"@sentry/types": "6.10.0",
"@sentry/utils": "6.10.0",
"localforage": "^1.8.1",
"tslib": "^1.9.3"
},
@ -22989,12 +22989,12 @@
}
},
"@sentry/minimal": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.4.1.tgz",
"integrity": "sha512-4x/PRbDZACCKJqjta9EkhiIMyGMf7VgBX13EEWEDVWLP7ymFukBuTr4ap/Tz9429kB/yXZuDGGMIZp/G618H3g==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.10.0.tgz",
"integrity": "sha512-yarm046UgUFIBoxqnBan2+BEgaO9KZCrLzsIsmALiQvpfW92K1lHurSawl5W6SR7wCYBnNn7CPvPE/BHFdy4YA==",
"requires": {
"@sentry/hub": "6.4.1",
"@sentry/types": "6.4.1",
"@sentry/hub": "6.10.0",
"@sentry/types": "6.10.0",
"tslib": "^1.9.3"
},
"dependencies": {
@ -23006,16 +23006,16 @@
}
},
"@sentry/types": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.4.1.tgz",
"integrity": "sha512-sTu/GaLsLYk1AkAqpkMT4+4q665LtZjhV0hkgiTD4N3zPl5uSf1pCIzxPRYjOpe7NEANmWv8U4PaGKGtc2eMfA=="
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.10.0.tgz",
"integrity": "sha512-M7s0JFgG7/6/yNVYoPUbxzaXDhnzyIQYRRJJKRaTD77YO4MHvi4Ke8alBWqD5fer0cPIfcSkBqa9BLdqRqcMWw=="
},
"@sentry/utils": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.4.1.tgz",
"integrity": "sha512-xJ1uVa5fvg23pXQfulvCIBb9pQ3p1awyd1PapK2AYi+wKjTuYl4B9edmhjRREEQEExznl/d2OVm78fRXLq7M9Q==",
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.10.0.tgz",
"integrity": "sha512-F9OczOcZMFtazYVZ6LfRIe65/eOfQbiAedIKS0li4npuMz0jKYRbxrjd/U7oLiNQkPAp4/BujU4m1ZIwq6a+tg==",
"requires": {
"@sentry/types": "6.4.1",
"@sentry/types": "6.10.0",
"tslib": "^1.9.3"
},
"dependencies": {

View File

@ -29,8 +29,8 @@
"@ng-bootstrap/ng-bootstrap": "^9.1.0",
"@ngx-lite/nav-drawer": "^0.4.6",
"@ngx-lite/util": "0.0.0",
"@sentry/angular": "^6.4.1",
"@sentry/integrations": "^6.4.1",
"@sentry/angular": "^6.10.0",
"@sentry/integrations": "^6.10.0",
"@types/file-saver": "^2.0.1",
"angular-ng-autocomplete": "^2.0.5",
"bootstrap": "^4.5.0",

View File

@ -96,7 +96,7 @@ export class DownloadService {
*/
private getFilenameFromHeader(headers: HttpHeaders, defaultName: string) {
const tokens = (headers.get('content-disposition') || '').split(';');
let filename = tokens[1].replace('filename=', '').replace('"', '').trim();
let filename = tokens[1].replace('filename=', '').replace(/"/ig, '').trim();
if (filename.startsWith('download_') || filename.startsWith('kavita_download_')) {
const ext = filename.substring(filename.lastIndexOf('.'), filename.length);
return defaultName + ext;

View File

@ -79,4 +79,6 @@ else
fi
chmod +x ./Kavita
./Kavita