Skip to content

Commit

Permalink
Smart Collection UI Changes (#3332)
Browse files Browse the repository at this point in the history
  • Loading branch information
majora2007 authored Nov 4, 2024
1 parent dcd281c commit 9e299d0
Show file tree
Hide file tree
Showing 29 changed files with 423 additions and 181 deletions.
26 changes: 20 additions & 6 deletions API/Controllers/ChapterController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,30 @@ public async Task<ActionResult<bool>> DeleteChapter(int chapterId)
if (chapter == null)
return BadRequest(_localizationService.Translate(User.GetUserId(), "chapter-doesnt-exist"));

var vol = (await _unitOfWork.VolumeRepository.GetVolumeAsync(chapter.VolumeId))!;
_unitOfWork.ChapterRepository.Remove(chapter);
var vol = await _unitOfWork.VolumeRepository.GetVolumeAsync(chapter.VolumeId, VolumeIncludes.Chapters);
if (vol == null) return BadRequest(_localizationService.Translate(User.GetUserId(), "volume-doesnt-exist"));

if (await _unitOfWork.CommitAsync())
// If there is only 1 chapter within the volume, then we need to remove the volume
var needToRemoveVolume = vol.Chapters.Count == 1;
if (needToRemoveVolume)
{
await _eventHub.SendMessageAsync(MessageFactory.ChapterRemoved, MessageFactory.ChapterRemovedEvent(chapter.Id, vol.SeriesId), false);
return Ok(true);
_unitOfWork.VolumeRepository.Remove(vol);
}
else
{
_unitOfWork.ChapterRepository.Remove(chapter);
}


if (!await _unitOfWork.CommitAsync()) return Ok(false);

await _eventHub.SendMessageAsync(MessageFactory.ChapterRemoved, MessageFactory.ChapterRemovedEvent(chapter.Id, vol.SeriesId), false);
if (needToRemoveVolume)
{
await _eventHub.SendMessageAsync(MessageFactory.VolumeRemoved, MessageFactory.VolumeRemovedEvent(chapter.VolumeId, vol.SeriesId), false);
}

return Ok(false);
return Ok(true);
}

/// <summary>
Expand Down
13 changes: 4 additions & 9 deletions API/Controllers/MetadataController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Threading.Tasks;
using API.Constants;
using API.Data;
using API.Data.Repositories;
using API.DTOs;
using API.DTOs.Filtering;
using API.DTOs.Metadata;
Expand Down Expand Up @@ -33,18 +34,12 @@ public class MetadataController(IUnitOfWork unitOfWork, ILocalizationService loc
/// <param name="libraryIds">String separated libraryIds or null for all genres</param>
/// <returns></returns>
[HttpGet("genres")]
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = new []{"libraryIds"})]
public async Task<ActionResult<IList<GenreTagDto>>> GetAllGenres(string? libraryIds)
[ResponseCache(CacheProfileName = ResponseCacheProfiles.Instant, VaryByQueryKeys = ["libraryIds", "context"])]
public async Task<ActionResult<IList<GenreTagDto>>> GetAllGenres(string? libraryIds, QueryContext context = QueryContext.None)
{
var ids = libraryIds?.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();

// NOTE: libraryIds isn't hooked up in the frontend
if (ids is {Count: > 0})
{
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(User.GetUserId(), ids));
}

return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(User.GetUserId()));
return Ok(await unitOfWork.GenreRepository.GetAllGenreDtosForLibrariesAsync(User.GetUserId(), ids, context));
}

/// <summary>
Expand Down
16 changes: 14 additions & 2 deletions API/Controllers/SettingsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDt
bookmarkDirectory = _directoryService.BookmarkDirectory;
}

var updateTask = false;
foreach (var setting in currentSettings)
{
if (setting.Key == ServerSettingKey.OnDeckProgressDays &&
Expand Down Expand Up @@ -204,7 +205,7 @@ public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDt
_unitOfWork.SettingsRepository.Update(setting);
}

UpdateSchedulingSettings(setting, updateSettingsDto);
updateTask = updateTask || UpdateSchedulingSettings(setting, updateSettingsDto);

UpdateEmailSettings(setting, updateSettingsDto);

Expand Down Expand Up @@ -348,6 +349,11 @@ public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDt
UpdateBookmarkDirectory(originalBookmarkDirectory, bookmarkDirectory);
}

if (updateTask)
{
BackgroundJob.Enqueue(() => _taskScheduler.ScheduleTasks());
}

if (updateSettingsDto.EnableFolderWatching)
{
BackgroundJob.Enqueue(() => _libraryWatcher.StartWatching());
Expand Down Expand Up @@ -379,25 +385,31 @@ private void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bo
_directoryService.ClearAndDeleteDirectory(originalBookmarkDirectory);
}

private void UpdateSchedulingSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)
private bool UpdateSchedulingSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)
{
if (setting.Key == ServerSettingKey.TaskBackup && updateSettingsDto.TaskBackup != setting.Value)
{
//if (updateSettingsDto.TotalBackup)
setting.Value = updateSettingsDto.TaskBackup;
_unitOfWork.SettingsRepository.Update(setting);

return true;
}

if (setting.Key == ServerSettingKey.TaskScan && updateSettingsDto.TaskScan != setting.Value)
{
setting.Value = updateSettingsDto.TaskScan;
_unitOfWork.SettingsRepository.Update(setting);
return true;
}

if (setting.Key == ServerSettingKey.TaskCleanup && updateSettingsDto.TaskCleanup != setting.Value)
{
setting.Value = updateSettingsDto.TaskCleanup;
_unitOfWork.SettingsRepository.Update(setting);
return true;
}
return false;
}

private void UpdateEmailSettings(ServerSetting setting, ServerSettingDto updateSettingsDto)
Expand Down
6 changes: 3 additions & 3 deletions API/Data/Repositories/GenreRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public interface IGenreRepository
Task<IList<Genre>> GetAllGenresAsync();
Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> normalizedNames);
Task RemoveAllGenreNoLongerAssociated(bool removeExternal = false);
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null);
Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null, QueryContext context = QueryContext.None);
Task<int> GetCountAsync();
Task<GenreTagDto> GetRandomGenre();
Task<GenreTagDto> GetGenreById(int id);
Expand Down Expand Up @@ -115,10 +115,10 @@ public async Task<IList<Genre>> GetAllGenresByNamesAsync(IEnumerable<string> nor
/// <param name="userId"></param>
/// <param name="libraryIds"></param>
/// <returns></returns>
public async Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null)
public async Task<IList<GenreTagDto>> GetAllGenreDtosForLibrariesAsync(int userId, IList<int>? libraryIds = null, QueryContext context = QueryContext.None)
{
var userRating = await _context.AppUser.GetUserAgeRestriction(userId);
var userLibs = await _context.Library.GetUserLibraries(userId).ToListAsync();
var userLibs = await _context.Library.GetUserLibraries(userId, context).ToListAsync();

if (libraryIds is {Count: > 0})
{
Expand Down
3 changes: 2 additions & 1 deletion API/Data/Repositories/SeriesRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public enum QueryContext
{
None = 1,
Search = 2,
[Obsolete("Use Dashboard")]
Recommended = 3,
Dashboard = 4,
}
Expand Down Expand Up @@ -1509,7 +1510,7 @@ public async Task<IEnumerable<SeriesDto>> GetSeriesForRelationKind(int userId, i

public async Task<PagedList<SeriesDto>> GetMoreIn(int userId, int libraryId, int genreId, UserParams userParams)
{
var libraryIds = GetLibraryIdsForUser(userId, libraryId, QueryContext.Recommended)
var libraryIds = GetLibraryIdsForUser(userId, libraryId, QueryContext.Dashboard)
.Where(id => libraryId == 0 || id == libraryId);
var usersSeriesIds = GetSeriesIdsForLibraryIds(libraryIds);

Expand Down
39 changes: 27 additions & 12 deletions API/Services/TaskScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using API.Services.Tasks.Metadata;
using API.SignalR;
using Hangfire;
using Kavita.Common.Helpers;
using Microsoft.Extensions.Logging;

namespace API.Services;
Expand Down Expand Up @@ -121,23 +122,32 @@ public TaskScheduler(ICacheService cacheService, ILogger<TaskScheduler> logger,
public async Task ScheduleTasks()
{
_logger.LogInformation("Scheduling reoccurring tasks");
var nonCronOptions = new List<string>(["disabled", "daily", "weekly"]);

var setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskScan)).Value;
if (setting != null)
if (setting == null || (!nonCronOptions.Contains(setting) && !CronHelper.IsValidCron(setting)))
{
var scanLibrarySetting = setting;
_logger.LogDebug("Scheduling Scan Library Task for {Setting}", scanLibrarySetting);
_logger.LogError("Scan Task has invalid cron, defaulting to Daily");
RecurringJob.AddOrUpdate(ScanLibrariesTaskId, () => ScanLibraries(false),
() => CronConverter.ConvertToCronNotation(scanLibrarySetting), RecurringJobOptions);
Cron.Daily, RecurringJobOptions);
}
else
{
var scanLibrarySetting = setting;
_logger.LogDebug("Scheduling Scan Library Task for {Setting}", scanLibrarySetting);
RecurringJob.AddOrUpdate(ScanLibrariesTaskId, () => ScanLibraries(false),
Cron.Daily, RecurringJobOptions);
() => CronConverter.ConvertToCronNotation(scanLibrarySetting), RecurringJobOptions);
}


setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskBackup)).Value;
if (setting != null)
if (setting == null || (!nonCronOptions.Contains(setting) && !CronHelper.IsValidCron(setting)))
{
_logger.LogError("Backup Task has invalid cron, defaulting to Daily");
RecurringJob.AddOrUpdate(BackupTaskId, () => _backupService.BackupDatabase(),
Cron.Weekly, RecurringJobOptions);
}
else
{
_logger.LogDebug("Scheduling Backup Task for {Setting}", setting);
var schedule = CronConverter.ConvertToCronNotation(setting);
Expand All @@ -149,16 +159,21 @@ public async Task ScheduleTasks()
RecurringJob.AddOrUpdate(BackupTaskId, () => _backupService.BackupDatabase(),
() => schedule, RecurringJobOptions);
}

setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskCleanup)).Value;
if (setting == null || (!nonCronOptions.Contains(setting) && !CronHelper.IsValidCron(setting)))
{
_logger.LogDebug("Scheduling Cleanup Task for {Setting}", setting);
RecurringJob.AddOrUpdate(CleanupTaskId, () => _cleanupService.Cleanup(),
CronConverter.ConvertToCronNotation(setting), RecurringJobOptions);
}
else
{
RecurringJob.AddOrUpdate(BackupTaskId, () => _backupService.BackupDatabase(),
Cron.Weekly, RecurringJobOptions);
_logger.LogError("Cleanup Task has invalid cron, defaulting to Daily");
RecurringJob.AddOrUpdate(CleanupTaskId, () => _cleanupService.Cleanup(),
Cron.Daily, RecurringJobOptions);
}

setting = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.TaskCleanup)).Value;
_logger.LogDebug("Scheduling Cleanup Task for {Setting}", setting);
RecurringJob.AddOrUpdate(CleanupTaskId, () => _cleanupService.Cleanup(),
CronConverter.ConvertToCronNotation(setting), RecurringJobOptions);

RecurringJob.AddOrUpdate(RemoveFromWantToReadTaskId, () => _cleanupService.CleanupWantToRead(),
Cron.Daily, RecurringJobOptions);
Expand Down
15 changes: 3 additions & 12 deletions UI/Web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions UI/Web/src/app/_models/collection-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export interface UserCollection {
source: ScrobbleProvider;
sourceUrl: string | null;
totalSourceCount: number;
/**
* HTML anchors separated by <br/>
*/
missingSeriesFromSource: string | null;
ageRating: AgeRating;
itemCount: number;
Expand Down
Loading

0 comments on commit 9e299d0

Please sign in to comment.