diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs
index a83d17fa..c5fe7a7c 100644
--- a/Kyoo.Common/Controllers/IRepository.cs
+++ b/Kyoo.Common/Controllers/IRepository.cs
@@ -590,10 +590,10 @@ namespace Kyoo.Controllers
/// Pagination information (where to start and how many to get)
/// The type of metadata to retrieve
/// A filtered list of external ids.
- Task>> GetMetadataID(Expression, bool>> where = null,
- Sort> sort = default,
+ Task> GetMetadataID(Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
- where T : class, IResource;
+ where T : class, IMetadata;
///
/// Get a list of external ids that match all filters
@@ -602,11 +602,11 @@ namespace Kyoo.Controllers
/// A sort by expression
/// Pagination information (where to start and how many to get)
/// A filtered list of external ids.
- Task>> GetMetadataID([Optional] Expression, bool>> where,
- Expression, object>> sort,
+ Task> GetMetadataID([Optional] Expression> where,
+ Expression> sort,
Pagination limit = default
- ) where T : class, IResource
- => GetMetadataID(where, new Sort>(sort), limit);
+ ) where T : class, IMetadata
+ => GetMetadataID(where, new Sort(sort), limit);
}
///
diff --git a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs
index 12ea0b2a..5b051ed8 100644
--- a/Kyoo.Common/Controllers/Implementations/LibraryManager.cs
+++ b/Kyoo.Common/Controllers/Implementations/LibraryManager.cs
@@ -231,7 +231,12 @@ namespace Kyoo.Controllers
.Then(x => l.Collections = x),
- (Collection c, nameof(Library.Shows)) => ShowRepository
+ (Collection c, nameof(Collection.ExternalIDs)) => SetRelation(c,
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
+ (x, y) => x.ExternalIDs = y,
+ (x, y) => { x.ResourceID = y.ID; }),
+
+ (Collection c, nameof(Collection.Shows)) => ShowRepository
.GetAll(x => x.Collections.Any(y => y.ID == obj.ID))
.Then(x => c.Shows = x),
@@ -241,9 +246,9 @@ namespace Kyoo.Controllers
(Show s, nameof(Show.ExternalIDs)) => SetRelation(s,
- ProviderRepository.GetMetadataID(x => x.FirstID == obj.ID),
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
- (x, y) => { x.First = y; x.FirstID = y.ID; }),
+ (x, y) => { x.ResourceID = y.ID; }),
(Show s, nameof(Show.Genres)) => GenreRepository
.GetAll(x => x.Shows.Any(y => y.ID == obj.ID))
@@ -281,9 +286,9 @@ namespace Kyoo.Controllers
(Season s, nameof(Season.ExternalIDs)) => SetRelation(s,
- ProviderRepository.GetMetadataID(x => x.FirstID == obj.ID),
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
- (x, y) => { x.First = y; x.FirstID = y.ID; }),
+ (x, y) => { x.ResourceID = y.ID; }),
(Season s, nameof(Season.Episodes)) => SetRelation(s,
EpisodeRepository.GetAll(x => x.Season.ID == obj.ID),
@@ -300,9 +305,9 @@ namespace Kyoo.Controllers
(Episode e, nameof(Episode.ExternalIDs)) => SetRelation(e,
- ProviderRepository.GetMetadataID(x => x.FirstID == obj.ID),
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
- (x, y) => { x.First = y; x.FirstID = y.ID; }),
+ (x, y) => { x.ResourceID = y.ID; }),
(Episode e, nameof(Episode.Tracks)) => SetRelation(e,
TrackRepository.GetAll(x => x.Episode.ID == obj.ID),
@@ -344,11 +349,16 @@ namespace Kyoo.Controllers
.GetAll(x => x.Studio.ID == obj.ID)
.Then(x => s.Shows = x),
+ (Studio s, nameof(Studio.ExternalIDs)) => SetRelation(s,
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
+ (x, y) => x.ExternalIDs = y,
+ (x, y) => { x.ResourceID = y.ID; }),
+
(People p, nameof(People.ExternalIDs)) => SetRelation(p,
- ProviderRepository.GetMetadataID(x => x.FirstID == obj.ID),
+ ProviderRepository.GetMetadataID(x => x.ResourceID == obj.ID),
(x, y) => x.ExternalIDs = y,
- (x, y) => { x.First = y; x.FirstID = y.ID; }),
+ (x, y) => { x.ResourceID = y.ID; }),
(People p, nameof(People.Roles)) => PeopleRepository
.GetFromPeople(obj.ID)
diff --git a/Kyoo.Common/Models/Link.cs b/Kyoo.Common/Models/Link.cs
index 09c519da..1f4cf4ac 100644
--- a/Kyoo.Common/Models/Link.cs
+++ b/Kyoo.Common/Models/Link.cs
@@ -92,7 +92,7 @@ namespace Kyoo.Models
get
{
return x => new {First = x.FirstID, Second = x.SecondID};
- }
+ }
}
}
@@ -157,7 +157,7 @@ namespace Kyoo.Models
get
{
return x => new {First = x.FirstID, Second = x.SecondID};
- }
+ }
}
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/MetadataID.cs b/Kyoo.Common/Models/MetadataID.cs
index de6ac817..e3bb42a6 100644
--- a/Kyoo.Common/Models/MetadataID.cs
+++ b/Kyoo.Common/Models/MetadataID.cs
@@ -1,15 +1,34 @@
using System;
using System.Linq.Expressions;
+using Kyoo.Models.Attributes;
namespace Kyoo.Models
{
///
/// ID and link of an item on an external provider.
///
- ///
- public class MetadataID : Link
- where T : class, IResource
+ public class MetadataID
{
+ ///
+ /// The ID of the resource which possess the metadata.
+ ///
+ [SerializeIgnore] public int ResourceID { get; set; }
+
+ ///
+ /// The name of the resource type. This is only used internally to discriminate types.
+ ///
+ [SerializeIgnore] public string ResourceType { get; set; }
+
+ ///
+ /// The ID of the provider.
+ ///
+ [SerializeIgnore] public int ProviderID { get; set; }
+
+ ///
+ /// The provider that can do something with this ID.
+ ///
+ public Provider Provider { get; set; }
+
///
/// The ID of the resource on the external provider.
///
@@ -20,20 +39,14 @@ namespace Kyoo.Models
///
public string Link { get; set; }
- ///
- /// A shortcut to access the provider of this metadata.
- /// Unlike the property, this is serializable.
- ///
- public Provider Provider => Second;
-
///
/// The expression to retrieve the unique ID of a MetadataID. This is an aggregate of the two resources IDs.
///
- public new static Expression, object>> PrimaryKey
+ public static Expression> PrimaryKey
{
get
{
- return x => new {First = x.FirstID, Second = x.SecondID};
+ return x => new {First = x.ResourceID, Second = x.ProviderID, Type = x.ResourceType};
}
}
}
diff --git a/Kyoo.Common/Models/Resources/Collection.cs b/Kyoo.Common/Models/Resources/Collection.cs
index 8162ff16..f7c5db3f 100644
--- a/Kyoo.Common/Models/Resources/Collection.cs
+++ b/Kyoo.Common/Models/Resources/Collection.cs
@@ -8,7 +8,7 @@ namespace Kyoo.Models
/// A class representing collections of .
/// A collection can also be stored in a .
///
- public class Collection : IResource
+ public class Collection : IResource, IMetadata
{
///
public int ID { get; set; }
@@ -42,6 +42,9 @@ namespace Kyoo.Models
/// The list of libraries that contains this collection.
///
[LoadableRelation] public ICollection Libraries { get; set; }
+
+ ///
+ public ICollection ExternalIDs { get; set; }
#if ENABLE_INTERNAL_LINKS
diff --git a/Kyoo.Common/Models/Resources/Episode.cs b/Kyoo.Common/Models/Resources/Episode.cs
index 7f76a8a4..687e88fb 100644
--- a/Kyoo.Common/Models/Resources/Episode.cs
+++ b/Kyoo.Common/Models/Resources/Episode.cs
@@ -10,7 +10,7 @@ namespace Kyoo.Models
///
/// A class to represent a single show's episode.
///
- public class Episode : IResource
+ public class Episode : IResource, IMetadata
{
///
public int ID { get; set; }
@@ -121,10 +121,8 @@ namespace Kyoo.Models
///
public DateTime? ReleaseDate { get; set; }
- ///
- /// The link to metadata providers that this episode has. See for more information.
- ///
- [EditableRelation] [LoadableRelation] public ICollection> ExternalIDs { get; set; }
+ ///
+ public ICollection ExternalIDs { get; set; }
///
/// The list of tracks this episode has. This lists video, audio and subtitles available.
diff --git a/Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs b/Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs
new file mode 100644
index 00000000..469d3dbb
--- /dev/null
+++ b/Kyoo.Common/Models/Resources/Interfaces/IMetadata.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using Kyoo.Models.Attributes;
+
+namespace Kyoo.Models
+{
+ ///
+ /// An interface applied to resources containing external metadata.
+ ///
+ public interface IMetadata
+ {
+ ///
+ /// The link to metadata providers that this show has. See for more information.
+ ///
+ [EditableRelation] [LoadableRelation] public ICollection ExternalIDs { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/Resources/IResource.cs b/Kyoo.Common/Models/Resources/Interfaces/IResource.cs
similarity index 100%
rename from Kyoo.Common/Models/Resources/IResource.cs
rename to Kyoo.Common/Models/Resources/Interfaces/IResource.cs
diff --git a/Kyoo.Common/Models/Resources/People.cs b/Kyoo.Common/Models/Resources/People.cs
index 7ae04613..ff2b8ed1 100644
--- a/Kyoo.Common/Models/Resources/People.cs
+++ b/Kyoo.Common/Models/Resources/People.cs
@@ -6,7 +6,7 @@ namespace Kyoo.Models
///
/// An actor, voice actor, writer, animator, somebody who worked on a .
///
- public class People : IResource
+ public class People : IResource, IMetadata
{
///
public int ID { get; set; }
@@ -26,10 +26,8 @@ namespace Kyoo.Models
///
[SerializeAs("{HOST}/api/people/{Slug}/poster")] public string Poster { get; set; }
- ///
- /// The link to metadata providers that this person has. See for more information.
- ///
- [EditableRelation] [LoadableRelation] public ICollection> ExternalIDs { get; set; }
+ ///
+ public ICollection ExternalIDs { get; set; }
///
/// The list of roles this person has played in. See for more information.
diff --git a/Kyoo.Common/Models/Resources/Season.cs b/Kyoo.Common/Models/Resources/Season.cs
index 9b292020..b390f712 100644
--- a/Kyoo.Common/Models/Resources/Season.cs
+++ b/Kyoo.Common/Models/Resources/Season.cs
@@ -10,7 +10,7 @@ namespace Kyoo.Models
///
/// A season of a .
///
- public class Season : IResource
+ public class Season : IResource, IMetadata
{
///
public int ID { get; set; }
@@ -81,10 +81,8 @@ namespace Kyoo.Models
///
[SerializeAs("{HOST}/api/seasons/{Slug}/thumb")] public string Poster { get; set; }
- ///
- /// The link to metadata providers that this episode has. See for more information.
- ///
- [EditableRelation] [LoadableRelation] public ICollection> ExternalIDs { get; set; }
+ ///
+ public ICollection ExternalIDs { get; set; }
///
/// The list of episodes that this season contains.
diff --git a/Kyoo.Common/Models/Resources/Show.cs b/Kyoo.Common/Models/Resources/Show.cs
index 57c9fcef..85c5b959 100644
--- a/Kyoo.Common/Models/Resources/Show.cs
+++ b/Kyoo.Common/Models/Resources/Show.cs
@@ -11,7 +11,7 @@ namespace Kyoo.Models
///
/// A series or a movie.
///
- public class Show : IResource, IOnMerge
+ public class Show : IResource, IMetadata, IOnMerge
{
///
public int ID { get; set; }
@@ -89,11 +89,9 @@ namespace Kyoo.Models
///
public bool IsMovie { get; set; }
- ///
- /// The link to metadata providers that this show has. See for more information.
- ///
- [EditableRelation] [LoadableRelation] public ICollection> ExternalIDs { get; set; }
-
+ ///
+ public ICollection ExternalIDs { get; set; }
+
///
/// The ID of the Studio that made this show.
///
@@ -157,19 +155,16 @@ namespace Kyoo.Models
///
/// This method will never return anything if the are not loaded.
/// The slug of the provider
- /// The field of the asked provider.
+ /// The field of the asked provider.
[CanBeNull]
public string GetID(string provider)
{
- return ExternalIDs?.FirstOrDefault(x => x.Second.Slug == provider)?.DataID;
+ return ExternalIDs?.FirstOrDefault(x => x.Provider.Slug == provider)?.DataID;
}
///
public void OnMerge(object merged)
{
- if (ExternalIDs != null)
- foreach (MetadataID id in ExternalIDs)
- id.First = this;
if (People != null)
foreach (PeopleRole link in People)
link.Show = this;
diff --git a/Kyoo.Common/Models/Resources/Studio.cs b/Kyoo.Common/Models/Resources/Studio.cs
index ebc3c4c1..80195317 100644
--- a/Kyoo.Common/Models/Resources/Studio.cs
+++ b/Kyoo.Common/Models/Resources/Studio.cs
@@ -6,7 +6,7 @@ namespace Kyoo.Models
///
/// A studio that make shows.
///
- public class Studio : IResource
+ public class Studio : IResource, IMetadata
{
///
public int ID { get; set; }
@@ -24,6 +24,9 @@ namespace Kyoo.Models
///
[LoadableRelation] public ICollection Shows { get; set; }
+ ///
+ public ICollection ExternalIDs { get; set; }
+
///
/// Create a new, empty, .
///
diff --git a/Kyoo.CommonAPI/DatabaseContext.cs b/Kyoo.CommonAPI/DatabaseContext.cs
index 36cdc47b..d0600da1 100644
--- a/Kyoo.CommonAPI/DatabaseContext.cs
+++ b/Kyoo.CommonAPI/DatabaseContext.cs
@@ -61,6 +61,10 @@ namespace Kyoo
///
public DbSet Providers { get; set; }
///
+ /// All metadata ids, not discriminated by type. See .
+ ///
+ public DbSet MetadataIDs { get; set; }
+ ///
/// The list of registered users.
///
public DbSet Users { get; set; }
@@ -83,17 +87,6 @@ namespace Kyoo
///
public DbSet LibraryItems { get; set; }
- ///
- /// Get all metadataIDs (ExternalIDs) of a given resource. See .
- ///
- /// The metadata of this type will be returned.
- /// A queryable of metadata ids for a type.
- public DbSet> MetadataIds()
- where T : class, IResource
- {
- return Set>();
- }
-
///
/// Get a generic link between two resource types.
///
@@ -132,6 +125,22 @@ namespace Kyoo
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
+ ///
+ /// Build the metadata model for the given type.
+ ///
+ /// The database model builder
+ /// The type to add metadata to.
+ private void _HasMetadata(ModelBuilder modelBuilder)
+ where T : class, IMetadata
+ {
+ modelBuilder.Entity()
+ .HasMany(x => x.ExternalIDs)
+ .WithOne()
+ .HasForeignKey(x => x.ResourceID)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+
+
///
/// Set database parameters to support every types of Kyoo.
///
@@ -234,43 +243,21 @@ namespace Kyoo
.WithMany(x => x.ShowLinks),
y => y.HasKey(Link.PrimaryKey));
- modelBuilder.Entity>()
- .HasKey(MetadataID.PrimaryKey);
- modelBuilder.Entity>()
- .HasOne(x => x.First)
- .WithMany(x => x.ExternalIDs)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>()
- .HasKey(MetadataID.PrimaryKey);
- modelBuilder.Entity>()
- .HasOne(x => x.First)
- .WithMany(x => x.ExternalIDs)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>()
- .HasKey(MetadataID.PrimaryKey);
- modelBuilder.Entity>()
- .HasOne(x => x.First)
- .WithMany(x => x.ExternalIDs)
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>()
- .HasKey(MetadataID.PrimaryKey);
- modelBuilder.Entity>()
- .HasOne(x => x.First)
- .WithMany(x => x.ExternalIDs)
- .OnDelete(DeleteBehavior.Cascade);
-
-
- modelBuilder.Entity>().HasOne(x => x.Second).WithMany()
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>().HasOne(x => x.Second).WithMany()
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>().HasOne(x => x.Second).WithMany()
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>().HasOne(x => x.Second).WithMany()
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity>().HasOne(x => x.Second).WithMany()
- .OnDelete(DeleteBehavior.Cascade);
+ modelBuilder.Entity()
+ .HasKey(MetadataID.PrimaryKey);
+ modelBuilder.Entity()
+ .Property(x => x.ResourceType)
+ .IsRequired();
+ modelBuilder.Entity()
+ .HasDiscriminator(x => x.ResourceType);
+ _HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
+ _HasMetadata(modelBuilder);
+
modelBuilder.Entity()
.HasKey(x => new {First = x.FirstID, Second = x.SecondID});
diff --git a/Kyoo.Tests/Database/RepositoryActivator.cs b/Kyoo.Tests/Database/RepositoryActivator.cs
index ee6aa4df..25530f78 100644
--- a/Kyoo.Tests/Database/RepositoryActivator.cs
+++ b/Kyoo.Tests/Database/RepositoryActivator.cs
@@ -22,9 +22,9 @@ namespace Kyoo.Tests
ProviderRepository provider = new(_database);
LibraryRepository library = new(_database, provider);
- CollectionRepository collection = new(_database);
+ CollectionRepository collection = new(_database, provider);
GenreRepository genre = new(_database);
- StudioRepository studio = new(_database);
+ StudioRepository studio = new(_database, provider);
PeopleRepository people = new(_database, provider,
new Lazy(() => LibraryManager.ShowRepository));
ShowRepository show = new(_database, studio, people, genre, provider);
diff --git a/Kyoo.Tests/Database/SpecificTests/ShowTests.cs b/Kyoo.Tests/Database/SpecificTests/ShowTests.cs
index 63207710..42ab693c 100644
--- a/Kyoo.Tests/Database/SpecificTests/ShowTests.cs
+++ b/Kyoo.Tests/Database/SpecificTests/ShowTests.cs
@@ -149,10 +149,9 @@ namespace Kyoo.Tests.Database
Show value = await _repository.Get(TestSample.Get().Slug);
value.ExternalIDs = new[]
{
- new MetadataID()
+ new MetadataID
{
- First = value,
- Second = new Provider("test", "test.png"),
+ Provider = new Provider("test", "test.png"),
DataID = "1234"
}
};
@@ -160,19 +159,19 @@ namespace Kyoo.Tests.Database
Assert.Equal(value.Slug, edited.Slug);
Assert.Equal(
- value.ExternalIDs.Select(x => new {x.DataID, x.Second.Slug}),
- edited.ExternalIDs.Select(x => new {x.DataID, x.Second.Slug}));
+ value.ExternalIDs.Select(x => new {x.DataID, x.Provider.Slug}),
+ edited.ExternalIDs.Select(x => new {x.DataID, x.Provider.Slug}));
await using DatabaseContext database = Repositories.Context.New();
Show show = await database.Shows
.Include(x => x.ExternalIDs)
- .ThenInclude(x => x.Second)
+ .ThenInclude(x => x.Provider)
.FirstAsync();
Assert.Equal(value.Slug, show.Slug);
Assert.Equal(
- value.ExternalIDs.Select(x => new {x.DataID, x.Second.Slug}),
- show.ExternalIDs.Select(x => new {x.DataID, x.Second.Slug}));
+ value.ExternalIDs.Select(x => new {x.DataID, x.Provider.Slug}),
+ show.ExternalIDs.Select(x => new {x.DataID, x.Provider.Slug}));
}
[Fact]
@@ -209,10 +208,9 @@ namespace Kyoo.Tests.Database
expected.Slug = "created-relation-test";
expected.ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
- First = expected,
- Second = new Provider("provider", "provider.png"),
+ Provider = new Provider("provider", "provider.png"),
DataID = "ID"
}
};
diff --git a/Kyoo.TheMovieDb/Convertors.cs b/Kyoo.TheMovieDb/Convertors.cs
index cb5b4412..0cf5fe98 100644
--- a/Kyoo.TheMovieDb/Convertors.cs
+++ b/Kyoo.TheMovieDb/Convertors.cs
@@ -48,9 +48,9 @@ namespace Kyoo.TheMovieDb
.ToArray(),
ExternalIDs = new []
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
Link = $"https://www.themoviedb.org/movie/{movie.Id}",
DataID = movie.Id.ToString()
}
@@ -94,9 +94,9 @@ namespace Kyoo.TheMovieDb
.ToArray(),
ExternalIDs = new []
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
Link = $"https://www.themoviedb.org/movie/{tv.Id}",
DataID = tv.Id.ToString()
}
@@ -145,9 +145,9 @@ namespace Kyoo.TheMovieDb
IsMovie = true,
ExternalIDs = new []
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
Link = $"https://www.themoviedb.org/movie/{movie.Id}",
DataID = movie.Id.ToString()
}
@@ -178,9 +178,9 @@ namespace Kyoo.TheMovieDb
IsMovie = true,
ExternalIDs = new []
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
Link = $"https://www.themoviedb.org/movie/{tv.Id}",
DataID = tv.Id.ToString()
}
@@ -205,9 +205,9 @@ namespace Kyoo.TheMovieDb
Poster = cast.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}" : null,
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
DataID = cast.Id.ToString(),
Link = $"https://www.themoviedb.org/person/{cast.Id}"
}
@@ -235,9 +235,9 @@ namespace Kyoo.TheMovieDb
Poster = cast.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{cast.ProfilePath}" : null,
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
DataID = cast.Id.ToString(),
Link = $"https://www.themoviedb.org/person/{cast.Id}"
}
@@ -265,9 +265,9 @@ namespace Kyoo.TheMovieDb
Poster = crew.ProfilePath != null ? $"https://image.tmdb.org/t/p/original{crew.ProfilePath}" : null,
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
- Second = provider,
+ Provider = provider,
DataID = crew.Id.ToString(),
Link = $"https://www.themoviedb.org/person/{crew.Id}"
}
diff --git a/Kyoo.TheTvdb/Convertors.cs b/Kyoo.TheTvdb/Convertors.cs
index bc31b5fd..6aad939b 100644
--- a/Kyoo.TheTvdb/Convertors.cs
+++ b/Kyoo.TheTvdb/Convertors.cs
@@ -58,11 +58,11 @@ namespace Kyoo.TheTvdb
Poster = result.Poster != null ? $"https://www.thetvdb.com{result.Poster}" : null,
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
DataID = result.Id.ToString(),
Link = $"https://www.thetvdb.com/series/{result.Slug}",
- Second = provider
+ Provider = provider
}
}
};
@@ -89,11 +89,11 @@ namespace Kyoo.TheTvdb
Genres = series.Genre.Select(y => new Genre(y)).ToList(),
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
DataID = series.Id.ToString(),
Link = $"https://www.thetvdb.com/series/{series.Slug}",
- Second = provider
+ Provider = provider
}
}
};
@@ -116,11 +116,11 @@ namespace Kyoo.TheTvdb
Poster = actor.Image != null ? $"https://www.thetvdb.com/banners/{actor.Image}" : null,
ExternalIDs = new []
{
- new MetadataID()
+ new MetadataID
{
DataID = actor.Id.ToString(),
Link = $"https://www.thetvdb.com/people/{actor.Id}",
- Second = provider
+ Provider = provider
}
}
},
@@ -147,11 +147,11 @@ namespace Kyoo.TheTvdb
Thumb = episode.Filename != null ? $"https://www.thetvdb.com/banners/{episode.Filename}" : null,
ExternalIDs = new[]
{
- new MetadataID
+ new MetadataID
{
DataID = episode.Id.ToString(),
Link = $"https://www.thetvdb.com/series/{episode.SeriesId}/episodes/{episode.Id}",
- Second = provider
+ Provider = provider
}
}
};
diff --git a/Kyoo/Controllers/Repositories/CollectionRepository.cs b/Kyoo/Controllers/Repositories/CollectionRepository.cs
index e0bc7843..6b546f07 100644
--- a/Kyoo/Controllers/Repositories/CollectionRepository.cs
+++ b/Kyoo/Controllers/Repositories/CollectionRepository.cs
@@ -18,6 +18,11 @@ namespace Kyoo.Controllers
///
private readonly DatabaseContext _database;
+ ///
+ /// A provider repository to handle externalID creation and deletion
+ ///
+ private readonly IProviderRepository _providers;
+
///
protected override Expression> DefaultSort => x => x.Name;
@@ -25,10 +30,12 @@ namespace Kyoo.Controllers
/// Create a new .
///
/// The database handle to use
- public CollectionRepository(DatabaseContext database)
+ /// /// A provider repository
+ public CollectionRepository(DatabaseContext database, IProviderRepository providers)
: base(database)
{
_database = database;
+ _providers = providers;
}
///
@@ -46,9 +53,35 @@ namespace Kyoo.Controllers
{
await base.Create(obj);
_database.Entry(obj).State = EntityState.Added;
+ obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Added);
await _database.SaveChangesAsync($"Trying to insert a duplicated collection (slug {obj.Slug} already exists).");
return obj;
}
+
+ ///
+ protected override async Task Validate(Collection resource)
+ {
+ await base.Validate(resource);
+ await resource.ExternalIDs.ForEachAsync(async x =>
+ {
+ x.Provider = await _providers.CreateIfNotExists(x.Provider);
+ x.ProviderID = x.Provider.ID;
+ x.ResourceType = nameof(Collection);
+ _database.Entry(x.Provider).State = EntityState.Detached;
+ });
+ }
+
+ ///
+ protected override async Task EditRelations(Collection resource, Collection changed, bool resetOld)
+ {
+ if (changed.ExternalIDs != null || resetOld)
+ {
+ await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync();
+ resource.ExternalIDs = changed.ExternalIDs;
+ }
+
+ await base.EditRelations(resource, changed, resetOld);
+ }
///
public override async Task Delete(Collection obj)
diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs
index 3c1393eb..7a2b0479 100644
--- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs
+++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs
@@ -160,9 +160,10 @@ namespace Kyoo.Controllers
await base.Validate(resource);
await resource.ExternalIDs.ForEachAsync(async x =>
{
- x.Second = await _providers.CreateIfNotExists(x.Second);
- x.SecondID = x.Second.ID;
- _database.Entry(x.Second).State = EntityState.Detached;
+ x.Provider = await _providers.CreateIfNotExists(x.Provider);
+ x.ProviderID = x.Provider.ID;
+ x.ResourceType = nameof(Episode);
+ _database.Entry(x.Provider).State = EntityState.Detached;
});
}
diff --git a/Kyoo/Controllers/Repositories/PeopleRepository.cs b/Kyoo/Controllers/Repositories/PeopleRepository.cs
index 9adb37ee..6267f52f 100644
--- a/Kyoo/Controllers/Repositories/PeopleRepository.cs
+++ b/Kyoo/Controllers/Repositories/PeopleRepository.cs
@@ -73,9 +73,10 @@ namespace Kyoo.Controllers
await base.Validate(resource);
await resource.ExternalIDs.ForEachAsync(async id =>
{
- id.Second = await _providers.CreateIfNotExists(id.Second);
- id.SecondID = id.Second.ID;
- _database.Entry(id.Second).State = EntityState.Detached;
+ id.Provider = await _providers.CreateIfNotExists(id.Provider);
+ id.ProviderID = id.Provider.ID;
+ id.ResourceType = nameof(People);
+ _database.Entry(id.Provider).State = EntityState.Detached;
});
await resource.Roles.ForEachAsync(async role =>
{
diff --git a/Kyoo/Controllers/Repositories/ProviderRepository.cs b/Kyoo/Controllers/Repositories/ProviderRepository.cs
index e48d4f50..13525c9c 100644
--- a/Kyoo/Controllers/Repositories/ProviderRepository.cs
+++ b/Kyoo/Controllers/Repositories/ProviderRepository.cs
@@ -9,21 +9,18 @@ using Microsoft.EntityFrameworkCore;
namespace Kyoo.Controllers
{
///
- /// A local repository to handle providers.
+ /// A local repository to handle providers.
///
public class ProviderRepository : LocalRepository, IProviderRepository
{
///
- /// The database handle
+ /// The database handle
///
private readonly DatabaseContext _database;
-
- ///
- protected override Expression> DefaultSort => x => x.Slug;
///
- /// Create a new .
+ /// Create a new .
///
/// The database handle
public ProviderRepository(DatabaseContext database)
@@ -32,6 +29,9 @@ namespace Kyoo.Controllers
_database = database;
}
+ ///
+ protected override Expression> DefaultSort => x => x.Slug;
+
///
public override async Task> Search(string query)
{
@@ -47,7 +47,8 @@ namespace Kyoo.Controllers
{
await base.Create(obj);
_database.Entry(obj).State = EntityState.Added;
- await _database.SaveChangesAsync($"Trying to insert a duplicated provider (slug {obj.Slug} already exists).");
+ await _database.SaveChangesAsync("Trying to insert a duplicated provider " +
+ $"(slug {obj.Slug} already exists).");
return obj;
}
@@ -56,20 +57,24 @@ namespace Kyoo.Controllers
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
-
+
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
}
///
- public Task>> GetMetadataID(Expression, bool>> where = null,
- Sort> sort = default,
+ public Task> GetMetadataID(Expression> where = null,
+ Sort sort = default,
Pagination limit = default)
- where T : class, IResource
+ where T : class, IMetadata
{
- return ApplyFilters(_database.MetadataIds().Include(y => y.Second),
- x => _database.MetadataIds().FirstOrDefaultAsync(y => y.FirstID == x),
- x => x.FirstID,
+ string discriminator = typeof(T).Name;
+ return ApplyFilters(_database.MetadataIDs
+ .Include(y => y.Provider)
+ .Where(x => x.ResourceType == discriminator),
+ x => _database.MetadataIDs.FirstOrDefaultAsync(y => y.ResourceID == x
+ && y.ResourceType == discriminator),
+ x => x.ResourceID,
where,
sort,
limit);
diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs
index e0036982..45aa4554 100644
--- a/Kyoo/Controllers/Repositories/SeasonRepository.cs
+++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs
@@ -106,9 +106,10 @@ namespace Kyoo.Controllers
await base.Validate(resource);
await resource.ExternalIDs.ForEachAsync(async id =>
{
- id.Second = await _providers.CreateIfNotExists(id.Second);
- id.SecondID = id.Second.ID;
- _database.Entry(id.Second).State = EntityState.Detached;
+ id.Provider = await _providers.CreateIfNotExists(id.Provider);
+ id.ProviderID = id.Provider.ID;
+ id.ResourceType = nameof(Season);
+ _database.Entry(id.Provider).State = EntityState.Detached;
});
}
diff --git a/Kyoo/Controllers/Repositories/ShowRepository.cs b/Kyoo/Controllers/Repositories/ShowRepository.cs
index 769cb232..37921c4d 100644
--- a/Kyoo/Controllers/Repositories/ShowRepository.cs
+++ b/Kyoo/Controllers/Repositories/ShowRepository.cs
@@ -101,9 +101,10 @@ namespace Kyoo.Controllers
});
await resource.ExternalIDs.ForEachAsync(async id =>
{
- id.Second = await _providers.CreateIfNotExists(id.Second);
- id.SecondID = id.Second.ID;
- _database.Entry(id.Second).State = EntityState.Detached;
+ id.Provider = await _providers.CreateIfNotExists(id.Provider);
+ id.ProviderID = id.Provider.ID;
+ id.ResourceType = nameof(Show);
+ _database.Entry(id.Provider).State = EntityState.Detached;
});
await resource.People.ForEachAsync(async role =>
{
diff --git a/Kyoo/Controllers/Repositories/StudioRepository.cs b/Kyoo/Controllers/Repositories/StudioRepository.cs
index 516b7c08..0422c382 100644
--- a/Kyoo/Controllers/Repositories/StudioRepository.cs
+++ b/Kyoo/Controllers/Repositories/StudioRepository.cs
@@ -18,6 +18,11 @@ namespace Kyoo.Controllers
///
private readonly DatabaseContext _database;
+ ///
+ /// A provider repository to handle externalID creation and deletion
+ ///
+ private readonly IProviderRepository _providers;
+
///
protected override Expression> DefaultSort => x => x.Name;
@@ -26,10 +31,12 @@ namespace Kyoo.Controllers
/// Create a new .
///
/// The database handle
- public StudioRepository(DatabaseContext database)
+ /// A provider repository
+ public StudioRepository(DatabaseContext database, IProviderRepository providers)
: base(database)
{
_database = database;
+ _providers = providers;
}
///
@@ -50,6 +57,31 @@ namespace Kyoo.Controllers
await _database.SaveChangesAsync($"Trying to insert a duplicated studio (slug {obj.Slug} already exists).");
return obj;
}
+
+ ///
+ protected override async Task Validate(Studio resource)
+ {
+ await base.Validate(resource);
+ await resource.ExternalIDs.ForEachAsync(async x =>
+ {
+ x.Provider = await _providers.CreateIfNotExists(x.Provider);
+ x.ProviderID = x.Provider.ID;
+ x.ResourceType = nameof(Studio);
+ _database.Entry(x.Provider).State = EntityState.Detached;
+ });
+ }
+
+ ///
+ protected override async Task EditRelations(Studio resource, Studio changed, bool resetOld)
+ {
+ if (changed.ExternalIDs != null || resetOld)
+ {
+ await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync();
+ resource.ExternalIDs = changed.ExternalIDs;
+ }
+
+ await base.EditRelations(resource, changed, resetOld);
+ }
///
public override async Task Delete(Studio obj)