From 7790cf31fdcc946c36e223d28a65b49b951415ff Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Thu, 1 Apr 2021 16:11:06 -0500 Subject: [PATCH] In Progress Query Update (#145) * Fixed a bug where chapter cover images weren't being updated due to a missed not. * Removed a piece of code that was needed for upgrading, since all beta users agreed to wipe db. * Fixed InProgress to properly respect order and show more recent activity first. Issue is with IEntityDate LastModified not updating in DataContext. * Updated dependencies to lastest stable. * LastModified on Volumes wasn't updating, validated it does update when data is changed. --- API.Tests/API.Tests.csproj | 4 ++-- API/API.csproj | 26 +++++++++++++------------- API/Controllers/ImageController.cs | 6 +++--- API/Controllers/ReaderController.cs | 13 +++++++++---- API/Data/DataContext.cs | 5 +++++ API/Data/SeriesRepository.cs | 4 ++-- API/Data/kavita.db | Bin 188416 -> 0 bytes API/Extensions/FileInfoExtensions.cs | 4 ++-- API/Services/MetadataService.cs | 4 ++-- API/Services/Tasks/ScannerService.cs | 12 ------------ 10 files changed, 38 insertions(+), 40 deletions(-) delete mode 100644 API/Data/kavita.db diff --git a/API.Tests/API.Tests.csproj b/API.Tests/API.Tests.csproj index 11597cb99..c1e0fa046 100644 --- a/API.Tests/API.Tests.csproj +++ b/API.Tests/API.Tests.csproj @@ -7,14 +7,14 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/API/API.csproj b/API/API.csproj index 2c6c68cc7..68c02f049 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -11,30 +11,30 @@ - - - + + + - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/API/Controllers/ImageController.cs b/API/Controllers/ImageController.cs index 62fbd51ae..b05f99409 100644 --- a/API/Controllers/ImageController.cs +++ b/API/Controllers/ImageController.cs @@ -22,7 +22,7 @@ namespace API.Controllers const string format = "jpeg"; Response.AddCacheHeader(content); - return File(content, "image/" + format); + return File(content, "image/" + format, $"chapterId"); } [HttpGet("volume-cover")] @@ -33,7 +33,7 @@ namespace API.Controllers const string format = "jpeg"; Response.AddCacheHeader(content); - return File(content, "image/" + format); + return File(content, "image/" + format, $"volumeId"); } [HttpGet("series-cover")] @@ -44,7 +44,7 @@ namespace API.Controllers const string format = "jpeg"; Response.AddCacheHeader(content); - return File(content, "image/" + format); + return File(content, "image/" + format, $"seriesId"); } } } \ No newline at end of file diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs index d157980ad..b2eb50ee1 100644 --- a/API/Controllers/ReaderController.cs +++ b/API/Controllers/ReaderController.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -19,14 +20,16 @@ namespace API.Controllers private readonly ICacheService _cacheService; private readonly ILogger _logger; private readonly IUnitOfWork _unitOfWork; + private readonly DataContext _dataContext; public ReaderController(IDirectoryService directoryService, ICacheService cacheService, - ILogger logger, IUnitOfWork unitOfWork) + ILogger logger, IUnitOfWork unitOfWork, DataContext dataContext) { _directoryService = directoryService; _cacheService = cacheService; _logger = logger; _unitOfWork = unitOfWork; + _dataContext = dataContext; } [HttpGet("image")] @@ -218,7 +221,8 @@ namespace API.Controllers PagesRead = bookmarkDto.PageNum, VolumeId = bookmarkDto.VolumeId, SeriesId = bookmarkDto.SeriesId, - ChapterId = bookmarkDto.ChapterId + ChapterId = bookmarkDto.ChapterId, + LastModified = DateTime.Now }); } else @@ -226,8 +230,9 @@ namespace API.Controllers userProgress.PagesRead = bookmarkDto.PageNum; userProgress.SeriesId = bookmarkDto.SeriesId; userProgress.VolumeId = bookmarkDto.VolumeId; + userProgress.LastModified = DateTime.Now; } - + _unitOfWork.UserRepository.Update(user); if (await _unitOfWork.Complete()) diff --git a/API/Data/DataContext.cs b/API/Data/DataContext.cs index f6626d2a8..9f7437cc3 100644 --- a/API/Data/DataContext.cs +++ b/API/Data/DataContext.cs @@ -47,11 +47,16 @@ namespace API.Data .HasForeignKey(ur => ur.RoleId) .IsRequired(); } + void OnEntityTracked(object sender, EntityTrackedEventArgs e) { if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IEntityDate entity) + { entity.Created = DateTime.Now; + entity.LastModified = DateTime.Now; + } + } void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e) diff --git a/API/Data/SeriesRepository.cs b/API/Data/SeriesRepository.cs index b9bae9773..7124f0932 100644 --- a/API/Data/SeriesRepository.cs +++ b/API/Data/SeriesRepository.cs @@ -315,13 +315,13 @@ namespace API.Data && s.PagesRead > 0 && s.PagesRead < s.Series.Pages && (libraryId <= 0 || s.Series.LibraryId == libraryId)) + .OrderByDescending(s => s.LastModified) + .Take(limit) .Select(s => s.Series.Id); var series = await _context.Series .Where(s => seriesWithProgress.Contains(s.Id)) - .OrderByDescending(s => s.LastModified) - .Take(limit) .ProjectTo(_mapper.ConfigurationProvider) .AsNoTracking() .ToListAsync(); diff --git a/API/Data/kavita.db b/API/Data/kavita.db deleted file mode 100644 index c946be3fb4ca693f60d7a24fb138e9f95c1f8081..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188416 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 BhbjO7 diff --git a/API/Extensions/FileInfoExtensions.cs b/API/Extensions/FileInfoExtensions.cs index d96b06de6..82f6e663f 100644 --- a/API/Extensions/FileInfoExtensions.cs +++ b/API/Extensions/FileInfoExtensions.cs @@ -10,9 +10,9 @@ namespace API.Extensions return comparison.Equals(fileInfo.LastWriteTime); } - public static bool IsLastWriteOlder(this FileInfo fileInfo, DateTime comparison) + public static bool IsLastWriteLessThan(this FileInfo fileInfo, DateTime comparison) { - return comparison > fileInfo.LastWriteTime; + return fileInfo.LastWriteTime < comparison; } } } \ No newline at end of file diff --git a/API/Services/MetadataService.cs b/API/Services/MetadataService.cs index 405e4c7e1..889bde5f9 100644 --- a/API/Services/MetadataService.cs +++ b/API/Services/MetadataService.cs @@ -33,7 +33,7 @@ namespace API.Services public void UpdateMetadata(Chapter chapter, bool forceUpdate) { var firstFile = chapter.Files.OrderBy(x => x.Chapter).FirstOrDefault(); - if (ShouldFindCoverImage(chapter.CoverImage, forceUpdate) && firstFile != null && new FileInfo(firstFile.FilePath).IsLastWriteOlder(firstFile.LastModified)) + if (ShouldFindCoverImage(chapter.CoverImage, forceUpdate) && firstFile != null && !new FileInfo(firstFile.FilePath).IsLastWriteLessThan(firstFile.LastModified)) { chapter.Files ??= new List(); chapter.CoverImage = _archiveService.GetCoverImage(firstFile.FilePath, true); @@ -53,7 +53,7 @@ namespace API.Services // Skip calculating Cover Image (I/O) if the chapter already has it set if (firstChapter == null || ShouldFindCoverImage(firstChapter.CoverImage)) { - if (firstFile != null && !new FileInfo(firstFile.FilePath).IsLastWriteOlder(firstFile.LastModified)) + if (firstFile != null && !new FileInfo(firstFile.FilePath).IsLastWriteLessThan(firstFile.LastModified)) { volume.CoverImage = _archiveService.GetCoverImage(firstFile.FilePath, true); } diff --git a/API/Services/Tasks/ScannerService.cs b/API/Services/Tasks/ScannerService.cs index d51f1207a..96e9620f1 100644 --- a/API/Services/Tasks/ScannerService.cs +++ b/API/Services/Tasks/ScannerService.cs @@ -261,18 +261,6 @@ namespace API.Services.Tasks var chapter = info.IsSpecial ? volume.Chapters.SingleOrDefault(c => c.Range == info.Filename || (c.Files.Select(f => f.FilePath).Contains(info.FullFilePath))) : volume.Chapters.SingleOrDefault(c => c.Range == info.Chapters); - if (info.IsSpecial && chapter != null && chapter.Files.Count > 1) - { - var fileToKeep = chapter.Files.SingleOrDefault(f => f.FilePath == info.FullFilePath); - if (fileToKeep != null) - { - chapter.Files = new List() - { - fileToKeep - }; - } - } - if (chapter == null) {