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 c946be3fb..000000000 Binary files a/API/Data/kavita.db and /dev/null differ 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) {