Last PR before Release (#2692)

This commit is contained in:
Joe Milazzo 2024-02-05 18:58:03 -06:00 committed by GitHub
parent 07e96389fb
commit 5cf6077dfd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 3801 additions and 2044 deletions

View file

@ -18,50 +18,62 @@ public static class MigrateWantToReadExport
{
public static async Task Migrate(DataContext dataContext, IDirectoryService directoryService, ILogger<Program> logger)
{
var importFile = Path.Join(directoryService.ConfigDirectory, "want-to-read-migration.csv");
if (File.Exists(importFile))
{
logger.LogCritical(
"Running MigrateWantToReadExport migration - Completed. This is not an error");
return;
}
logger.LogCritical(
"Running MigrateWantToReadExport migration - Please be patient, this may take some time. This is not an error");
await using var command = dataContext.Database.GetDbConnection().CreateCommand();
command.CommandText = "Select AppUserId, Id from Series WHERE AppUserId IS NOT NULL ORDER BY AppUserId;";
await dataContext.Database.OpenConnectionAsync();
await using var result = await command.ExecuteReaderAsync();
await using var writer = new StreamWriter(Path.Join(directoryService.ConfigDirectory, "want-to-read-migration.csv"));
await using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
// Write header
csvWriter.WriteField("AppUserId");
csvWriter.WriteField("Id");
await csvWriter.NextRecordAsync();
// Write data
while (await result.ReadAsync())
{
var appUserId = result["AppUserId"].ToString();
var id = result["Id"].ToString();
csvWriter.WriteField(appUserId);
csvWriter.WriteField(id);
await csvWriter.NextRecordAsync();
}
try
{
await dataContext.Database.CloseConnectionAsync();
writer.Close();
} catch (Exception) {/* Swallow */}
var importFile = Path.Join(directoryService.ConfigDirectory, "want-to-read-migration.csv");
if (File.Exists(importFile))
{
logger.LogCritical(
"Running MigrateWantToReadExport migration - Completed. This is not an error");
return;
}
logger.LogCritical(
"Running MigrateWantToReadExport migration - Completed. This is not an error");
logger.LogCritical(
"Running MigrateWantToReadExport migration - Please be patient, this may take some time. This is not an error");
await using var command = dataContext.Database.GetDbConnection().CreateCommand();
command.CommandText = "Select AppUserId, Id from Series WHERE AppUserId IS NOT NULL ORDER BY AppUserId;";
await dataContext.Database.OpenConnectionAsync();
await using var result = await command.ExecuteReaderAsync();
await using var writer =
new StreamWriter(Path.Join(directoryService.ConfigDirectory, "want-to-read-migration.csv"));
await using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
// Write header
csvWriter.WriteField("AppUserId");
csvWriter.WriteField("Id");
await csvWriter.NextRecordAsync();
// Write data
while (await result.ReadAsync())
{
var appUserId = result["AppUserId"].ToString();
var id = result["Id"].ToString();
csvWriter.WriteField(appUserId);
csvWriter.WriteField(id);
await csvWriter.NextRecordAsync();
}
try
{
await dataContext.Database.CloseConnectionAsync();
writer.Close();
}
catch (Exception)
{
/* Swallow */
}
logger.LogCritical(
"Running MigrateWantToReadExport migration - Completed. This is not an error");
}
catch (Exception ex)
{
// On new installs, the db isn't setup yet, so this has nothing to do
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
/// <inheritdoc />
public partial class ScrobbleEventError : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<float>(
name: "VolumeNumber",
table: "ScrobbleEvent",
type: "REAL",
nullable: true,
oldClrType: typeof(int),
oldType: "INTEGER",
oldNullable: true);
migrationBuilder.AddColumn<string>(
name: "ErrorDetails",
table: "ScrobbleEvent",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsErrored",
table: "ScrobbleEvent",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ErrorDetails",
table: "ScrobbleEvent");
migrationBuilder.DropColumn(
name: "IsErrored",
table: "ScrobbleEvent");
migrationBuilder.AlterColumn<int>(
name: "VolumeNumber",
table: "ScrobbleEvent",
type: "INTEGER",
nullable: true,
oldClrType: typeof(float),
oldType: "REAL",
oldNullable: true);
}
}
}

View file

@ -1522,9 +1522,15 @@ namespace API.Data.Migrations
b.Property<DateTime>("CreatedUtc")
.HasColumnType("TEXT");
b.Property<string>("ErrorDetails")
.HasColumnType("TEXT");
b.Property<int>("Format")
.HasColumnType("INTEGER");
b.Property<bool>("IsErrored")
.HasColumnType("INTEGER");
b.Property<bool>("IsProcessed")
.HasColumnType("INTEGER");
@ -1558,8 +1564,8 @@ namespace API.Data.Migrations
b.Property<int>("SeriesId")
.HasColumnType("INTEGER");
b.Property<int?>("VolumeNumber")
.HasColumnType("INTEGER");
b.Property<float?>("VolumeNumber")
.HasColumnType("REAL");
b.HasKey("Id");

View file

@ -8,6 +8,7 @@ using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
namespace API.Data.Repositories;
#nullable enable
public interface IAppUserSmartFilterRepository
{
@ -55,6 +56,7 @@ public class AppUserSmartFilterRepository : IAppUserSmartFilterRepository
public async Task<AppUserSmartFilter?> GetById(int smartFilterId)
{
return await _context.AppUserSmartFilter.FirstOrDefaultAsync(d => d.Id == smartFilterId);
return await _context.AppUserSmartFilter
.FirstOrDefaultAsync(d => d.Id == smartFilterId);
}
}

View file

@ -14,6 +14,7 @@ using AutoMapper.QueryableExtensions;
using Microsoft.EntityFrameworkCore;
namespace API.Data.Repositories;
#nullable enable
[Flags]
public enum ChapterIncludes

View file

@ -5,12 +5,14 @@ using System.Threading.Tasks;
using API.Constants;
using API.DTOs;
using API.DTOs.Recommendation;
using API.DTOs.Scrobbling;
using API.DTOs.SeriesDetail;
using API.Entities;
using API.Entities.Enums;
using API.Entities.Metadata;
using API.Extensions;
using API.Extensions.QueryExtensions;
using API.Services.Plus;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using Microsoft.AspNetCore.Identity;
@ -31,8 +33,9 @@ public interface IExternalSeriesMetadataRepository
Task<SeriesDetailPlusDto> GetSeriesDetailPlusDto(int seriesId);
Task LinkRecommendationsToSeries(Series series);
Task<bool> IsBlacklistedSeries(int seriesId);
Task CreateBlacklistedSeries(int seriesId);
Task CreateBlacklistedSeries(int seriesId, bool saveChanges = true);
Task RemoveFromBlacklist(int seriesId);
Task<IList<int>> GetAllSeriesIdsWithoutMetadata(int limit);
}
public class ExternalSeriesMetadataRepository : IExternalSeriesMetadataRepository
@ -197,14 +200,19 @@ public class ExternalSeriesMetadataRepository : IExternalSeriesMetadataRepositor
/// Creates a new instance against SeriesId and Saves to the DB
/// </summary>
/// <param name="seriesId"></param>
public async Task CreateBlacklistedSeries(int seriesId)
/// <param name="saveChanges"></param>
public async Task CreateBlacklistedSeries(int seriesId, bool saveChanges = true)
{
if (seriesId <= 0) return;
if (seriesId <= 0 || await _context.SeriesBlacklist.AnyAsync(s => s.SeriesId == seriesId)) return;
await _context.SeriesBlacklist.AddAsync(new SeriesBlacklist()
{
SeriesId = seriesId
});
await _context.SaveChangesAsync();
if (saveChanges)
{
await _context.SaveChangesAsync();
}
}
/// <summary>
@ -224,4 +232,16 @@ public class ExternalSeriesMetadataRepository : IExternalSeriesMetadataRepositor
await _context.SaveChangesAsync();
}
}
public async Task<IList<int>> GetAllSeriesIdsWithoutMetadata(int limit)
{
return await _context.Series
.Where(s => !ExternalMetadataService.NonEligibleLibraryTypes.Contains(s.Library.Type))
.Where(s => s.ExternalSeriesMetadata == null || s.ExternalSeriesMetadata.ValidUntilUtc < DateTime.UtcNow)
.OrderByDescending(s => s.Library.Type)
.ThenBy(s => s.NormalizedName)
.Select(s => s.Id)
.Take(limit)
.ToListAsync();
}
}