Polish 4 (#3577)
Co-authored-by: Zeoic <zeorgaming@gmail.com> Co-authored-by: Fesaa <77553571+Fesaa@users.noreply.github.com>
This commit is contained in:
parent
b38400c092
commit
0ffe0228e5
30 changed files with 339 additions and 115 deletions
|
@ -12,10 +12,11 @@
|
|||
<LangVersion>latestmajor</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<Delete Files="../openapi.json" />
|
||||
<Exec Command="swagger tofile --output ../openapi.json bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).dll v1" />
|
||||
</Target>
|
||||
<!-- Moved to GA -->
|
||||
<!-- <Target Name="PostBuild" AfterTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">-->
|
||||
<!-- <Delete Files="../openapi.json" />-->
|
||||
<!-- <Exec Command="swagger tofile --output ../openapi.json bin/$(Configuration)/$(TargetFramework)/$(AssemblyName).dll v1" />-->
|
||||
<!-- </Target>-->
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
|
|
|
@ -652,9 +652,9 @@ public class SeriesController : BaseApiController
|
|||
/// <param name="seriesId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("update-match")]
|
||||
public ActionResult UpdateSeriesMatch([FromQuery] int seriesId, [FromQuery] int aniListId)
|
||||
public ActionResult UpdateSeriesMatch([FromQuery] int seriesId, [FromQuery] int aniListId, [FromQuery] long? malId)
|
||||
{
|
||||
BackgroundJob.Enqueue(() => _externalMetadataService.FixSeriesMatch(seriesId, aniListId));
|
||||
BackgroundJob.Enqueue(() => _externalMetadataService.FixSeriesMatch(seriesId, aniListId, malId));
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
|
|
@ -213,9 +213,10 @@ public class ExternalSeriesMetadataRepository : IExternalSeriesMetadataRepositor
|
|||
{
|
||||
return await _context.Series
|
||||
.Where(s => !ExternalMetadataService.NonEligibleLibraryTypes.Contains(s.Library.Type))
|
||||
.WhereIf(includeStaleData, s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.ValidUntilUtc < DateTime.UtcNow)
|
||||
.Where(s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.ValidUntilUtc == DateTime.MinValue)
|
||||
.Where(s => s.Library.AllowMetadataMatching)
|
||||
.WhereIf(includeStaleData, s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.ValidUntilUtc < DateTime.UtcNow)
|
||||
.Where(s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.AniListId == 0)
|
||||
.Where(s => !s.IsBlacklisted && !s.DontMatch)
|
||||
.OrderByDescending(s => s.Library.Type)
|
||||
.ThenBy(s => s.NormalizedName)
|
||||
.Select(s => s.Id)
|
||||
|
@ -229,6 +230,7 @@ public class ExternalSeriesMetadataRepository : IExternalSeriesMetadataRepositor
|
|||
.Include(s => s.Library)
|
||||
.Include(s => s.ExternalSeriesMetadata)
|
||||
.Where(s => !ExternalMetadataService.NonEligibleLibraryTypes.Contains(s.Library.Type))
|
||||
.Where(s => s.Library.AllowMetadataMatching)
|
||||
.FilterMatchState(filter.MatchStateOption)
|
||||
.OrderBy(s => s.NormalizedName)
|
||||
.ProjectTo<ManageMatchSeriesDto>(_mapper.ConfigurationProvider)
|
||||
|
|
|
@ -18,6 +18,7 @@ using Kavita.Common.Extensions;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace API.Data.Repositories;
|
||||
#nullable enable
|
||||
|
||||
[Flags]
|
||||
public enum LibraryIncludes
|
||||
|
@ -260,7 +261,7 @@ public class LibraryRepository : ILibraryRepository
|
|||
public async Task<IList<LanguageDto>> GetAllLanguagesForLibrariesAsync(List<int>? libraryIds)
|
||||
{
|
||||
var ret = await _context.Series
|
||||
.WhereIf(libraryIds is {Count: > 0} , s => libraryIds.Contains(s.LibraryId))
|
||||
.WhereIf(libraryIds is {Count: > 0} , s => libraryIds!.Contains(s.LibraryId))
|
||||
.Select(s => s.Metadata.Language)
|
||||
.AsSplitQuery()
|
||||
.AsNoTracking()
|
||||
|
|
|
@ -19,11 +19,13 @@ public interface IScrobbleRepository
|
|||
void Attach(ScrobbleError error);
|
||||
void Remove(ScrobbleEvent evt);
|
||||
void Remove(IEnumerable<ScrobbleEvent> events);
|
||||
void Remove(IEnumerable<ScrobbleError> errors);
|
||||
void Update(ScrobbleEvent evt);
|
||||
Task<IList<ScrobbleEvent>> GetByEvent(ScrobbleEventType type, bool isProcessed = false);
|
||||
Task<IList<ScrobbleEvent>> GetProcessedEvents(int daysAgo);
|
||||
Task<bool> Exists(int userId, int seriesId, ScrobbleEventType eventType);
|
||||
Task<IEnumerable<ScrobbleErrorDto>> GetScrobbleErrors();
|
||||
Task<IList<ScrobbleError>> GetAllScrobbleErrorsForSeries(int seriesId);
|
||||
Task ClearScrobbleErrors();
|
||||
Task<bool> HasErrorForSeries(int seriesId);
|
||||
Task<ScrobbleEvent?> GetEvent(int userId, int seriesId, ScrobbleEventType eventType);
|
||||
|
@ -66,6 +68,11 @@ public class ScrobbleRepository : IScrobbleRepository
|
|||
_context.ScrobbleEvent.RemoveRange(events);
|
||||
}
|
||||
|
||||
public void Remove(IEnumerable<ScrobbleError> errors)
|
||||
{
|
||||
_context.ScrobbleError.RemoveRange(errors);
|
||||
}
|
||||
|
||||
public void Update(ScrobbleEvent evt)
|
||||
{
|
||||
_context.Entry(evt).State = EntityState.Modified;
|
||||
|
@ -113,6 +120,13 @@ public class ScrobbleRepository : IScrobbleRepository
|
|||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<ScrobbleError>> GetAllScrobbleErrorsForSeries(int seriesId)
|
||||
{
|
||||
return await _context.ScrobbleError
|
||||
.Where(e => e.SeriesId == seriesId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task ClearScrobbleErrors()
|
||||
{
|
||||
_context.ScrobbleError.RemoveRange(_context.ScrobbleError);
|
||||
|
@ -161,4 +175,5 @@ public class ScrobbleRepository : IScrobbleRepository
|
|||
return await _context.ScrobbleEvent.Where(e => e.SeriesId == seriesId)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -276,18 +276,18 @@ public static class Seed
|
|||
await context.SaveChangesAsync();
|
||||
|
||||
// Port, IpAddresses and LoggingLevel are managed in appSettings.json. Update the DB values to match
|
||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.Port).Value =
|
||||
(await context.ServerSetting.FirstAsync(s => s.Key == ServerSettingKey.Port)).Value =
|
||||
Configuration.Port + string.Empty;
|
||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.IpAddresses).Value =
|
||||
(await context.ServerSetting.FirstAsync(s => s.Key == ServerSettingKey.IpAddresses)).Value =
|
||||
Configuration.IpAddresses;
|
||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.CacheDirectory).Value =
|
||||
(await context.ServerSetting.FirstAsync(s => s.Key == ServerSettingKey.CacheDirectory)).Value =
|
||||
directoryService.CacheDirectory + string.Empty;
|
||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.BackupDirectory).Value =
|
||||
(await context.ServerSetting.FirstAsync(s => s.Key == ServerSettingKey.BackupDirectory)).Value =
|
||||
DirectoryService.BackupDirectory + string.Empty;
|
||||
context.ServerSetting.First(s => s.Key == ServerSettingKey.CacheSize).Value =
|
||||
(await context.ServerSetting.FirstAsync(s => s.Key == ServerSettingKey.CacheSize)).Value =
|
||||
Configuration.CacheSize + string.Empty;
|
||||
await context.SaveChangesAsync();
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public static async Task SeedMetadataSettings(DataContext context)
|
||||
|
|
|
@ -252,8 +252,6 @@ public static class SeriesFilter
|
|||
if (!condition) return queryable;
|
||||
|
||||
var subQuery = queryable
|
||||
.Include(s => s.Progress)
|
||||
.Where(s => s.Progress != null)
|
||||
.Select(s => new
|
||||
{
|
||||
SeriesId = s.Id,
|
||||
|
@ -372,7 +370,7 @@ public static class SeriesFilter
|
|||
|
||||
var subQuery = queryable
|
||||
.Include(s => s.Progress)
|
||||
.Where(s => s.Progress != null)
|
||||
.Where(s => s.Progress.Any())
|
||||
.Select(s => new
|
||||
{
|
||||
SeriesId = s.Id,
|
||||
|
@ -435,7 +433,7 @@ public static class SeriesFilter
|
|||
|
||||
var subQuery = queryable
|
||||
.Include(s => s.Progress)
|
||||
.Where(s => s.Progress != null)
|
||||
.Where(s => s.Progress.Any())
|
||||
.Select(s => new
|
||||
{
|
||||
SeriesId = s.Id,
|
||||
|
|
|
@ -311,8 +311,16 @@ public class BookService : IBookService
|
|||
|
||||
var imageFile = GetKeyForImage(book, image.Attributes[key].Value);
|
||||
image.Attributes.Remove(key);
|
||||
// UrlEncode here to transform ../ into an escaped version, which avoids blocking on nginx
|
||||
image.Attributes.Add(key, $"{apiBase}" + Uri.EscapeDataString(imageFile));
|
||||
|
||||
if (!imageFile.StartsWith("http"))
|
||||
{
|
||||
// UrlEncode here to transform ../ into an escaped version, which avoids blocking on nginx
|
||||
image.Attributes.Add(key, $"{apiBase}" + Uri.EscapeDataString(imageFile));
|
||||
}
|
||||
else
|
||||
{
|
||||
image.Attributes.Add(key, imageFile);
|
||||
}
|
||||
|
||||
// Add a custom class that the reader uses to ensure images stay within reader
|
||||
parent.AddClass("kavita-scale-width-container");
|
||||
|
|
|
@ -49,7 +49,7 @@ public interface IExternalMetadataService
|
|||
|
||||
Task<IList<MalStackDto>> GetStacksForUser(int userId);
|
||||
Task<IList<ExternalSeriesMatchDto>> MatchSeries(MatchSeriesDto dto);
|
||||
Task FixSeriesMatch(int seriesId, int anilistId);
|
||||
Task FixSeriesMatch(int seriesId, int anilistId, long? malId);
|
||||
Task UpdateSeriesDontMatch(int seriesId, bool dontMatch);
|
||||
Task<bool> WriteExternalMetadataToSeries(ExternalSeriesDetailDto externalMetadata, int seriesId);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
public async Task FetchExternalDataTask()
|
||||
{
|
||||
// Find all Series that are eligible and limit
|
||||
var ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25);
|
||||
var ids = await _unitOfWork.ExternalSeriesMetadataRepository.GetSeriesThatNeedExternalMetadata(25, false);
|
||||
if (ids.Count == 0) return;
|
||||
|
||||
_logger.LogInformation("[Kavita+ Data Refresh] Started Refreshing {Count} series data from Kavita+", ids.Count);
|
||||
|
@ -133,6 +133,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
/// </summary>
|
||||
/// <param name="seriesId"></param>
|
||||
/// <param name="libraryType"></param>
|
||||
/// <returns>If a successful match was made</returns>
|
||||
public async Task<bool> FetchSeriesMetadata(int seriesId, LibraryType libraryType)
|
||||
{
|
||||
if (!IsPlusEligible(libraryType)) return false;
|
||||
|
@ -150,8 +151,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
_logger.LogDebug("Prefetching Kavita+ data for Series {SeriesId}", seriesId);
|
||||
|
||||
// Prefetch SeriesDetail data
|
||||
await GetSeriesDetailPlus(seriesId, libraryType);
|
||||
return true;
|
||||
return await GetSeriesDetailPlus(seriesId, libraryType) != null;
|
||||
}
|
||||
|
||||
public async Task<IList<MalStackDto>> GetStacksForUser(int userId)
|
||||
|
@ -303,7 +303,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
/// </summary>
|
||||
/// <param name="seriesId"></param>
|
||||
/// <param name="anilistId"></param>
|
||||
public async Task FixSeriesMatch(int seriesId, int anilistId)
|
||||
public async Task FixSeriesMatch(int seriesId, int anilistId, long? malId)
|
||||
{
|
||||
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(seriesId, SeriesIncludes.Library);
|
||||
if (series == null) return;
|
||||
|
@ -317,7 +317,8 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
var metadata = await FetchExternalMetadataForSeries(seriesId, series.Library.Type, new PlusSeriesRequestDto()
|
||||
{
|
||||
AniListId = anilistId,
|
||||
SeriesName = string.Empty // Required field
|
||||
MalId = malId,
|
||||
SeriesName = series.Name // Required field, not used since AniList/Mal Id are passed
|
||||
});
|
||||
|
||||
if (metadata.Series == null)
|
||||
|
@ -329,6 +330,11 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
// Find all scrobble events and rewrite them to be the correct
|
||||
var events = await _unitOfWork.ScrobbleRepository.GetAllEventsForSeries(seriesId);
|
||||
_unitOfWork.ScrobbleRepository.Remove(events);
|
||||
|
||||
// Find all scrobble errors and remove them
|
||||
var errors = await _unitOfWork.ScrobbleRepository.GetAllScrobbleErrorsForSeries(seriesId);
|
||||
_unitOfWork.ScrobbleRepository.Remove(errors);
|
||||
|
||||
await _unitOfWork.CommitAsync();
|
||||
|
||||
// Regenerate all events for the series for all users
|
||||
|
@ -566,7 +572,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
return false;
|
||||
}
|
||||
|
||||
foreach (var relation in externalMetadataRelations)
|
||||
foreach (var relation in externalMetadataRelations.Where(r => r.Relation != RelationKind.Parent))
|
||||
{
|
||||
var names = new [] {relation.SeriesName.PreferredTitle, relation.SeriesName.RomajiTitle, relation.SeriesName.EnglishTitle, relation.SeriesName.NativeTitle};
|
||||
var relatedSeries = await _unitOfWork.SeriesRepository.GetSeriesByAnyName(
|
||||
|
|
|
@ -930,6 +930,7 @@ public class ScrobblingService : IScrobblingService
|
|||
|
||||
if (await _unitOfWork.ExternalSeriesMetadataRepository.IsBlacklistedSeries(evt.SeriesId))
|
||||
{
|
||||
_logger.LogInformation("Series {SeriesName} ({SeriesId}) can't be matched and thus cannot scrobble this event", evt.Series.Name, evt.SeriesId);
|
||||
_unitOfWork.ScrobbleRepository.Attach(new ScrobbleError()
|
||||
{
|
||||
Comment = UnknownSeriesErrorMessage,
|
||||
|
@ -942,6 +943,7 @@ public class ScrobblingService : IScrobblingService
|
|||
evt.ProcessDateUtc = DateTime.UtcNow;
|
||||
_unitOfWork.ScrobbleRepository.Update(evt);
|
||||
await _unitOfWork.CommitAsync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ using API.DTOs.Theme;
|
|||
using API.Entities;
|
||||
using API.Entities.Enums.Theme;
|
||||
using API.Extensions;
|
||||
using API.Services.Tasks.Scanner.Parser;
|
||||
using API.SignalR;
|
||||
using Flurl.Http;
|
||||
using HtmlAgilityPack;
|
||||
|
@ -192,7 +193,8 @@ public class ThemeService : IThemeService
|
|||
|
||||
private static List<string> GetPreviewUrls(IEnumerable<GitHubContent> themeContents)
|
||||
{
|
||||
return themeContents.Where(c => c.Name.ToLower().EndsWith(".jpg") || c.Name.ToLower().EndsWith(".png") )
|
||||
return themeContents
|
||||
.Where(c => Parser.IsImage(c.Name) )
|
||||
.Select(p => p.DownloadUrl)
|
||||
.ToList();
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
"Port": 5000,
|
||||
"IpAddresses": "",
|
||||
"BaseUrl": "/",
|
||||
"Cache": 50
|
||||
"Cache": 75
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue