diff --git a/API.Tests/Extensions/VolumeListExtensionsTests.cs b/API.Tests/Extensions/VolumeListExtensionsTests.cs
index b8b734c51..92a3e93ff 100644
--- a/API.Tests/Extensions/VolumeListExtensionsTests.cs
+++ b/API.Tests/Extensions/VolumeListExtensionsTests.cs
@@ -154,5 +154,25 @@ public class VolumeListExtensionsTests
}
+ ///
+ /// Single volume (comicvine type style) with negative or non-numerical
+ ///
+ public void GetCoverImage_LooseChapters_WithSub1_InOneVolume()
+ {
+ var volumes = new List()
+ {
+ new VolumeBuilder("2")
+ .WithChapter(new ChapterBuilder("-1").WithCoverImage("Chapter -1").Build())
+ .WithChapter(new ChapterBuilder("1").WithCoverImage("Chapter 1").Build())
+ .Build(),
+ };
+
+ // Not testable due to the code not actually doing the heavy lifting
+ // var actual = volumes.GetCoverImage(MangaFormat.Archive);
+ // Assert.NotNull(actual);
+ // Assert.Equal("Chapter 1", actual.CoverImage);
+ }
+
+
#endregion
}
diff --git a/API.Tests/Services/CacheServiceTests.cs b/API.Tests/Services/CacheServiceTests.cs
index ba06525a3..cd60ed579 100644
--- a/API.Tests/Services/CacheServiceTests.cs
+++ b/API.Tests/Services/CacheServiceTests.cs
@@ -52,12 +52,12 @@ internal class MockReadingItemServiceForCacheService : IReadingItemService
throw new System.NotImplementedException();
}
- public ParserInfo Parse(string path, string rootPath, string libraryRoot, LibraryType type)
+ public ParserInfo Parse(string path, string rootPath, string libraryRoot, Library library)
{
throw new System.NotImplementedException();
}
- public ParserInfo ParseFile(string path, string rootPath, string libraryRoot, LibraryType type)
+ public ParserInfo ParseFile(string path, string rootPath, string libraryRoot, Library library)
{
throw new System.NotImplementedException();
}
diff --git a/API.Tests/Services/ParseScannedFilesTests.cs b/API.Tests/Services/ParseScannedFilesTests.cs
index 04dc20522..03e97530c 100644
--- a/API.Tests/Services/ParseScannedFilesTests.cs
+++ b/API.Tests/Services/ParseScannedFilesTests.cs
@@ -54,14 +54,14 @@ internal class MockReadingItemService : IReadingItemService
throw new NotImplementedException();
}
- public ParserInfo Parse(string path, string rootPath, string libraryRoot, LibraryType type)
+ public ParserInfo Parse(string path, string rootPath, string libraryRoot, Library library)
{
- return _defaultParser.Parse(path, rootPath, libraryRoot, type);
+ return _defaultParser.Parse(path, rootPath, libraryRoot, library.Type);
}
- public ParserInfo ParseFile(string path, string rootPath, string libraryRoot, LibraryType type)
+ public ParserInfo ParseFile(string path, string rootPath, string libraryRoot, Library library)
{
- return _defaultParser.Parse(path, rootPath, libraryRoot, type);
+ return _defaultParser.Parse(path, rootPath, libraryRoot, library.Type);
}
}
diff --git a/API/Entities/Enums/LibraryType.cs b/API/Entities/Enums/LibraryType.cs
index ad17e62b1..c9e04238b 100644
--- a/API/Entities/Enums/LibraryType.cs
+++ b/API/Entities/Enums/LibraryType.cs
@@ -34,5 +34,10 @@ public enum LibraryType
///
[Description("Comic (ComicVine)")]
ComicVine = 5,
+ ///
+ /// This library requires custom regex from admin
+ ///
+ [Description("Generic")]
+ Generic = 6,
}
diff --git a/API/Extensions/ChapterListExtensions.cs b/API/Extensions/ChapterListExtensions.cs
index 0a21cc5ad..db707a5f9 100644
--- a/API/Extensions/ChapterListExtensions.cs
+++ b/API/Extensions/ChapterListExtensions.cs
@@ -43,6 +43,6 @@ public static class ChapterListExtensions
///
public static int MinimumReleaseYear(this IList chapters)
{
- return chapters.Select(v => v.ReleaseDate.Year).Where(y => NumberHelper.IsValidYear(y)).DefaultIfEmpty().Min();
+ return chapters.Select(v => v.ReleaseDate.Year).Where(NumberHelper.IsValidYear).DefaultIfEmpty().Min();
}
}
diff --git a/API/Services/MetadataService.cs b/API/Services/MetadataService.cs
index d0c9d78c2..af46505c7 100644
--- a/API/Services/MetadataService.cs
+++ b/API/Services/MetadataService.cs
@@ -107,10 +107,16 @@ public class MetadataService : IMetadataService
_directoryService.FileSystem.Path.Join(_directoryService.CoverImageDirectory, volume.CoverImage),
null, volume.Created, forceUpdate)) return Task.FromResult(false);
-
+ // For cover selection, chapters need to try for issue 1 first, then fallback to first sort order
volume.Chapters ??= new List();
- var firstChapter = volume.Chapters.MinBy(x => x.MinNumber, ChapterSortComparerDefaultFirst.Default);
- if (firstChapter == null) return Task.FromResult(false);
+
+ var firstChapter = volume.Chapters.FirstOrDefault(x => x.MinNumber.Is(1f));
+ if (firstChapter == null)
+ {
+ firstChapter = volume.Chapters.MinBy(x => x.SortOrder, ChapterSortComparerDefaultFirst.Default);
+ if (firstChapter == null) return Task.FromResult(false);
+ }
+
volume.CoverImage = firstChapter.CoverImage;
_updateEvents.Add(MessageFactory.CoverUpdateEvent(volume.Id, MessageFactoryEntityTypes.Volume));
diff --git a/API/Services/ReadingItemService.cs b/API/Services/ReadingItemService.cs
index cd1c508e2..2545c031b 100644
--- a/API/Services/ReadingItemService.cs
+++ b/API/Services/ReadingItemService.cs
@@ -1,5 +1,6 @@
using System;
using API.Data.Metadata;
+using API.Entities;
using API.Entities.Enums;
using API.Services.Tasks.Scanner.Parser;
using Microsoft.Extensions.Logging;
@@ -13,7 +14,7 @@ public interface IReadingItemService
int GetNumberOfPages(string filePath, MangaFormat format);
string GetCoverImage(string filePath, string fileName, MangaFormat format, EncodeFormat encodeFormat, CoverImageSize size = CoverImageSize.Default);
void Extract(string fileFilePath, string targetDirectory, MangaFormat format, int imageCount = 1);
- ParserInfo? ParseFile(string path, string rootPath, string libraryRoot, LibraryType type);
+ ParserInfo? ParseFile(string path, string rootPath, string libraryRoot, Library library);
}
public class ReadingItemService : IReadingItemService
@@ -28,6 +29,7 @@ public class ReadingItemService : IReadingItemService
private readonly ImageParser _imageParser;
private readonly BookParser _bookParser;
private readonly PdfParser _pdfParser;
+ private readonly GenericLibraryParser _genericLibraryParser;
public ReadingItemService(IArchiveService archiveService, IBookService bookService, IImageService imageService,
IDirectoryService directoryService, ILogger logger)
@@ -43,6 +45,7 @@ public class ReadingItemService : IReadingItemService
_bookParser = new BookParser(directoryService, bookService, _basicParser);
_pdfParser = new PdfParser(directoryService);
_basicParser = new BasicParser(directoryService, _imageParser);
+ _genericLibraryParser = new GenericLibraryParser(directoryService);
}
///
@@ -71,9 +74,9 @@ public class ReadingItemService : IReadingItemService
/// Path of a file
///
/// Library type to determine parsing to perform
- public ParserInfo? ParseFile(string path, string rootPath, string libraryRoot, LibraryType type)
+ public ParserInfo? ParseFile(string path, string rootPath, string libraryRoot, Library library)
{
- var info = Parse(path, rootPath, libraryRoot, type);
+ var info = Parse(path, rootPath, libraryRoot, library);
if (info == null)
{
_logger.LogError("Unable to parse any meaningful information out of file {FilePath}", path);
@@ -166,27 +169,31 @@ public class ReadingItemService : IReadingItemService
///
///
///
- private ParserInfo? Parse(string path, string rootPath, string libraryRoot, LibraryType type)
+ private ParserInfo? Parse(string path, string rootPath, string libraryRoot, Library library)
{
- if (_comicVineParser.IsApplicable(path, type))
+ if (_comicVineParser.IsApplicable(path, library.Type))
{
- return _comicVineParser.Parse(path, rootPath, libraryRoot, type, GetComicInfo(path));
+ return _comicVineParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
}
- if (_imageParser.IsApplicable(path, type))
+ if (_imageParser.IsApplicable(path, library.Type))
{
- return _imageParser.Parse(path, rootPath, libraryRoot, type, GetComicInfo(path));
+ return _imageParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
}
- if (_bookParser.IsApplicable(path, type))
+ if (_bookParser.IsApplicable(path, library.Type))
{
- return _bookParser.Parse(path, rootPath, libraryRoot, type, GetComicInfo(path));
+ return _bookParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
}
- if (_pdfParser.IsApplicable(path, type))
+ if (_genericLibraryParser.IsApplicable(path, library.Type))
{
- return _pdfParser.Parse(path, rootPath, libraryRoot, type, GetComicInfo(path));
+ return _genericLibraryParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
}
- if (_basicParser.IsApplicable(path, type))
+ if (_pdfParser.IsApplicable(path, library.Type))
{
- return _basicParser.Parse(path, rootPath, libraryRoot, type, GetComicInfo(path));
+ return _pdfParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
+ }
+ if (_basicParser.IsApplicable(path, library.Type))
+ {
+ return _basicParser.Parse(path, rootPath, libraryRoot, library.Type, GetComicInfo(path));
}
return null;
diff --git a/API/Services/Tasks/Scanner/ParseScannedFiles.cs b/API/Services/Tasks/Scanner/ParseScannedFiles.cs
index 498e59d47..a5aafc36e 100644
--- a/API/Services/Tasks/Scanner/ParseScannedFiles.cs
+++ b/API/Services/Tasks/Scanner/ParseScannedFiles.cs
@@ -411,7 +411,7 @@ public class ParseScannedFiles
// Multiple Series can exist within a folder. We should instead put these infos on the result and perform merging above
IList infos = files
- .Select(file => _readingItemService.ParseFile(file, folder, libraryRoot, library.Type))
+ .Select(file => _readingItemService.ParseFile(file, folder, libraryRoot, library))
.Where(info => info != null)
.ToList()!;
diff --git a/API/Services/Tasks/Scanner/Parser/BasicParser.cs b/API/Services/Tasks/Scanner/Parser/BasicParser.cs
index 9df68abb9..459c93fb7 100644
--- a/API/Services/Tasks/Scanner/Parser/BasicParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/BasicParser.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using API.Data.Metadata;
using API.Entities.Enums;
@@ -11,7 +12,8 @@ namespace API.Services.Tasks.Scanner.Parser;
///
public class BasicParser(IDirectoryService directoryService, IDefaultParser imageParser) : DefaultParser(directoryService)
{
- public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null)
+ public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
{
var fileName = directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath);
// TODO: Potential Bug: This will return null, but on Image libraries, if all images, we would want to include this.
diff --git a/API/Services/Tasks/Scanner/Parser/BookParser.cs b/API/Services/Tasks/Scanner/Parser/BookParser.cs
index 9c7ed9a16..b72bd7e20 100644
--- a/API/Services/Tasks/Scanner/Parser/BookParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/BookParser.cs
@@ -1,11 +1,13 @@
-using API.Data.Metadata;
+using System.Collections.Generic;
+using API.Data.Metadata;
using API.Entities.Enums;
namespace API.Services.Tasks.Scanner.Parser;
public class BookParser(IDirectoryService directoryService, IBookService bookService, IDefaultParser basicParser) : DefaultParser(directoryService)
{
- public override ParserInfo Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo comicInfo = null)
+ public override ParserInfo Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
{
var info = bookService.ParseInfo(filePath);
if (info == null) return null;
diff --git a/API/Services/Tasks/Scanner/Parser/ComicVineParser.cs b/API/Services/Tasks/Scanner/Parser/ComicVineParser.cs
index 79830c86c..0b46ad473 100644
--- a/API/Services/Tasks/Scanner/Parser/ComicVineParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/ComicVineParser.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
using API.Data.Metadata;
using API.Entities.Enums;
@@ -15,11 +16,8 @@ public class ComicVineParser(IDirectoryService directoryService) : DefaultParser
///
/// This Parser generates Series name to be defined as Series + first Issue Volume, so "Batman (2020)".
///
- ///
- ///
- ///
- ///
- public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null)
+ public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
{
if (type != LibraryType.ComicVine) return null;
diff --git a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs
index abf59f83a..4aca1a77f 100644
--- a/API/Services/Tasks/Scanner/Parser/DefaultParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/DefaultParser.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using API.Data.Metadata;
@@ -8,7 +9,7 @@ namespace API.Services.Tasks.Scanner.Parser;
public interface IDefaultParser
{
- ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null);
+ ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null, IEnumerable? extraRegex = null);
void ParseFromFallbackFolders(string filePath, string rootPath, LibraryType type, ref ParserInfo ret);
bool IsApplicable(string filePath, LibraryType type);
}
@@ -26,8 +27,11 @@ public abstract class DefaultParser(IDirectoryService directoryService) : IDefau
///
/// Root folder
/// Allows different Regex to be used for parsing.
+ /// ComicInfo if present (for epub it si always present)
+ /// The regex for the Generic Parser
/// or null if Series was empty
- public abstract ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null);
+ public abstract ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null);
///
/// Fills out by trying to parse volume, chapters, and series from folders
diff --git a/API/Services/Tasks/Scanner/Parser/GenericLibraryParser.cs b/API/Services/Tasks/Scanner/Parser/GenericLibraryParser.cs
new file mode 100644
index 000000000..ebcb1264c
--- /dev/null
+++ b/API/Services/Tasks/Scanner/Parser/GenericLibraryParser.cs
@@ -0,0 +1,90 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using API.Data.Metadata;
+using API.Entities.Enums;
+
+namespace API.Services.Tasks.Scanner.Parser;
+#nullable enable
+
+///
+/// Uses an at-runtime array of Regex to parse out information
+///
+///
+public class GenericLibraryParser(IDirectoryService directoryService) : DefaultParser(directoryService)
+{
+ public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
+ {
+ if (extraRegex == null) return null;
+
+ // The idea is this is passed in as a default param. Only Generic will use it
+ var fileName = directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath);
+ var info = new ParserInfo()
+ {
+ Filename = Path.GetFileName(filePath),
+ Format = Parser.ParseFormat(filePath),
+ Title = Parser.RemoveExtensionIfSupported(fileName)!,
+ FullFilePath = filePath,
+ Series = string.Empty,
+ ComicInfo = comicInfo,
+ Chapters = Parser.ParseComicChapter(fileName),
+ Volumes = Parser.ParseComicVolume(fileName)
+ };
+
+
+ foreach (var regex in extraRegex)
+ {
+ var matches = new Regex(regex, RegexOptions.IgnoreCase).Matches(fileName);
+ foreach (var group in matches.Select(match => match.Groups))
+ {
+ foreach (var matchKey in group.Keys)
+ {
+ var matchValue = group[matchKey].Value;
+ switch (matchKey)
+ {
+ case "Series":
+ info.Series = SetIfNotDefault(matchValue, info.Series);
+ break;
+ case "Chapter":
+ info.Chapters = SetIfNotDefault(matchValue, info.Chapters);
+ break;
+ }
+ }
+ }
+ }
+
+ // Process the final info here: (cleaning values, setting internal encoding overrides)
+ if (info.IsSpecial)
+ {
+ info.Volumes = Parser.SpecialVolume;
+ }
+
+ if (string.IsNullOrEmpty(info.Chapters))
+ {
+ info.Chapters = Parser.DefaultChapter;
+ }
+
+ if (!info.IsSpecial && string.IsNullOrEmpty(info.Volumes))
+ {
+ info.Chapters = Parser.LooseLeafVolume;
+ }
+
+
+ return string.IsNullOrEmpty(info.Series) ? null : info;
+ }
+
+ private static string SetIfNotDefault(string value, string originalValue)
+ {
+ if (string.IsNullOrEmpty(value)) return originalValue;
+ if (string.IsNullOrEmpty(originalValue)) return value;
+
+ return originalValue;
+ }
+
+ public override bool IsApplicable(string filePath, LibraryType type)
+ {
+ return type == LibraryType.Generic;
+ }
+}
diff --git a/API/Services/Tasks/Scanner/Parser/ImageParser.cs b/API/Services/Tasks/Scanner/Parser/ImageParser.cs
index a1227d841..a2e08dea9 100644
--- a/API/Services/Tasks/Scanner/Parser/ImageParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/ImageParser.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using API.Data.Metadata;
using API.Entities.Enums;
@@ -7,7 +8,8 @@ namespace API.Services.Tasks.Scanner.Parser;
public class ImageParser(IDirectoryService directoryService) : DefaultParser(directoryService)
{
- public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo? comicInfo = null)
+ public override ParserInfo? Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
{
if (type != LibraryType.Image || !Parser.IsImage(filePath)) return null;
diff --git a/API/Services/Tasks/Scanner/Parser/PdfParser.cs b/API/Services/Tasks/Scanner/Parser/PdfParser.cs
index 1b90a95e7..aa203887b 100644
--- a/API/Services/Tasks/Scanner/Parser/PdfParser.cs
+++ b/API/Services/Tasks/Scanner/Parser/PdfParser.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using API.Data.Metadata;
using API.Entities.Enums;
@@ -6,7 +7,8 @@ namespace API.Services.Tasks.Scanner.Parser;
public class PdfParser(IDirectoryService directoryService) : DefaultParser(directoryService)
{
- public override ParserInfo Parse(string filePath, string rootPath, string libraryRoot, LibraryType type, ComicInfo comicInfo = null)
+ public override ParserInfo Parse(string filePath, string rootPath, string libraryRoot, LibraryType type,
+ ComicInfo? comicInfo = null, IEnumerable? extraRegex = null)
{
var fileName = directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath);
var ret = new ParserInfo
diff --git a/UI/Web/src/app/_models/library/library.ts b/UI/Web/src/app/_models/library/library.ts
index c8b55bd1d..f53492694 100644
--- a/UI/Web/src/app/_models/library/library.ts
+++ b/UI/Web/src/app/_models/library/library.ts
@@ -1,12 +1,13 @@
import {FileTypeGroup} from "./file-type-group.enum";
export enum LibraryType {
- Manga = 0,
- Comic = 1,
- Book = 2,
- Images = 3,
- LightNovel = 4,
- ComicVine = 5
+ Manga = 0,
+ Comic = 1,
+ Book = 2,
+ Images = 3,
+ LightNovel = 4,
+ ComicVine = 5,
+ Generic = 6
}
export interface Library {
diff --git a/UI/Web/src/app/_pipes/library-type.pipe.ts b/UI/Web/src/app/_pipes/library-type.pipe.ts
index b9f74dc05..ee29367a6 100644
--- a/UI/Web/src/app/_pipes/library-type.pipe.ts
+++ b/UI/Web/src/app/_pipes/library-type.pipe.ts
@@ -24,6 +24,10 @@ export class LibraryTypePipe implements PipeTransform {
return this.translocoService.translate('library-type-pipe.image');
case LibraryType.Manga:
return this.translocoService.translate('library-type-pipe.manga');
+ case LibraryType.LightNovel:
+ return this.translocoService.translate('library-type-pipe.lightNovel');
+ case LibraryType.Generic:
+ return this.translocoService.translate('library-type-pipe.generic');
default:
return '';
}
diff --git a/UI/Web/src/app/shared/_services/utility.service.ts b/UI/Web/src/app/shared/_services/utility.service.ts
index 496d58aad..c4676efcd 100644
--- a/UI/Web/src/app/shared/_services/utility.service.ts
+++ b/UI/Web/src/app/shared/_services/utility.service.ts
@@ -65,6 +65,7 @@ export class UtilityService {
switch(libraryType) {
case LibraryType.Book:
case LibraryType.LightNovel:
+ case LibraryType.Generic:
return this.translocoService.translate('common.book-num') + (includeSpace ? ' ' : '');
case LibraryType.Comic:
case LibraryType.ComicVine:
diff --git a/UI/Web/src/app/sidenav/_components/side-nav/side-nav.component.ts b/UI/Web/src/app/sidenav/_components/side-nav/side-nav.component.ts
index 39efc38be..b85e9933e 100644
--- a/UI/Web/src/app/sidenav/_components/side-nav/side-nav.component.ts
+++ b/UI/Web/src/app/sidenav/_components/side-nav/side-nav.component.ts
@@ -185,6 +185,7 @@ export class SideNavComponent implements OnInit {
getLibraryTypeIcon(format: LibraryType) {
switch (format) {
case LibraryType.Book:
+ case LibraryType.Generic:
case LibraryType.LightNovel:
return 'fa-book';
case LibraryType.Comic:
diff --git a/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.ts b/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.ts
index 141fd99d7..10ec6ec22 100644
--- a/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.ts
+++ b/UI/Web/src/app/sidenav/_modals/library-settings-modal/library-settings-modal.component.ts
@@ -196,6 +196,12 @@ export class LibrarySettingsModalComponent implements OnInit {
this.libraryForm.get(FileTypeGroup.Pdf + '')?.setValue(false);
this.libraryForm.get(FileTypeGroup.Epub + '')?.setValue(false);
break;
+ case LibraryType.Generic:
+ this.libraryForm.get(FileTypeGroup.Archive + '')?.setValue(false);
+ this.libraryForm.get(FileTypeGroup.Images + '')?.setValue(false);
+ this.libraryForm.get(FileTypeGroup.Pdf + '')?.setValue(true);
+ this.libraryForm.get(FileTypeGroup.Epub + '')?.setValue(false);
+ break;
}
}),
takeUntilDestroyed(this.destroyRef)
diff --git a/UI/Web/src/assets/langs/en.json b/UI/Web/src/assets/langs/en.json
index 535962fab..52f46ade3 100644
--- a/UI/Web/src/assets/langs/en.json
+++ b/UI/Web/src/assets/langs/en.json
@@ -502,7 +502,9 @@
"comic": "Comic",
"manga": "Manga",
"comicVine": "ComicVine",
- "image": "Image"
+ "image": "Image",
+ "lightNovel": "Light Novel",
+ "generic": "Generic"
},
"age-rating-pipe": {
diff --git a/openapi.json b/openapi.json
index d75eba614..43509ccb9 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.7.14.9"
+ "version": "0.7.14.10"
},
"servers": [
{
@@ -2924,7 +2924,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -2938,7 +2939,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -2952,7 +2954,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -3640,7 +3643,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -13549,7 +13553,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -14174,7 +14179,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"description": "Library type",
@@ -15965,7 +15971,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -16080,7 +16087,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -17082,7 +17090,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -17136,7 +17145,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"
@@ -19528,7 +19538,8 @@
2,
3,
4,
- 5
+ 5,
+ 6
],
"type": "integer",
"format": "int32"