Polish for Release (#3714)

This commit is contained in:
Joe Milazzo 2025-04-08 17:25:37 -06:00 committed by GitHub
parent 9d9938bce2
commit c80d046fc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 3611 additions and 41 deletions

View file

@ -270,4 +270,15 @@ public class ScrobblingController : BaseApiController
await _unitOfWork.CommitAsync();
return Ok();
}
/// <summary>
/// Has the logged in user ran scrobble generation
/// </summary>
/// <returns></returns>
[HttpGet("has-ran-scrobble-gen")]
public async Task<ActionResult<bool>> HasRanScrobbleGen()
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId());
return Ok(user is {HasRunScrobbleEventGeneration: true});
}
}

View file

@ -1,4 +1,5 @@

using System;
using API.DTOs.Account;
namespace API.DTOs;

View file

@ -0,0 +1,55 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using API.Entities.History;
using API.Services.Tasks.Scanner.Parser;
using Kavita.Common.EnvironmentInfo;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace API.Data.ManualMigrations;
/// <summary>
/// v0.8.6 - Manually check when a user triggers scrobble event generation
/// </summary>
public static class ManualMigrateScrobbleEventGen
{
public static async Task Migrate(DataContext context, ILogger<Program> logger)
{
if (await context.ManualMigrationHistory.AnyAsync(m => m.Name == "ManualMigrateScrobbleEventGen"))
{
return;
}
logger.LogCritical("Running ManualMigrateScrobbleEventGen migration - Please be patient, this may take some time. This is not an error");
var users = await context.Users
.Where(u => u.AniListAccessToken != null)
.ToListAsync();
foreach (var user in users)
{
if (await context.ScrobbleEvent.AnyAsync(se => se.AppUserId == user.Id))
{
user.HasRunScrobbleEventGeneration = true;
user.ScrobbleEventGenerationRan = DateTime.UtcNow;
context.AppUser.Update(user);
}
}
if (context.ChangeTracker.HasChanges())
{
await context.SaveChangesAsync();
}
await context.ManualMigrationHistory.AddAsync(new ManualMigrationHistory()
{
Name = "ManualMigrateScrobbleEventGen",
ProductVersion = BuildInfo.Version.ToString(),
RanAt = DateTime.UtcNow
});
await context.SaveChangesAsync();
logger.LogCritical("Running ManualMigrateScrobbleEventGen migration - Completed. This is not an error");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
/// <inheritdoc />
public partial class ScrobbleGenerationDbCapture : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "HasRunScrobbleEventGeneration",
table: "AspNetUsers",
type: "INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<DateTime>(
name: "ScrobbleEventGenerationRan",
table: "AspNetUsers",
type: "TEXT",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "HasRunScrobbleEventGeneration",
table: "AspNetUsers");
migrationBuilder.DropColumn(
name: "ScrobbleEventGenerationRan",
table: "AspNetUsers");
}
}
}

View file

@ -85,6 +85,9 @@ namespace API.Data.Migrations
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<bool>("HasRunScrobbleEventGeneration")
.HasColumnType("INTEGER");
b.Property<DateTime>("LastActive")
.HasColumnType("TEXT");
@ -124,6 +127,9 @@ namespace API.Data.Migrations
.IsConcurrencyToken()
.HasColumnType("INTEGER");
b.Property<DateTime>("ScrobbleEventGenerationRan")
.HasColumnType("TEXT");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");

View file

@ -76,6 +76,16 @@ public class AppUser : IdentityUser<int>, IHasConcurrencyToken
/// </summary>
public string? MalAccessToken { get; set; }
/// <summary>
/// Has the user ran Scrobble Event Generation
/// </summary>
/// <remarks>Only applicable for Kavita+ and when a Token is present</remarks>
public bool HasRunScrobbleEventGeneration { get; set; }
/// <summary>
/// The timestamp of when Scrobble Event Generation ran (Utc)
/// </summary>
/// <remarks>Kavita+ only</remarks>
public DateTime ScrobbleEventGenerationRan { get; set; }
/// <summary>

View file

@ -624,8 +624,15 @@ public class ScrobblingService : IScrobblingService
{
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(userId);
if (user == null || string.IsNullOrEmpty(user.AniListAccessToken)) return;
if (user.HasRunScrobbleEventGeneration)
{
_logger.LogWarning("User {UserName} has already run scrobble event generation, Kavita will not generate more events", user.UserName);
return;
}
}
var libAllowsScrobbling = (await _unitOfWork.LibraryRepository.GetLibrariesAsync())
.ToDictionary(lib => lib.Id, lib => lib.AllowScrobbling);
@ -667,6 +674,14 @@ public class ScrobblingService : IScrobblingService
if (series.PagesRead <= 0) continue; // Since we only scrobble when things are higher, we can
await ScrobbleReadingUpdate(uId, series.Id);
}
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(uId);
if (user != null)
{
user.HasRunScrobbleEventGeneration = true;
user.ScrobbleEventGenerationRan = DateTime.UtcNow;
await _unitOfWork.CommitAsync();
}
}
}

View file

@ -536,7 +536,7 @@ public class CoverDbService : ICoverDbService
if (!string.IsNullOrEmpty(filePath))
{
// Additional check to see if downloaded image is similar and we have a higher resolution
if (chooseBetterImage)
if (chooseBetterImage && !string.IsNullOrEmpty(series.CoverImage))
{
try
{

View file

@ -287,6 +287,7 @@ public class Startup
// v0.8.6
await ManualMigrateScrobbleSpecials.Migrate(dataContext, logger);
await ManualMigrateScrobbleEventGen.Migrate(dataContext, logger);
// Update the version in the DB after all migrations are run
var installVersion = await unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion);