Metadata Downloading (#3525)

This commit is contained in:
Joe Milazzo 2025-02-05 16:16:44 -06:00 committed by GitHub
parent eb66763078
commit f4fd7230ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
108 changed files with 6296 additions and 484 deletions

View file

@ -81,7 +81,8 @@ public class LibraryController : BaseApiController
.WithIncludeInDashboard(dto.IncludeInDashboard)
.WithManageCollections(dto.ManageCollections)
.WithManageReadingLists(dto.ManageReadingLists)
.WIthAllowScrobbling(dto.AllowScrobbling)
.WithAllowScrobbling(dto.AllowScrobbling)
.WithAllowMetadataMatching(dto.AllowMetadataMatching)
.Build();
library.LibraryFileTypes = dto.FileGroupTypes

View file

@ -631,13 +631,13 @@ public class SeriesController : BaseApiController
/// <summary>
/// This will perform the fix match
/// </summary>
/// <param name="dto"></param>
/// <param name="aniListId"></param>
/// <param name="seriesId"></param>
/// <returns></returns>
[HttpPost("update-match")]
public async Task<ActionResult> UpdateSeriesMatch(ExternalSeriesDetailDto dto, [FromQuery] int seriesId)
public async Task<ActionResult> UpdateSeriesMatch([FromQuery] int seriesId, [FromQuery] int aniListId)
{
await _externalMetadataService.FixSeriesMatch(seriesId, dto);
await _externalMetadataService.FixSeriesMatch(seriesId, aniListId);
return Ok();
}

View file

@ -5,6 +5,7 @@ using System.Net;
using System.Threading.Tasks;
using API.Data;
using API.DTOs.Email;
using API.DTOs.KavitaPlus.Metadata;
using API.DTOs.Settings;
using API.Entities;
using API.Entities.Enums;
@ -534,4 +535,73 @@ public class SettingsController : BaseApiController
if (string.IsNullOrEmpty(user?.Email)) return BadRequest("Your account has no email on record. Cannot email.");
return Ok(await _emailService.SendTestEmail(user!.Email));
}
/// <summary>
/// Get the metadata settings for Kavita+ users.
/// </summary>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpGet("metadata-settings")]
public async Task<ActionResult<MetadataSettingsDto>> GetMetadataSettings()
{
return Ok(await _unitOfWork.SettingsRepository.GetMetadataSettingDto());
}
/// <summary>
/// Update the metadata settings for Kavita+ users
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpPost("metadata-settings")]
public async Task<ActionResult<MetadataSettingsDto>> UpdateMetadataSettings(MetadataSettingsDto dto)
{
var existingMetadataSetting = await _unitOfWork.SettingsRepository.GetMetadataSettings();
existingMetadataSetting.Enabled = dto.Enabled;
existingMetadataSetting.EnableSummary = dto.EnableSummary;
existingMetadataSetting.EnablePublicationStatus = dto.EnablePublicationStatus;
existingMetadataSetting.EnableRelationships = dto.EnableRelationships;
existingMetadataSetting.EnablePeople = dto.EnablePeople;
existingMetadataSetting.EnableStartDate = dto.EnableStartDate;
existingMetadataSetting.EnableGenres = dto.EnableGenres;
existingMetadataSetting.EnableTags = dto.EnableTags;
existingMetadataSetting.PersonRoles = dto.PersonRoles;
existingMetadataSetting.FirstLastPeopleNaming = dto.FirstLastPeopleNaming;
existingMetadataSetting.AgeRatingMappings = dto.AgeRatingMappings ?? [];
existingMetadataSetting.Blacklist = dto.Blacklist.DistinctBy(d => d.ToNormalized()).ToList() ?? [];
existingMetadataSetting.Whitelist = dto.Whitelist.DistinctBy(d => d.ToNormalized()).ToList() ?? [];
// Handle Field Mappings
if (dto.FieldMappings != null)
{
// Clear existing mappings
existingMetadataSetting.FieldMappings ??= [];
_unitOfWork.SettingsRepository.RemoveRange(existingMetadataSetting.FieldMappings);
existingMetadataSetting.FieldMappings.Clear();
// Add new mappings
foreach (var mappingDto in dto.FieldMappings)
{
existingMetadataSetting.FieldMappings.Add(new MetadataFieldMapping
{
SourceType = mappingDto.SourceType,
DestinationType = mappingDto.DestinationType,
SourceValue = mappingDto.SourceValue,
DestinationValue = mappingDto.DestinationValue,
ExcludeFromSource = mappingDto.ExcludeFromSource
});
}
}
// Save changes
await _unitOfWork.CommitAsync();
// Return updated settings
return Ok(await _unitOfWork.SettingsRepository.GetMetadataSettingDto());
}
}

