Fixing tracks editing

This commit is contained in:
Zoe Roux 2021-03-15 23:52:11 +01:00
parent d38926924c
commit d2a38c9b3d
7 changed files with 59 additions and 13 deletions

View File

@ -27,9 +27,9 @@ namespace Kyoo.Models
public int Runtime { get; set; } //This runtime variable should be in minutes
[LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
[EditableRelation] [LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
[LoadableRelation] public virtual ICollection<Track> Tracks { get; set; }
[EditableRelation] [LoadableRelation] public virtual ICollection<Track> Tracks { get; set; }
public Episode() { }

View File

@ -143,7 +143,7 @@ namespace Kyoo
? Activator.CreateInstance(property.PropertyType)
: null;
if (value?.Equals(defaultValue) == false)
if (value?.Equals(defaultValue) == false && value != property.GetValue(first))
property.SetValue(first, value);
}
@ -303,6 +303,22 @@ namespace Kyoo
foreach (T i in self)
action(i);
}
public static async Task ForEachAsync<T>([CanBeNull] this IEnumerable<T> self, Func<T, Task> action)
{
if (self == null)
return;
foreach (T i in self)
await action(i);
}
public static async Task ForEachAsync<T>([CanBeNull] this IAsyncEnumerable<T> self, Action<T> action)
{
if (self == null)
return;
await foreach (T i in self)
action(i);
}
private static MethodInfo GetMethod(Type type, BindingFlags flag, string name, Type[] generics, object[] args)
{

View File

@ -43,6 +43,11 @@ namespace Kyoo.Controllers
{
return Database.Set<T>().FirstOrDefaultAsync(x => x.ID == id);
}
public virtual Task<T> GetWithTracking(int id)
{
return Database.Set<T>().AsTracking().FirstOrDefaultAsync(x => x.ID == id);
}
public virtual Task<T> Get(string slug)
{
@ -159,7 +164,7 @@ namespace Kyoo.Controllers
Database.ChangeTracker.LazyLoadingEnabled = false;
try
{
T old = await Get(edited.ID);
T old = await GetWithTracking(edited.ID);
if (old == null)
throw new ItemNotFound($"No resource found with the ID {edited.ID}.");
@ -180,8 +185,8 @@ namespace Kyoo.Controllers
await navigation.LoadAsync();
// TODO this may be usless for lists since the API does not return IDs but the
// TODO LinkEquality does not check slugs (their are lazy loaded and only the ID is available)
if (Utility.ResourceEquals(getter.GetClrValue(edited), getter.GetClrValue(old)))
navigation.Metadata.PropertyInfo.SetValue(edited, default);
// if (Utility.ResourceEquals(getter.GetClrValue(edited), getter.GetClrValue(old)))
// navigation.Metadata.PropertyInfo.SetValue(edited, default);
}
else
navigation.Metadata.PropertyInfo.SetValue(edited, default);

View File

@ -15,15 +15,20 @@ namespace Kyoo.Controllers
private readonly DatabaseContext _database;
private readonly IProviderRepository _providers;
private readonly IShowRepository _shows;
private readonly ITrackRepository _tracks;
protected override Expression<Func<Episode, object>> DefaultSort => x => x.EpisodeNumber;
public EpisodeRepository(DatabaseContext database, IProviderRepository providers, IShowRepository shows)
public EpisodeRepository(DatabaseContext database,
IProviderRepository providers,
IShowRepository shows,
ITrackRepository tracks)
: base(database)
{
_database = database;
_providers = providers;
_shows = shows;
_tracks = tracks;
}
@ -161,6 +166,14 @@ namespace Kyoo.Controllers
await base.Validate(resource);
if (resource.Tracks != null)
{
// TODO remove old values
resource.Tracks = await resource.Tracks
.SelectAsync(x => _tracks.CreateIfNotExists(x, true))
.ToListAsync();
}
if (resource.ExternalIDs != null)
{
foreach (MetadataID link in resource.ExternalIDs)
@ -181,10 +194,10 @@ namespace Kyoo.Controllers
throw new ArgumentNullException(nameof(obj));
_database.Entry(obj).State = EntityState.Deleted;
await obj.Tracks.ForEachAsync(x => _tracks.CreateIfNotExists(x, true));
if (obj.ExternalIDs != null)
foreach (MetadataID entry in obj.ExternalIDs)
_database.Entry(entry).State = EntityState.Deleted;
// Since Tracks & Episodes are on the same database and handled by dotnet-ef, we can't use the repository to delete them.
await _database.SaveChangesAsync();
}
}

View File

@ -36,7 +36,12 @@ namespace Kyoo.Controllers
await _database.DisposeAsync();
}
public Task<Track> Get(string slug, StreamType type = StreamType.Unknown)
public override Task<Track> Get(string slug)
{
return Get(slug, StreamType.Unknown);
}
public Task<Track> Get(string slug, StreamType type)
{
Match match = Regex.Match(slug,
@"(?<show>.*)-s(?<season>\d+)e(?<episode>\d+)\.(?<language>.{0,3})(?<forced>-forced)?(\..*)?");
@ -93,6 +98,8 @@ namespace Kyoo.Controllers
return obj;
}
protected override Task Validate(Track resource)
{
return Task.CompletedTask;

View File

@ -12,7 +12,10 @@ namespace Kyoo
{
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
public DbSet<Library> Libraries { get; set; }
public DbSet<Collection> Collections { get; set; }
@ -35,6 +38,8 @@ namespace Kyoo
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<ItemType>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

View File

@ -58,9 +58,9 @@ namespace Kyoo
services.AddDbContext<DatabaseContext>(options =>
{
options.UseNpgsql(_configuration.GetConnectionString("Database"));
// .EnableSensitiveDataLogging()
// .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
options.UseNpgsql(_configuration.GetConnectionString("Database"))
.EnableSensitiveDataLogging()
.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
}, ServiceLifetime.Transient);
services.AddDbContext<IdentityDatabase>(options =>