From ebbaf2d0602916ddd386060a6985c960ae461a12 Mon Sep 17 00:00:00 2001 From: Joe Milazzo Date: Sun, 11 Dec 2022 07:04:22 -0600 Subject: [PATCH] Epub Table of Generation fixes for Sigil (#1689) * Fixed generating table of contents where key lookup could fail with how Sigil packs the epubs. * Tweaked Kavita's fallback ToC generation (when one doesn't exist in the epub) to also use CoalesceKey. * Code smells --- API/Controllers/SettingsController.cs | 6 ---- API/DTOs/Settings/ServerSettingDTO.cs | 5 ---- API/Data/Seed.cs | 1 - API/Entities/Enums/ServerSettingKey.cs | 9 ++---- API/Helpers/AutoMapperProfiles.cs | 1 - .../Converters/ServerSettingConverter.cs | 3 -- API/Services/BookService.cs | 29 +++++++++++-------- API/Services/CacheService.cs | 6 ---- API/Startup.cs | 19 ++++-------- .../src/app/admin/_models/server-settings.ts | 1 - .../manage-settings.component.html | 9 ------ .../manage-settings.component.ts | 2 -- openapi.json | 7 +---- 13 files changed, 27 insertions(+), 71 deletions(-) diff --git a/API/Controllers/SettingsController.cs b/API/Controllers/SettingsController.cs index 2ea4698e9..8bc273741 100644 --- a/API/Controllers/SettingsController.cs +++ b/API/Controllers/SettingsController.cs @@ -213,12 +213,6 @@ public class SettingsController : BaseApiController } } - if (setting.Key == ServerSettingKey.EnableSwaggerUi && updateSettingsDto.EnableSwaggerUi + string.Empty != setting.Value) - { - setting.Value = updateSettingsDto.EnableSwaggerUi + string.Empty; - _unitOfWork.SettingsRepository.Update(setting); - } - if (setting.Key == ServerSettingKey.TotalBackups && updateSettingsDto.TotalBackups + string.Empty != setting.Value) { if (updateSettingsDto.TotalBackups > 30 || updateSettingsDto.TotalBackups < 1) diff --git a/API/DTOs/Settings/ServerSettingDTO.cs b/API/DTOs/Settings/ServerSettingDTO.cs index 9084e52e7..18af645e4 100644 --- a/API/DTOs/Settings/ServerSettingDTO.cs +++ b/API/DTOs/Settings/ServerSettingDTO.cs @@ -49,11 +49,6 @@ public class ServerSettingDto /// public bool ConvertBookmarkToWebP { get; set; } /// - /// If the Swagger UI Should be exposed. Does not require authentication, but does require a JWT. - /// - [Obsolete("Being removed in v0.7 in favor of dedicated hosted api")] - public bool EnableSwaggerUi { get; set; } - /// /// The amount of Backups before cleanup /// /// Value should be between 1 and 30 diff --git a/API/Data/Seed.cs b/API/Data/Seed.cs index db8c788ff..3219d58a0 100644 --- a/API/Data/Seed.cs +++ b/API/Data/Seed.cs @@ -98,7 +98,6 @@ public static class Seed new() {Key = ServerSettingKey.BookmarkDirectory, Value = directoryService.BookmarkDirectory}, new() {Key = ServerSettingKey.EmailServiceUrl, Value = EmailService.DefaultApiUrl}, new() {Key = ServerSettingKey.ConvertBookmarkToWebP, Value = "false"}, - new() {Key = ServerSettingKey.EnableSwaggerUi, Value = "false"}, new() {Key = ServerSettingKey.TotalBackups, Value = "30"}, new() {Key = ServerSettingKey.TotalLogs, Value = "30"}, new() {Key = ServerSettingKey.EnableFolderWatching, Value = "false"}, diff --git a/API/Entities/Enums/ServerSettingKey.cs b/API/Entities/Enums/ServerSettingKey.cs index 5c4fbd601..352f8dd70 100644 --- a/API/Entities/Enums/ServerSettingKey.cs +++ b/API/Entities/Enums/ServerSettingKey.cs @@ -3,6 +3,9 @@ using System.ComponentModel; namespace API.Entities.Enums; +/// +/// 15 is blocked as it was EnableSwaggerUi, which is no longer used +/// public enum ServerSettingKey { /// @@ -83,12 +86,6 @@ public enum ServerSettingKey [Description("ConvertBookmarkToWebP")] ConvertBookmarkToWebP = 14, /// - /// If the Swagger UI Should be exposed. Does not require authentication, but does require a JWT. - /// - [Description("EnableSwaggerUi")] - [Obsolete("Being removed in v0.7 in favor of dedicated hosted api")] - EnableSwaggerUi = 15, - /// /// Total Number of Backups to maintain before cleaning. Default 30, min 1. /// [Description("TotalBackups")] diff --git a/API/Helpers/AutoMapperProfiles.cs b/API/Helpers/AutoMapperProfiles.cs index 018b3982b..bef39e90d 100644 --- a/API/Helpers/AutoMapperProfiles.cs +++ b/API/Helpers/AutoMapperProfiles.cs @@ -145,7 +145,6 @@ public class AutoMapperProfiles : Profile CreateMap(); CreateMap(); - //.AfterMap((src, dest) => dest.Title = ReadingListHelper.FormatTitle(dest)); CreateMap() .ForMember(dest => dest.SeriesId, diff --git a/API/Helpers/Converters/ServerSettingConverter.cs b/API/Helpers/Converters/ServerSettingConverter.cs index 008e08e90..7c2b23570 100644 --- a/API/Helpers/Converters/ServerSettingConverter.cs +++ b/API/Helpers/Converters/ServerSettingConverter.cs @@ -54,9 +54,6 @@ public class ServerSettingConverter : ITypeConverter, case ServerSettingKey.ConvertCoverToWebP: destination.ConvertCoverToWebP = bool.Parse(row.Value); break; - case ServerSettingKey.EnableSwaggerUi: - destination.EnableSwaggerUi = bool.Parse(row.Value); - break; case ServerSettingKey.TotalBackups: destination.TotalBackups = int.Parse(row.Value); break; diff --git a/API/Services/BookService.cs b/API/Services/BookService.cs index 3244ce07f..369184925 100644 --- a/API/Services/BookService.cs +++ b/API/Services/BookService.cs @@ -717,6 +717,20 @@ public class BookService : IBookService return PrepareFinalHtml(doc, body); } + private static string CoalesceKey(EpubBookRef book, IDictionary mappings, string key) + { + if (mappings.ContainsKey(CleanContentKeys(key))) return key; + + // Fallback to searching for key (bad epub metadata) + var correctedKey = book.Content.Html.Keys.SingleOrDefault(s => s.EndsWith(key)); + if (!string.IsNullOrEmpty(correctedKey)) + { + key = correctedKey; + } + + return key; + } + /// /// This will return a list of mappings from ID -> page num. ID will be the xhtml key and page num will be the reading order /// this is used to rewrite anchors in the book text so that we always load properly in our reader. @@ -743,7 +757,7 @@ public class BookService : IBookService foreach (var nestedChapter in navigationItem.NestedItems.Where(n => n.Link != null)) { - var key = BookService.CleanContentKeys(nestedChapter.Link.ContentFileName); + var key = CoalesceKey(book, mappings, nestedChapter.Link.ContentFileName); if (mappings.ContainsKey(key)) { nestedChapters.Add(new BookChapterItem() @@ -760,7 +774,7 @@ public class BookService : IBookService } if (chaptersList.Count != 0) return chaptersList; - // Generate from TOC + // Generate from TOC from links (any point past this, Kavita is generating as a TOC doesn't exist) var tocPage = book.Content.Html.Keys.FirstOrDefault(k => k.ToUpper().Contains("TOC")); if (tocPage == null) return chaptersList; @@ -775,16 +789,7 @@ public class BookService : IBookService { if (!anchor.Attributes.Contains("href")) continue; - var key = BookService.CleanContentKeys(anchor.Attributes["href"].Value).Split("#")[0]; - if (!mappings.ContainsKey(key)) - { - // Fallback to searching for key (bad epub metadata) - var correctedKey = book.Content.Html.Keys.SingleOrDefault(s => s.EndsWith(key)); - if (!string.IsNullOrEmpty(correctedKey)) - { - key = correctedKey; - } - } + var key = CoalesceKey(book, mappings, anchor.Attributes["href"].Value.Split("#")[0]); if (string.IsNullOrEmpty(key) || !mappings.ContainsKey(key)) continue; var part = string.Empty; diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs index 95a9a646e..62607f1aa 100644 --- a/API/Services/CacheService.cs +++ b/API/Services/CacheService.cs @@ -90,12 +90,6 @@ public class CacheService : ICacheService return path; } - - /// - /// Caches the files for the given chapter to CacheDirectory - /// - /// - /// This will always return the Chapter for the chapterId public async Task Ensure(int chapterId, bool extractPdfToImages = false) { _directoryService.ExistOrCreate(_directoryService.CacheDirectory); diff --git a/API/Startup.cs b/API/Startup.cs index d3481ed51..14c361f0c 100644 --- a/API/Startup.cs +++ b/API/Startup.cs @@ -246,21 +246,14 @@ public class Startup app.UseMiddleware(); - Task.Run(async () => + if (env.IsDevelopment()) { - var allowSwaggerUi = (await unitOfWork.SettingsRepository.GetSettingsDtoAsync()) - .EnableSwaggerUi; - - if (env.IsDevelopment() || allowSwaggerUi) + app.UseSwagger(); + app.UseSwaggerUI(c => { - app.UseSwagger(); - app.UseSwaggerUI(c => - { - c.SwaggerEndpoint("/swagger/v1/swagger.json", "Kavita API " + BuildInfo.Version); - }); - - } - }); + c.SwaggerEndpoint("/swagger/v1/swagger.json", "Kavita API " + BuildInfo.Version); + }); + } if (env.IsDevelopment()) { diff --git a/UI/Web/src/app/admin/_models/server-settings.ts b/UI/Web/src/app/admin/_models/server-settings.ts index b52c2ec9d..b5ecd1248 100644 --- a/UI/Web/src/app/admin/_models/server-settings.ts +++ b/UI/Web/src/app/admin/_models/server-settings.ts @@ -11,7 +11,6 @@ export interface ServerSettings { emailServiceUrl: string; convertBookmarkToWebP: boolean; convertCoverToWebP: boolean; - enableSwaggerUi: boolean; totalBackups: number; totalLogs: number; enableFolderWatching: boolean; diff --git a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html index 2be4afe30..5071e16df 100644 --- a/UI/Web/src/app/admin/manage-settings/manage-settings.component.html +++ b/UI/Web/src/app/admin/manage-settings/manage-settings.component.html @@ -88,15 +88,6 @@ -
- -

Allows Swagger UI to be exposed via swagger/ on your server. Authentication is not required, but a valid JWT token is. Requires a restart to take effect. Swagger is hosted on yourip:5000/swagger

-
- - -
-
-
diff --git a/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts b/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts index 9aef206e9..54be134c0 100644 --- a/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts +++ b/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts @@ -47,7 +47,6 @@ export class ManageSettingsComponent implements OnInit { this.settingsForm.addControl('enableOpds', new FormControl(this.serverSettings.enableOpds, [Validators.required])); this.settingsForm.addControl('baseUrl', new FormControl(this.serverSettings.baseUrl, [Validators.required])); this.settingsForm.addControl('emailServiceUrl', new FormControl(this.serverSettings.emailServiceUrl, [Validators.required])); - this.settingsForm.addControl('enableSwaggerUi', new FormControl(this.serverSettings.enableSwaggerUi, [Validators.required])); this.settingsForm.addControl('totalBackups', new FormControl(this.serverSettings.totalBackups, [Validators.required, Validators.min(1), Validators.max(30)])); this.settingsForm.addControl('totalLogs', new FormControl(this.serverSettings.totalLogs, [Validators.required, Validators.min(1), Validators.max(30)])); this.settingsForm.addControl('enableFolderWatching', new FormControl(this.serverSettings.enableFolderWatching, [Validators.required])); @@ -66,7 +65,6 @@ export class ManageSettingsComponent implements OnInit { this.settingsForm.get('enableOpds')?.setValue(this.serverSettings.enableOpds); this.settingsForm.get('baseUrl')?.setValue(this.serverSettings.baseUrl); this.settingsForm.get('emailServiceUrl')?.setValue(this.serverSettings.emailServiceUrl); - this.settingsForm.get('enableSwaggerUi')?.setValue(this.serverSettings.enableSwaggerUi); this.settingsForm.get('totalBackups')?.setValue(this.serverSettings.totalBackups); this.settingsForm.get('totalLogs')?.setValue(this.serverSettings.totalLogs); this.settingsForm.get('enableFolderWatching')?.setValue(this.serverSettings.enableFolderWatching); diff --git a/openapi.json b/openapi.json index a8bc35094..41aa353b1 100644 --- a/openapi.json +++ b/openapi.json @@ -7,7 +7,7 @@ "name": "GPL-3.0", "url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE" }, - "version": "0.6.1.8" + "version": "0.6.1.9" }, "servers": [ { @@ -12843,11 +12843,6 @@ "type": "boolean", "description": "If the server should save bookmarks as WebP encoding" }, - "enableSwaggerUi": { - "type": "boolean", - "description": "If the Swagger UI Should be exposed. Does not require authentication, but does require a JWT.", - "deprecated": true - }, "totalBackups": { "type": "integer", "description": "The amount of Backups before cleanup",