View file

@ -8,6 +8,7 @@ using API.DTOs.Uploads;
using API.Entities.Enums;
using API.Extensions;
using API.Services;
using API.Services.Tasks.Metadata;
using API.SignalR;
using Flurl.Http;
using Microsoft.AspNetCore.Authorization;
@ -31,11 +32,12 @@ public class UploadController : BaseApiController
private readonly IEventHub _eventHub;
private readonly IReadingListService _readingListService;
private readonly ILocalizationService _localizationService;
private readonly ICoverDbService _coverDbService;
/// <inheritdoc />
public UploadController(IUnitOfWork unitOfWork, IImageService imageService, ILogger<UploadController> logger,
ITaskScheduler taskScheduler, IDirectoryService directoryService, IEventHub eventHub, IReadingListService readingListService,
ILocalizationService localizationService)
ILocalizationService localizationService, ICoverDbService coverDbService)
{
_unitOfWork = unitOfWork;
_imageService = imageService;
@ -45,6 +47,7 @@ public class UploadController : BaseApiController
_eventHub = eventHub;
_readingListService = readingListService;
_localizationService = localizationService;
_coverDbService = coverDbService;
}
/// <summary>
@ -495,34 +498,8 @@ public class UploadController : BaseApiController
var person = await _unitOfWork.PersonRepository.GetPersonById(uploadFileDto.Id);
if (person == null) return BadRequest(await _localizationService.Translate(User.GetUserId(), "person-doesnt-exist"));
if (!string.IsNullOrEmpty(uploadFileDto.Url))
{
var filePath = await CreateThumbnail(uploadFileDto, $"{ImageService.GetPersonFormat(uploadFileDto.Id)}");
if (!string.IsNullOrEmpty(filePath))
{
person.CoverImage = filePath;
person.CoverImageLocked = true;
_imageService.UpdateColorScape(person);
_unitOfWork.PersonRepository.Update(person);
}
}
else
{
person.CoverImage = string.Empty;
person.CoverImageLocked = false;
_imageService.UpdateColorScape(person);
_unitOfWork.PersonRepository.Update(person);
}
if (_unitOfWork.HasChanges())
{
await _unitOfWork.CommitAsync();
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
MessageFactory.CoverUpdateEvent(person.Id, MessageFactoryEntityTypes.Person), false);
return Ok();
}
await _coverDbService.SetPersonCoverImage(person, uploadFileDto.Url, true);
return Ok();
}
catch (Exception e)
{

View file

@ -135,6 +135,14 @@ public class UsersController : BaseApiController
existingPreferences.PdfScrollMode = preferencesDto.PdfScrollMode;
existingPreferences.PdfSpreadMode = preferencesDto.PdfSpreadMode;
if (await _licenseService.HasActiveLicense())
{
existingPreferences.AniListScrobblingEnabled = preferencesDto.AniListScrobblingEnabled;
existingPreferences.WantToReadSync = preferencesDto.WantToReadSync;
}
if (preferencesDto.Theme != null && existingPreferences.Theme.Id != preferencesDto.Theme?.Id)
{
var theme = await _unitOfWork.SiteThemeRepository.GetTheme(preferencesDto.Theme!.Id);
@ -147,6 +155,7 @@ public class UsersController : BaseApiController
existingPreferences.Locale = preferencesDto.Locale;
}
_unitOfWork.UserRepository.Update(existingPreferences);
if (!await _unitOfWork.CommitAsync()) return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-user-pref"));