Reader Polish (#2465)
Co-authored-by: Andre Smith <Hobogrammer@users.noreply.github.com>
This commit is contained in:
parent
9fdaf5f99f
commit
e489d2404a
24 changed files with 156 additions and 120 deletions
|
@ -308,7 +308,7 @@ public class OpdsController : BaseApiController
|
|||
var userId = await GetUser(apiKey);
|
||||
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
|
||||
return BadRequest(await _localizationService.Translate(userId, "opds-disabled"));
|
||||
var (baseUrl, prefix) = await GetPrefix();
|
||||
var (_, prefix) = await GetPrefix();
|
||||
|
||||
var filters = _unitOfWork.AppUserSmartFilterRepository.GetAllDtosByUserId(userId);
|
||||
var feed = CreateFeed(await _localizationService.Translate(userId, "smartFilters"), $"{prefix}{apiKey}/smart-filters", apiKey, prefix);
|
||||
|
@ -337,7 +337,7 @@ public class OpdsController : BaseApiController
|
|||
var userId = await GetUser(apiKey);
|
||||
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
|
||||
return BadRequest(await _localizationService.Translate(userId, "opds-disabled"));
|
||||
var (baseUrl, prefix) = await GetPrefix();
|
||||
var (_, prefix) = await GetPrefix();
|
||||
|
||||
var externalSources = await _unitOfWork.AppUserExternalSourceRepository.GetExternalSources(userId);
|
||||
var feed = CreateFeed(await _localizationService.Translate(userId, "external-sources"), $"{prefix}{apiKey}/external-sources", apiKey, prefix);
|
||||
|
@ -370,15 +370,13 @@ public class OpdsController : BaseApiController
|
|||
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
|
||||
return BadRequest(await _localizationService.Translate(userId, "opds-disabled"));
|
||||
var (baseUrl, prefix) = await GetPrefix();
|
||||
var libraries = await _unitOfWork.LibraryRepository.GetLibrariesForUserIdAsync(userId);
|
||||
var feed = CreateFeed(await _localizationService.Translate(userId, "libraries"), $"{prefix}{apiKey}/libraries", apiKey, prefix);
|
||||
SetFeedId(feed, "libraries");
|
||||
|
||||
// Ensure libraries follow SideNav order
|
||||
var userSideNavStreams = await _unitOfWork.UserRepository.GetSideNavStreams(userId, false);
|
||||
foreach (var sideNavStream in userSideNavStreams.Where(s => s.StreamType == SideNavStreamType.Library))
|
||||
foreach (var library in userSideNavStreams.Where(s => s.StreamType == SideNavStreamType.Library).Select(sideNavStream => sideNavStream.Library))
|
||||
{
|
||||
var library = sideNavStream.Library;
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Id = library!.Id.ToString(),
|
||||
|
@ -779,13 +777,13 @@ public class OpdsController : BaseApiController
|
|||
var chapters = (await _unitOfWork.ChapterRepository.GetChaptersAsync(volume.Id)).OrderBy(x => double.Parse(x.Number, CultureInfo.InvariantCulture),
|
||||
_chapterSortComparer);
|
||||
|
||||
foreach (var chapter in chapters)
|
||||
foreach (var chapterId in chapters.Select(c => c.Id))
|
||||
{
|
||||
var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapter.Id);
|
||||
var chapterTest = await _unitOfWork.ChapterRepository.GetChapterDtoAsync(chapter.Id);
|
||||
var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapterId);
|
||||
var chapterTest = await _unitOfWork.ChapterRepository.GetChapterDtoAsync(chapterId);
|
||||
foreach (var mangaFile in files)
|
||||
{
|
||||
feed.Entries.Add(await CreateChapterWithFile(userId, seriesId, volume.Id, chapter.Id, mangaFile, series, chapterTest, apiKey, prefix, baseUrl));
|
||||
feed.Entries.Add(await CreateChapterWithFile(userId, seriesId, volume.Id, chapterId, mangaFile, series, chapterTest, apiKey, prefix, baseUrl));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,18 +105,23 @@ public class ReaderController : BaseApiController
|
|||
/// <param name="extractPdf">Should Kavita extract pdf into images. Defaults to false.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("image")]
|
||||
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Hour, VaryByQueryKeys = new []{"chapterId","page", "extractPdf", "apiKey"})]
|
||||
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Hour, VaryByQueryKeys = new []{"chapterId", "page", "extractPdf", "apiKey"})]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult> GetImage(int chapterId, int page, string apiKey, bool extractPdf = false)
|
||||
{
|
||||
if (page < 0) page = 0;
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByApiKeyAsync(apiKey);
|
||||
if (userId == 0) return BadRequest();
|
||||
var chapter = await _cacheService.Ensure(chapterId, extractPdf);
|
||||
if (chapter == null) return NoContent();
|
||||
|
||||
try
|
||||
{
|
||||
if (new Random().Next(1, 10) > 5)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
var chapter = await _cacheService.Ensure(chapterId, extractPdf);
|
||||
if (chapter == null) return NoContent();
|
||||
_logger.LogInformation("Fetching Page {PageNum} on Chapter {ChapterId}", page, chapterId);
|
||||
var path = _cacheService.GetCachedPagePath(chapter.Id, page);
|
||||
if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
|
||||
return BadRequest(await _localizationService.Translate(userId, "no-image-for-page", page));
|
||||
|
@ -245,8 +250,8 @@ public class ReaderController : BaseApiController
|
|||
LibraryId = dto.LibraryId,
|
||||
IsSpecial = dto.IsSpecial,
|
||||
Pages = dto.Pages,
|
||||
SeriesTotalPages = series?.Pages ?? 0,
|
||||
SeriesTotalPagesRead = series?.PagesRead ?? 0,
|
||||
SeriesTotalPages = series.Pages,
|
||||
SeriesTotalPagesRead = series.PagesRead,
|
||||
ChapterTitle = dto.ChapterTitle ?? string.Empty,
|
||||
Subtitle = string.Empty,
|
||||
Title = dto.SeriesName,
|
||||
|
|
|
@ -280,7 +280,7 @@ public class LibraryRepository : ILibraryRepository
|
|||
{
|
||||
Title = s,
|
||||
IsoCode = s
|
||||
};;
|
||||
};
|
||||
}
|
||||
|
||||
public IEnumerable<PublicationStatusDto> GetAllPublicationStatusesDtosForLibrariesAsync(List<int> libraryIds)
|
||||
|
|
|
@ -644,6 +644,7 @@ public class DirectoryService : IDirectoryService
|
|||
/// Scans a directory by utilizing a recursive folder search. If a .kavitaignore file is found, will ignore matching patterns
|
||||
/// </summary>
|
||||
/// <param name="folderPath"></param>
|
||||
/// <param name="supportedExtensions"></param>
|
||||
/// <param name="matcher"></param>
|
||||
/// <returns></returns>
|
||||
public IList<string> ScanFiles(string folderPath, string supportedExtensions, GlobMatcher? matcher = null)
|
||||
|
|
|
@ -398,7 +398,7 @@ public class ReaderService : IReaderService
|
|||
// Handle Chapters within next Volume
|
||||
// ! When selecting the chapter for the next volume, we need to make sure a c0 comes before a c1+
|
||||
var chapters = volume.Chapters.OrderBy(x => x.Number.AsDouble(), _chapterSortComparer).ToList();
|
||||
if (currentChapter.Number.Equals(Parser.DefaultChapter) && chapters.Last().Number.Equals(Parser.DefaultChapter))
|
||||
if (currentChapter.Number.Equals(Parser.DefaultChapter) && chapters[^1].Number.Equals(Parser.DefaultChapter))
|
||||
{
|
||||
// We need to handle an extra check if the current chapter is the last special, as we should return -1
|
||||
if (currentChapter.IsSpecial) return -1;
|
||||
|
|
|
@ -813,7 +813,7 @@ public class SeriesService : ISeriesService
|
|||
|
||||
private static double ExponentialSmoothing(IList<double> data, double alpha)
|
||||
{
|
||||
var forecast = data.First();
|
||||
var forecast = data[0];
|
||||
|
||||
foreach (var value in data)
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ public class StreamService : IStreamService
|
|||
var smartFilter = await _unitOfWork.AppUserSmartFilterRepository.GetById(smartFilterId);
|
||||
if (smartFilter == null) throw new KavitaException(await _localizationService.Translate(userId, "smart-filter-doesnt-exist"));
|
||||
|
||||
var stream = user?.DashboardStreams.FirstOrDefault(d => d.SmartFilter?.Id == smartFilterId);
|
||||
var stream = user.DashboardStreams.FirstOrDefault(d => d.SmartFilter?.Id == smartFilterId);
|
||||
if (stream != null) throw new KavitaException(await _localizationService.Translate(userId, "smart-filter-already-in-use"));
|
||||
|
||||
var maxOrder = user!.DashboardStreams.Max(d => d.Order);
|
||||
|
@ -159,7 +159,7 @@ public class StreamService : IStreamService
|
|||
var smartFilter = await _unitOfWork.AppUserSmartFilterRepository.GetById(smartFilterId);
|
||||
if (smartFilter == null) throw new KavitaException(await _localizationService.Translate(userId, "smart-filter-doesnt-exist"));
|
||||
|
||||
var stream = user?.SideNavStreams.FirstOrDefault(d => d.SmartFilter?.Id == smartFilterId);
|
||||
var stream = user.SideNavStreams.FirstOrDefault(d => d.SmartFilter?.Id == smartFilterId);
|
||||
if (stream != null) throw new KavitaException(await _localizationService.Translate(userId, "smart-filter-already-in-use"));
|
||||
|
||||
var maxOrder = user!.SideNavStreams.Max(d => d.Order);
|
||||
|
|
|
@ -72,7 +72,7 @@ public class TachiyomiService : ITachiyomiService
|
|||
if (looseLeafChapterVolume == null)
|
||||
{
|
||||
var volumeChapter = _mapper.Map<ChapterDto>(volumes
|
||||
.Last().Chapters
|
||||
[^1].Chapters
|
||||
.OrderBy(c => c.Number.AsFloat(), ChapterSortComparerZeroFirst.Default)
|
||||
.Last());
|
||||
if (volumeChapter.Number == "0")
|
||||
|
|
|
@ -179,7 +179,7 @@ public class LibraryWatcher : ILibraryWatcher
|
|||
/// <param name="e"></param>
|
||||
private void OnError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
_logger.LogError(e.GetException(), "[LibraryWatcher] An error occured, likely too many changes occured at once or the folder being watched was deleted. Restarting Watchers");
|
||||
_logger.LogError(e.GetException(), "[LibraryWatcher] An error occured, likely too many changes occured at once or the folder being watched was deleted. Restarting Watchers {Current}/{Total}", _bufferFullCounter, 3);
|
||||
bool condition;
|
||||
lock (Lock)
|
||||
{
|
||||
|
|
|
@ -312,7 +312,6 @@ public class ParseScannedFiles
|
|||
}
|
||||
|
||||
await _eventHub.SendMessageAsync(MessageFactory.NotificationProgress, MessageFactory.FileScanProgressEvent("File Scan Done", library.Name, ProgressEventType.Ended));
|
||||
return;
|
||||
|
||||
async Task ProcessFolder(IList<string> files, string folder)
|
||||
{
|
||||
|
|
|
@ -295,7 +295,7 @@ public class ProcessSeries : IProcessSeries
|
|||
if (series.Format == MangaFormat.Epub || series.Format == MangaFormat.Pdf && chapters.Count == 1)
|
||||
{
|
||||
series.Metadata.MaxCount = 1;
|
||||
} else if (series.Metadata.TotalCount == 1 && chapters.Count == 1 && chapters.First().IsSpecial)
|
||||
} else if (series.Metadata.TotalCount == 1 && chapters.Count == 1 && chapters[0].IsSpecial)
|
||||
{
|
||||
// If a series has a TotalCount of 1 and there is only a Special, mark it as Complete
|
||||
series.Metadata.MaxCount = series.Metadata.TotalCount;
|
||||
|
|
|
@ -347,6 +347,7 @@ public class Startup
|
|||
=>
|
||||
{
|
||||
opts.EnrichDiagnosticContext = LogEnricher.EnrichFromRequest;
|
||||
opts.IncludeQueryInRequestPath = true;
|
||||
});
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue