mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Fix repositories create/edit/delete events
This commit is contained in:
parent
d7dee62e97
commit
5b7bfa79f9
@ -44,9 +44,9 @@ dotnet_style_prefer_conditional_expression_over_return = true
|
||||
# Disable strange throw.
|
||||
csharp_style_throw_expression = false:suggestion
|
||||
# Forbid "var" everywhere
|
||||
csharp_style_var_for_built_in_types = false:warning
|
||||
csharp_style_var_when_type_is_apparent = false:warning
|
||||
csharp_style_var_elsewhere = false:warning
|
||||
csharp_style_var_for_built_in_types = false:suggestion
|
||||
csharp_style_var_when_type_is_apparent = false:suggestion
|
||||
csharp_style_var_elsewhere = false:suggestion
|
||||
# Prefer method-like constructs to have a block body
|
||||
csharp_style_expression_bodied_methods = false:none
|
||||
csharp_style_expression_bodied_constructors = false:none
|
||||
|
@ -37,7 +37,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// The event handler type for all events of this repository.
|
||||
/// </summary>
|
||||
/// <param name="resource">The resource created/modified/deleted</param>
|
||||
public delegate void ResourceEventHandler(T resource);
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
public delegate Task ResourceEventHandler(T resource);
|
||||
|
||||
/// <summary>
|
||||
/// Get a resource from it's ID.
|
||||
@ -146,7 +147,15 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <summary>
|
||||
/// Called when a resource has been created.
|
||||
/// </summary>
|
||||
event ResourceEventHandler OnCreated;
|
||||
static event ResourceEventHandler OnCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been created.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly created.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceCreated(T obj)
|
||||
=> OnCreated?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Edit a resource and replace every property
|
||||
@ -171,7 +180,15 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <summary>
|
||||
/// Called when a resource has been edited.
|
||||
/// </summary>
|
||||
event ResourceEventHandler OnEdited;
|
||||
static event ResourceEventHandler OnEdited;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been edited.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly edited.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceEdited(T obj)
|
||||
=> OnEdited?.Invoke(obj) ?? Task.CompletedTask;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a resource by it's ID
|
||||
@ -207,7 +224,15 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// <summary>
|
||||
/// Called when a resource has been edited.
|
||||
/// </summary>
|
||||
event ResourceEventHandler OnDeleted;
|
||||
static event ResourceEventHandler OnDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been deleted.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly deleted.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
protected static Task OnResourceDeleted(T obj)
|
||||
=> OnDeleted?.Invoke(obj) ?? Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -68,7 +68,7 @@ namespace Kyoo.Core.Controllers
|
||||
await base.Create(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Collection>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Core.Controllers
|
||||
{
|
||||
@ -48,6 +49,25 @@ namespace Kyoo.Core.Controllers
|
||||
new Sort<Episode>.By(x => x.EpisodeNumber)
|
||||
);
|
||||
|
||||
static EpisodeRepository()
|
||||
{
|
||||
// Edit episode slugs when the show's slug changes.
|
||||
IRepository<Show>.OnEdited += async (show) =>
|
||||
{
|
||||
await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
|
||||
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||
List<Episode> episodes = await database.Episodes.AsTracking()
|
||||
.Where(x => x.ShowId == show.Id)
|
||||
.ToListAsync();
|
||||
foreach (Episode ep in episodes)
|
||||
{
|
||||
ep.ShowSlug = show.Slug;
|
||||
await database.SaveChangesAsync();
|
||||
await IRepository<Episode>.OnResourceEdited(ep);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="EpisodeRepository"/>.
|
||||
/// </summary>
|
||||
@ -61,18 +81,6 @@ namespace Kyoo.Core.Controllers
|
||||
{
|
||||
_database = database;
|
||||
_shows = shows;
|
||||
|
||||
// Edit episode slugs when the show's slug changes.
|
||||
shows.OnEdited += (show) =>
|
||||
{
|
||||
List<Episode> episodes = _database.Episodes.AsTracking().Where(x => x.ShowId == show.Id).ToList();
|
||||
foreach (Episode ep in episodes)
|
||||
{
|
||||
ep.ShowSlug = show.Slug;
|
||||
_database.SaveChanges();
|
||||
OnResourceEdited(ep);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -96,7 +104,7 @@ namespace Kyoo.Core.Controllers
|
||||
obj is { SeasonNumber: not null, EpisodeNumber: not null }
|
||||
? Get(x => x.ShowId == obj.ShowId && x.SeasonNumber == obj.SeasonNumber && x.EpisodeNumber == obj.EpisodeNumber)
|
||||
: Get(x => x.ShowId == obj.ShowId && x.AbsoluteNumber == obj.AbsoluteNumber));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Episode>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,6 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc/>
|
||||
public Type RepositoryType => typeof(T);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event IRepository<T>.ResourceEventHandler OnCreated;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event IRepository<T>.ResourceEventHandler OnEdited;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event IRepository<T>.ResourceEventHandler OnDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Sort the given query.
|
||||
/// </summary>
|
||||
@ -434,24 +425,6 @@ namespace Kyoo.Core.Controllers
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been created.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly created.</param>
|
||||
protected void OnResourceCreated(T obj)
|
||||
{
|
||||
OnCreated?.Invoke(obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback that should be called after a resource has been edited.
|
||||
/// </summary>
|
||||
/// <param name="obj">The resource newly edited.</param>
|
||||
protected void OnResourceEdited(T obj)
|
||||
{
|
||||
OnEdited?.Invoke(obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual async Task<T> CreateIfNotExists(T obj)
|
||||
{
|
||||
@ -481,7 +454,7 @@ namespace Kyoo.Core.Controllers
|
||||
Merger.Complete(old, edited, x => x.GetCustomAttribute<LoadableRelationAttribute>() == null);
|
||||
await EditRelations(old, edited);
|
||||
await Database.SaveChangesAsync();
|
||||
OnEdited?.Invoke(old);
|
||||
await IRepository<T>.OnResourceEdited(old);
|
||||
return old;
|
||||
}
|
||||
finally
|
||||
@ -504,7 +477,7 @@ namespace Kyoo.Core.Controllers
|
||||
throw new ArgumentException("Could not patch resource");
|
||||
|
||||
await Database.SaveChangesAsync();
|
||||
OnEdited?.Invoke(resource);
|
||||
await IRepository<T>.OnResourceEdited(resource);
|
||||
return resource;
|
||||
}
|
||||
finally
|
||||
@ -586,7 +559,7 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc/>
|
||||
public virtual Task Delete(T obj)
|
||||
{
|
||||
OnDeleted?.Invoke(obj);
|
||||
IRepository<T>.OnResourceDeleted(obj);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace Kyoo.Core.Controllers
|
||||
await base.Create(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Movie>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
@ -80,7 +79,7 @@ namespace Kyoo.Core.Controllers
|
||||
await base.Create(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<People>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,10 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
using Kyoo.Postgresql;
|
||||
using Kyoo.Utils;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Core.Controllers
|
||||
{
|
||||
@ -43,30 +42,35 @@ namespace Kyoo.Core.Controllers
|
||||
/// <inheritdoc/>
|
||||
protected override Sort<Season> DefaultSort => new Sort<Season>.By(x => x.SeasonNumber);
|
||||
|
||||
static SeasonRepository()
|
||||
{
|
||||
// Edit seasons slugs when the show's slug changes.
|
||||
IRepository<Show>.OnEdited += async (show) =>
|
||||
{
|
||||
await using AsyncServiceScope scope = CoreModule.Services.CreateAsyncScope();
|
||||
DatabaseContext database = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
|
||||
List<Season> seasons = await database.Seasons.AsTracking()
|
||||
.Where(x => x.ShowId == show.Id)
|
||||
.ToListAsync();
|
||||
foreach (Season season in seasons)
|
||||
{
|
||||
season.ShowSlug = show.Slug;
|
||||
await database.SaveChangesAsync();
|
||||
await IRepository<Season>.OnResourceEdited(season);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="SeasonRepository"/>.
|
||||
/// </summary>
|
||||
/// <param name="database">The database handle that will be used</param>
|
||||
/// <param name="shows">A shows repository</param>
|
||||
/// <param name="thumbs">The thumbnail manager used to store images.</param>
|
||||
public SeasonRepository(DatabaseContext database,
|
||||
IRepository<Show> shows,
|
||||
IThumbnailsManager thumbs)
|
||||
: base(database, thumbs)
|
||||
{
|
||||
_database = database;
|
||||
|
||||
// Edit seasons slugs when the show's slug changes.
|
||||
shows.OnEdited += (show) =>
|
||||
{
|
||||
List<Season> seasons = _database.Seasons.AsTracking().Where(x => x.ShowId == show.Id).ToList();
|
||||
foreach (Season season in seasons)
|
||||
{
|
||||
season.ShowSlug = show.Slug;
|
||||
_database.SaveChanges();
|
||||
OnResourceEdited(season);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@ -87,7 +91,7 @@ namespace Kyoo.Core.Controllers
|
||||
obj.ShowSlug = _database.Shows.First(x => x.Id == obj.ShowId).Slug;
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(x => x.ShowId == obj.ShowId && x.SeasonNumber == obj.SeasonNumber));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Season>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ namespace Kyoo.Core.Controllers
|
||||
await base.Create(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Show>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ namespace Kyoo.Core.Controllers
|
||||
await base.Create(obj);
|
||||
_database.Entry(obj).State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<Studio>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ namespace Kyoo.Core.Controllers
|
||||
if (obj.Logo != null)
|
||||
_database.Entry(obj).Reference(x => x.Logo).TargetEntry!.State = EntityState.Added;
|
||||
await _database.SaveChangesAsync(() => Get(obj.Slug));
|
||||
OnResourceCreated(obj);
|
||||
await IRepository<User>.OnResourceCreated(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AspNetCore.Proxy;
|
||||
@ -41,6 +42,12 @@ namespace Kyoo.Core
|
||||
/// </summary>
|
||||
public class CoreModule : IPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// A service provider to access services in static context (in events for example).
|
||||
/// </summary>
|
||||
/// <remarks>Don't forget to create a scope.</remarks>
|
||||
public static IServiceProvider Services { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => "Core";
|
||||
|
||||
|
@ -23,6 +23,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Kyoo.Core;
|
||||
using Kyoo.Meiliseach;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
@ -117,6 +118,7 @@ namespace Kyoo.Host
|
||||
{
|
||||
try
|
||||
{
|
||||
CoreModule.Services = host.Services;
|
||||
_logger.Information("Version: {Version}", Assembly.GetExecutingAssembly().GetName().Version.ToString(3));
|
||||
_logger.Information("Data directory: {DataDirectory}", Environment.CurrentDirectory);
|
||||
await host.RunAsync(cancellationToken);
|
||||
|
@ -63,12 +63,12 @@ namespace Kyoo.Meiliseach
|
||||
nameof(LibraryItem.Status),
|
||||
nameof(LibraryItem.AirDate),
|
||||
nameof(Movie.StudioID),
|
||||
nameof(LibraryItem.Kind),
|
||||
},
|
||||
SortableAttributes = new[]
|
||||
{
|
||||
nameof(LibraryItem.AirDate),
|
||||
nameof(LibraryItem.AddedDate),
|
||||
nameof(LibraryItem.Kind),
|
||||
},
|
||||
DisplayedAttributes = new[]
|
||||
{
|
||||
@ -94,7 +94,7 @@ namespace Kyoo.Meiliseach
|
||||
_configuration.GetValue("MEILI_HOST", "http://meilisearch:7700"),
|
||||
_configuration.GetValue<string?>("MEILI_MASTER_KEY")
|
||||
)).SingleInstance();
|
||||
builder.RegisterType<SearchManager>().SingleInstance();
|
||||
builder.RegisterType<SearchManager>().As<ISearchManager>().SingleInstance().AutoActivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,10 @@ public class SearchManager : ISearchManager
|
||||
if (kind != null)
|
||||
{
|
||||
dynamic expando = new ExpandoObject();
|
||||
var dictionary = (IDictionary<string, object?>)expando;
|
||||
|
||||
foreach (PropertyInfo property in item.GetType().GetProperties())
|
||||
expando.TryAdd(property.Name, property.GetValue(item));
|
||||
dictionary.Add(property.Name, property.GetValue(item));
|
||||
expando.Ref = $"{kind}/{item.Id}";
|
||||
expando.Kind = kind;
|
||||
return _client.Index(index).AddDocumentsAsync(new[] { item });
|
||||
|
@ -50,7 +50,7 @@ namespace Kyoo.Tests.Database
|
||||
thumbs.Object);
|
||||
MovieRepository movies = new(_NewContext(), studio, people, thumbs.Object);
|
||||
ShowRepository show = new(_NewContext(), studio, people, thumbs.Object);
|
||||
SeasonRepository season = new(_NewContext(), show, thumbs.Object);
|
||||
SeasonRepository season = new(_NewContext(), thumbs.Object);
|
||||
LibraryItemRepository libraryItem = new(_NewContext(), thumbs.Object);
|
||||
EpisodeRepository episode = new(_NewContext(), show, thumbs.Object);
|
||||
UserRepository user = new(_NewContext(), thumbs.Object);
|
||||
|
Loading…
x
Reference in New Issue
Block a user