Random Stuff (#3798)
This commit is contained in:
parent
574cf4b78e
commit
70f00895e8
63 changed files with 659 additions and 567 deletions
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||
<PackageReference Include="MailKit" Version="4.11.0" />
|
||||
<PackageReference Include="MailKit" Version="4.12.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
<PackageReference Include="Hangfire.InMemory" Version="1.0.0" />
|
||||
<PackageReference Include="Hangfire.MaximumConcurrentExecutions" Version="1.1.0" />
|
||||
<PackageReference Include="Hangfire.Storage.SQLite" Version="0.4.2" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
|
||||
<PackageReference Include="MarkdownDeep.NET.Core" Version="1.5.0.4" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.18" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||
<PackageReference Include="MimeTypeMapOfficial" Version="1.0.17" />
|
||||
<PackageReference Include="Nager.ArticleNumber" Version="1.0.7" />
|
||||
<PackageReference Include="NetVips" Version="3.0.0" />
|
||||
<PackageReference Include="NetVips" Version="3.0.1" />
|
||||
<PackageReference Include="NetVips.Native" Version="8.16.1" />
|
||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
|
|
@ -87,20 +87,20 @@
|
|||
<PackageReference Include="Serilog.Settings.Configuration" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.AspNetCore.SignalR" Version="0.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.SignalR.Core" Version="0.1.2" />
|
||||
<PackageReference Include="SharpCompress" Version="0.39.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.8.0.113526">
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.8" />
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.9.0.115408">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.8.0" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="22.0.13" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.3" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.9.0" />
|
||||
<PackageReference Include="System.IO.Abstractions" Version="22.0.14" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.4" />
|
||||
<PackageReference Include="VersOne.Epub" Version="3.3.3" />
|
||||
<PackageReference Include="VersOne.Epub" Version="3.3.4" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
@ -111,17 +111,16 @@
|
|||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Hangfire-log.db" />
|
||||
<None Remove="obj\**" />
|
||||
<None Remove="cache\**" />
|
||||
<None Remove="cache-long\**" />
|
||||
<None Remove="backups\**" />
|
||||
<None Remove="logs\**" />
|
||||
<None Remove="temp\**" />
|
||||
<None Remove="kavita.log" />
|
||||
<None Remove="kavita.db" />
|
||||
<None Remove="covers\**" />
|
||||
<None Remove="config\kavita.log" />
|
||||
<None Remove="config\kavita.db" />
|
||||
<None Remove="config\covers\**" />
|
||||
<None Remove="wwwroot\**" />
|
||||
<None Remove="cache\cache-long\**" />
|
||||
<None Remove="config\cache\**" />
|
||||
<None Remove="config\logs\**" />
|
||||
<None Remove="config\covers\**" />
|
||||
|
|
@ -139,6 +138,7 @@
|
|||
<Compile Remove="covers\**" />
|
||||
<Compile Remove="wwwroot\**" />
|
||||
<Compile Remove="config\cache\**" />
|
||||
<Compile Remove="cache\cache-long\**" />
|
||||
<Compile Remove="config\logs\**" />
|
||||
<Compile Remove="config\covers\**" />
|
||||
<Compile Remove="config\bookmarks\**" />
|
||||
|
|
@ -188,7 +188,6 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="config\cache-long\" />
|
||||
<Folder Include="config\themes" />
|
||||
<Content Include="EmailTemplates\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
|
|
|
|||
|
|
@ -4,14 +4,18 @@ using API.DTOs.Scrobbling;
|
|||
namespace API.DTOs.KavitaPlus.ExternalMetadata;
|
||||
#nullable enable
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to match some series from Kavita to an external id which K+ uses.
|
||||
/// </summary>
|
||||
internal sealed record MatchSeriesRequestDto
|
||||
{
|
||||
public string SeriesName { get; set; }
|
||||
public ICollection<string> AlternativeNames { get; set; }
|
||||
public required string SeriesName { get; set; }
|
||||
public ICollection<string> AlternativeNames { get; set; } = [];
|
||||
public int Year { get; set; } = 0;
|
||||
public string Query { get; set; }
|
||||
public string? Query { get; set; }
|
||||
public int? AniListId { get; set; }
|
||||
public long? MalId { get; set; }
|
||||
public string? HardcoverId { get; set; }
|
||||
public int? CbrId { get; set; }
|
||||
public PlusMediaFormat Format { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -26,7 +27,7 @@ public class SecurityEventMiddleware(RequestDelegate next)
|
|||
}
|
||||
catch (KavitaUnauthenticatedUserException ex)
|
||||
{
|
||||
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
|
||||
var ipAddress = context.Request.Headers["X-Forwarded-For"].FirstOrDefault() ?? context.Connection.RemoteIpAddress?.ToString();
|
||||
var requestMethod = context.Request.Method;
|
||||
var requestPath = context.Request.Path;
|
||||
var userAgent = context.Request.Headers.UserAgent;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
|
|
@ -48,15 +49,13 @@ public class Program
|
|||
|
||||
var directoryService = new DirectoryService(null!, new FileSystem());
|
||||
|
||||
|
||||
// Check if this is the first time running and if so, rename appsettings-init.json to appsettings.json
|
||||
HandleFirstRunConfiguration();
|
||||
|
||||
|
||||
// Before anything, check if JWT has been generated properly or if user still has default
|
||||
if (!Configuration.CheckIfJwtTokenSet() &&
|
||||
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != Environments.Development)
|
||||
{
|
||||
Log.Logger.Information("Generating JWT TokenKey for encrypting user sessions...");
|
||||
var rBytes = new byte[256];
|
||||
RandomNumberGenerator.Create().GetBytes(rBytes);
|
||||
Configuration.JwtToken = Convert.ToBase64String(rBytes).Replace("/", string.Empty);
|
||||
}
|
||||
EnsureJwtTokenKey();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -70,6 +69,7 @@ public class Program
|
|||
{
|
||||
var logger = services.GetRequiredService<ILogger<Program>>();
|
||||
var context = services.GetRequiredService<DataContext>();
|
||||
|
||||
var pendingMigrations = await context.Database.GetPendingMigrationsAsync();
|
||||
var isDbCreated = await context.Database.CanConnectAsync();
|
||||
if (isDbCreated && pendingMigrations.Any())
|
||||
|
|
@ -157,6 +157,26 @@ public class Program
|
|||
}
|
||||
}
|
||||
|
||||
private static void EnsureJwtTokenKey()
|
||||
{
|
||||
if (Configuration.CheckIfJwtTokenSet() || Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == Environments.Development) return;
|
||||
|
||||
Log.Logger.Information("Generating JWT TokenKey for encrypting user sessions...");
|
||||
var rBytes = new byte[256];
|
||||
RandomNumberGenerator.Create().GetBytes(rBytes);
|
||||
Configuration.JwtToken = Convert.ToBase64String(rBytes).Replace("/", string.Empty);
|
||||
}
|
||||
|
||||
private static void HandleFirstRunConfiguration()
|
||||
{
|
||||
var firstRunConfigFilePath = Path.Join(Directory.GetCurrentDirectory(), "config/appsettings-init.json");
|
||||
if (File.Exists(firstRunConfigFilePath) &&
|
||||
!File.Exists(Path.Join(Directory.GetCurrentDirectory(), "config/appsettings.json")))
|
||||
{
|
||||
File.Move(firstRunConfigFilePath, Path.Join(Directory.GetCurrentDirectory(), "config/appsettings.json"));
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<string> GetMigrationDirectory(DataContext context, IDirectoryService directoryService)
|
||||
{
|
||||
string? currentVersion = null;
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
AlternativeNames = altNames.Where(s => !string.IsNullOrEmpty(s)).ToList(),
|
||||
Year = series.Metadata.ReleaseYear,
|
||||
AniListId = potentialAnilistId ?? ScrobblingService.GetAniListId(series),
|
||||
MalId = potentialMalId ?? ScrobblingService.GetMalId(series),
|
||||
MalId = potentialMalId ?? ScrobblingService.GetMalId(series)
|
||||
};
|
||||
|
||||
var token = (await _unitOfWork.UserRepository.GetDefaultAdminUser()).AniListAccessToken;
|
||||
|
|
@ -792,7 +792,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
var characters = externalCharacters
|
||||
.Select(w => new PersonDto()
|
||||
{
|
||||
Name = w.Name,
|
||||
Name = w.Name.Trim(),
|
||||
AniListId = ScrobblingService.ExtractId<int>(w.Url, ScrobblingService.AniListCharacterWebsite),
|
||||
Description = StringHelper.CorrectUrls(StringHelper.RemoveSourceInDescription(StringHelper.SquashBreaklines(w.Description))),
|
||||
})
|
||||
|
|
@ -873,7 +873,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
var artists = upstreamArtists
|
||||
.Select(w => new PersonDto()
|
||||
{
|
||||
Name = w.Name,
|
||||
Name = w.Name.Trim(),
|
||||
AniListId = ScrobblingService.ExtractId<int>(w.Url, ScrobblingService.AniListStaffWebsite),
|
||||
Description = StringHelper.CorrectUrls(StringHelper.RemoveSourceInDescription(StringHelper.SquashBreaklines(w.Description))),
|
||||
})
|
||||
|
|
@ -929,7 +929,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
var writers = upstreamWriters
|
||||
.Select(w => new PersonDto()
|
||||
{
|
||||
Name = w.Name,
|
||||
Name = w.Name.Trim(),
|
||||
AniListId = ScrobblingService.ExtractId<int>(w.Url, ScrobblingService.AniListStaffWebsite),
|
||||
Description = StringHelper.CorrectUrls(StringHelper.RemoveSourceInDescription(StringHelper.SquashBreaklines(w.Description))),
|
||||
})
|
||||
|
|
@ -1353,7 +1353,7 @@ public class ExternalMetadataService : IExternalMetadataService
|
|||
var people = staff!
|
||||
.Select(w => new PersonDto()
|
||||
{
|
||||
Name = w,
|
||||
Name = w.Trim(),
|
||||
})
|
||||
.Concat(chapter.People
|
||||
.Where(p => p.Role == role)
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ public class CoverDbService : ICoverDbService
|
|||
else
|
||||
{
|
||||
_directoryService.DeleteFiles([tempFullPath]);
|
||||
person.CoverImage = Path.GetFileName(existingPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -651,6 +651,7 @@ public class CoverDbService : ICoverDbService
|
|||
else
|
||||
{
|
||||
_directoryService.DeleteFiles([tempFullPath]);
|
||||
return;
|
||||
}
|
||||
|
||||
chapter.CoverImage = finalFileName;
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ public class LibraryWatcher : ILibraryWatcher
|
|||
if (rootFolder.Count == 0) return string.Empty;
|
||||
|
||||
// Select the first folder and join with library folder, this should give us the folder to scan.
|
||||
return Parser.Parser.NormalizePath(_directoryService.FileSystem.Path.Join(libraryFolder, rootFolder[rootFolder.Count - 1]));
|
||||
return Parser.Parser.NormalizePath(_directoryService.FileSystem.Path.Join(libraryFolder, rootFolder[^1]));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public interface IVersionUpdaterService
|
|||
Task PushUpdate(UpdateNotificationDto update);
|
||||
Task<IList<UpdateNotificationDto>> GetAllReleases(int count = 0);
|
||||
Task<int> GetNumberOfReleasesBehind(bool stableOnly = false);
|
||||
void BustGithubCache();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -384,7 +385,7 @@ public partial class VersionUpdaterService : IVersionUpdaterService
|
|||
if (DateTime.UtcNow - fileInfo.LastWriteTimeUtc <= CacheDuration)
|
||||
{
|
||||
var cachedData = await File.ReadAllTextAsync(_cacheLatestReleaseFilePath);
|
||||
return System.Text.Json.JsonSerializer.Deserialize<UpdateNotificationDto>(cachedData);
|
||||
return JsonSerializer.Deserialize<UpdateNotificationDto>(cachedData);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -407,7 +408,7 @@ public partial class VersionUpdaterService : IVersionUpdaterService
|
|||
{
|
||||
try
|
||||
{
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(update, JsonOptions);
|
||||
var json = JsonSerializer.Serialize(update, JsonOptions);
|
||||
await File.WriteAllTextAsync(_cacheLatestReleaseFilePath, json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -446,6 +447,21 @@ public partial class VersionUpdaterService : IVersionUpdaterService
|
|||
.Count(u => u.IsReleaseNewer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the Github cache
|
||||
/// </summary>
|
||||
public void BustGithubCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(_cacheFilePath);
|
||||
File.Delete(_cacheLatestReleaseFilePath);
|
||||
} catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clear Github cache");
|
||||
}
|
||||
}
|
||||
|
||||
private UpdateNotificationDto? CreateDto(GithubReleaseMetadata? update)
|
||||
{
|
||||
if (update == null || string.IsNullOrEmpty(update.Tag_Name)) return null;
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ public class Startup
|
|||
{
|
||||
_config = config;
|
||||
_env = env;
|
||||
|
||||
// Disable Hangfire Automatic Retry
|
||||
GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
|
|
@ -223,7 +226,7 @@ public class Startup
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env,
|
||||
IHostApplicationLifetime applicationLifetime, IServiceProvider serviceProvider, ICacheService cacheService,
|
||||
IDirectoryService directoryService, IUnitOfWork unitOfWork, IBackupService backupService, IImageService imageService)
|
||||
IDirectoryService directoryService, IUnitOfWork unitOfWork, IBackupService backupService, IImageService imageService, IVersionUpdaterService versionService)
|
||||
{
|
||||
|
||||
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
|
||||
|
|
@ -235,9 +238,10 @@ public class Startup
|
|||
// Apply all migrations on startup
|
||||
var dataContext = serviceProvider.GetRequiredService<DataContext>();
|
||||
|
||||
|
||||
logger.LogInformation("Running Migrations");
|
||||
|
||||
#region Migrations
|
||||
|
||||
// v0.7.9
|
||||
await MigrateUserLibrarySideNavStream.Migrate(unitOfWork, dataContext, logger);
|
||||
|
||||
|
|
@ -289,13 +293,23 @@ public class Startup
|
|||
await ManualMigrateScrobbleSpecials.Migrate(dataContext, logger);
|
||||
await ManualMigrateScrobbleEventGen.Migrate(dataContext, logger);
|
||||
|
||||
#endregion
|
||||
|
||||
// Update the version in the DB after all migrations are run
|
||||
var installVersion = await unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion);
|
||||
var isVersionDifferent = installVersion.Value != BuildInfo.Version.ToString();
|
||||
installVersion.Value = BuildInfo.Version.ToString();
|
||||
unitOfWork.SettingsRepository.Update(installVersion);
|
||||
await unitOfWork.CommitAsync();
|
||||
|
||||
logger.LogInformation("Running Migrations - complete");
|
||||
|
||||
if (isVersionDifferent)
|
||||
{
|
||||
// Clear the Github cache so update stuff shows correctly
|
||||
versionService.BustGithubCache();
|
||||
}
|
||||
|
||||
}).GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue