Creating provider manager, creating season creation etc.

This commit is contained in:
Zoe Roux 2019-08-09 02:05:32 +02:00
parent 7f503cf3d3
commit 69a8ec1c18
11 changed files with 229 additions and 43 deletions

View File

@ -56,12 +56,12 @@ namespace Kyoo.InternalAPI
string ShowPath = Path.GetDirectoryName(file);
string ShowTitle = match.Groups["ShowTitle"].Value;
bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long Season);
bool episodeSucess = long.TryParse(match.Groups["Episode"].Value, out long Episode);
bool seasonSuccess = long.TryParse(match.Groups["Season"].Value, out long seasonNumber);
bool episodeSucess = long.TryParse(match.Groups["Episode"].Value, out long episodeNumber);
Debug.WriteLine("&ShowPath: " + ShowPath + " Show: " + ShowTitle + " season: " + Season + " episode: " + Episode);
Debug.WriteLine("&ShowPath: " + ShowPath + " Show: " + ShowTitle + " season: " + seasonNumber + " episode: " + episodeNumber);
if (!libraryManager.IsShowRegistered(ShowPath, out long? showID))
if (!libraryManager.IsShowRegistered(ShowPath, out long showID))
{
Debug.WriteLine("&Should register show: " + ShowTitle);
Show show = await metadataProvider.GetShowFromName(ShowTitle, ShowPath);
@ -69,6 +69,15 @@ namespace Kyoo.InternalAPI
}
Debug.WriteLine("&Show ID: " + showID);
if(!libraryManager.IsSeasonRegistered(showID, seasonNumber, out long seasonID))
{
Debug.WriteLine("&Should register season: " + ShowTitle + " - " + seasonNumber);
Season season = await metadataProvider.GetSeason(showID, seasonNumber);
showID = libraryManager.RegisterSeason(season);
}
Debug.WriteLine("&Season ID: " + seasonID);
}
}
}

View File

@ -5,15 +5,18 @@ namespace Kyoo.InternalAPI
{
public interface ILibraryManager
{
//Read values
//Public value reading
IEnumerable<Show> QueryShows(string selection);
//Check if value exists
bool IsEpisodeRegistered(string episodePath);
bool IsShowRegistered(string showPath);
bool IsShowRegistered(string showPath, out long? showID);
bool IsShowRegistered(string showPath, out long showID);
bool IsSeasonRegistered(long showID, long seasonNumber);
bool IsSeasonRegistered(long showID, long seasonNumber, out long seasonID);
bool IsEpisodeRegistered(string episodePath);
//Register values
long RegisterShow(Show show);
long RegisterSeason(Season season);
}
}

View File

@ -163,6 +163,7 @@ namespace Kyoo.InternalAPI
sqlConnection.Close();
}
#region Read the database
public IEnumerable<Show> QueryShows(string selection)
{
string query = "SELECT * FROM shows;";
@ -179,18 +180,9 @@ namespace Kyoo.InternalAPI
return shows;
}
}
#endregion
public bool IsEpisodeRegistered(string episodePath)
{
string query = "SELECT 1 FROM episodes WHERE path = $path;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$path", episodePath);
return cmd.ExecuteScalar() != null;
}
}
#region Check if items exists
public bool IsShowRegistered(string showPath)
{
string query = "SELECT 1 FROM shows WHERE path = $path;";
@ -202,18 +194,56 @@ namespace Kyoo.InternalAPI
}
}
public bool IsShowRegistered(string showPath, out long? showID)
public bool IsShowRegistered(string showPath, out long showID)
{
string query = "SELECT 1 FROM shows WHERE path = $path;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$path", showPath);
showID = cmd.ExecuteScalar() as long?;
showID = cmd.ExecuteScalar() as long? ?? -1;
return showID != null;
return showID != -1;
}
}
public bool IsSeasonRegistered(long showID, long seasonNumber)
{
string query = "SELECT 1 FROM seasons WHERE showID = $showID AND seasonNumber = $seasonNumber;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$showID", showID);
cmd.Parameters.AddWithValue("$seasonNumber", seasonNumber);
return cmd.ExecuteScalar() != null;
}
}
public bool IsSeasonRegistered(long showID, long seasonNumber, out long seasonID)
{
string query = "SELECT 1 FROM seasons WHERE showID = $showID AND seasonNumber = $seasonNumber;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$showID", showID);
cmd.Parameters.AddWithValue("$seasonNumber", seasonNumber);
seasonID = cmd.ExecuteScalar() as long? ?? -1;
return seasonID != -1;
}
}
public bool IsEpisodeRegistered(string episodePath)
{
string query = "SELECT 1 FROM episodes WHERE path = $path;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$path", episodePath);
return cmd.ExecuteScalar() != null;
}
}
#endregion
#region Write Into The Database
public long RegisterShow(Show show)
{
string query = "INSERT INTO shows (slug, title, aliases, path, overview, genres, startYear, endYear, imgPrimary, imgThumb, imgLogo, imgBackdrop, externalIDs) VALUES($slug, $title, $aliases, $path, $overview, $genres, $startYear, $endYear, $imgPrimary, $imgThumb, $imgLogo, $imgBackdrop, $externalIDs);";
@ -240,5 +270,26 @@ namespace Kyoo.InternalAPI
return (long)cmd.ExecuteScalar();
}
}
public long RegisterSeason(Season season)
{
string query = "INSERT INTO seasons (showID, seasonNumber, title, overview, year, imgPrimary, externalIDs) VALUES($showID, $seasonNumber, $title, $overview, $year, $imgPrimary, $externalIDs);";
Debug.WriteLine("&SQL QUERY:: " + query);
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$showID", season.ShowID);
cmd.Parameters.AddWithValue("$seasonNumber", season.seasonNumber);
cmd.Parameters.AddWithValue("$title", season.Title);
cmd.Parameters.AddWithValue("$overview", season.Overview);
cmd.Parameters.AddWithValue("$year", season.year);
cmd.Parameters.AddWithValue("$imgPrimary", season.ImgPrimary);
cmd.Parameters.AddWithValue("$externalIDs", season.ExternalIDs);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT LAST_INSERT_ROWID()";
return (long)cmd.ExecuteScalar();
}
}
#endregion
}
}

View File

@ -5,10 +5,14 @@ namespace Kyoo.InternalAPI
{
public interface IMetadataProvider
{
Task<Show> CompleteShow(Show show);
//For the show
Task<Show> GetShowByID(string id);
Task<Show> GetShowFromName(string showName, string showPath);
Task<Show> GetImages(Show show);
//For the seasons
Task<Season> GetSeason(string showName, int seasonNumber);
}
}

View File

@ -7,13 +7,13 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace Kyoo.InternalAPI.MetadataProvider
{
public class ShowProviderTvDB : HelperTvDB, IMetadataProvider
[MetaProvider]
public class ProviderTheTvDB : HelperTvDB, IMetadataProvider
{
private struct SearchTbDB
{
@ -122,7 +122,7 @@ namespace Kyoo.InternalAPI.MetadataProvider
GetYear(data.firstAired),
null, //endYear
string.Format("{0}={1}|", Provider, data.id));
return await CompleteShow(show);
return await GetShowByID(GetID(show.ExternalIDs)) ?? show;
}
}
else
@ -140,17 +140,12 @@ namespace Kyoo.InternalAPI.MetadataProvider
return new Show() { Slug = ToSlug(showName), Title = showName };
}
public async Task<Show> CompleteShow(Show show)
public async Task<Show> GetShowByID(string id)
{
string id = GetId(show.ExternalIDs);
if (id == null)
return show;
string token = await Authentificate();
if (token == null)
return show;
return null;
WebRequest request = WebRequest.Create("https://api.thetvdb.com/series/" + id);
request.Method = "GET";
@ -174,12 +169,17 @@ namespace Kyoo.InternalAPI.MetadataProvider
var model = new { data = new DataTvDb(), errors = new ErrorsTvDB() };
DataTvDb data = JsonConvert.DeserializeAnonymousType(content, model).data;
show.Title = data.seriesName;
show.Aliases = data.aliases;
show.Overview = data.overview;
show.Genres = data.genre;
show.Status = GetStatus(data.status);
show.StartYear = GetYear(data.firstAired);
Show show = new Show(-1,
null, //Slug
data.seriesName,
data.aliases,
null, //Path
data.overview,
data.genre,
GetStatus(data.status),
GetYear(data.firstAired),
null, //endYear
string.Format("TvDB={0}|", id));
await GetImages(show);
return show;
}
@ -188,20 +188,20 @@ namespace Kyoo.InternalAPI.MetadataProvider
{
Debug.WriteLine("&TheTvDB Provider couldn't work for the show with the id: " + id + ".\nError Code: " + response.StatusCode + " Message: " + response.StatusDescription);
response.Close();
return show;
return null;
}
}
catch(WebException ex)
{
Debug.WriteLine("&TheTvDB Provider couldn't work for the show with the id: " + id + ".\nError Code: " + ex.Status);
return show;
return null;
}
}
public async Task<Show> GetImages(Show show)
{
Debug.WriteLine("&Getting images for: " + show.Title);
string id = GetId(show.ExternalIDs);
string id = GetID(show.ExternalIDs);
if (id == null)
return show;
@ -248,5 +248,10 @@ namespace Kyoo.InternalAPI.MetadataProvider
return show;
}
public Task<Season> GetSeason(string showName, int seasonNumber)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,13 @@
using System;
namespace Kyoo.InternalAPI.MetadataProvider
{
[AttributeUsage(AttributeTargets.Class)]
public class MetaProvider : Attribute
{
public MetaProvider()
{
}
}
}

View File

@ -8,7 +8,7 @@ namespace Kyoo.InternalAPI.MetadataProvider
{
public abstract string Provider { get; }
public string GetId(string externalIDs)
public string GetID(string externalIDs)
{
if (externalIDs.Contains(Provider))
{

View File

@ -0,0 +1,84 @@
using Kyoo.InternalAPI.MetadataProvider;
using Kyoo.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
namespace Kyoo.InternalAPI
{
public class ProviderManager : IMetadataProvider
{
private readonly List<IMetadataProvider> providers = new List<IMetadataProvider>();
private readonly IConfiguration config;
public ProviderManager(IConfiguration configuration)
{
config = configuration;
LoadProviders();
}
void LoadProviders()
{
providers.Clear();
providers.Add(new ProviderTheTvDB());
string[] pluginsPaths = Directory.GetFiles(config.GetValue<string>("providerPlugins"));
List<Assembly> plugins = new List<Assembly>();
List<Type> types = new List<Type>();
for (int i = 0; i < pluginsPaths.Length; i++)
{
plugins.Add(Assembly.LoadFile(pluginsPaths[i]));
types.AddRange(plugins[i].GetTypes());
}
List<Type> providersPlugins = types.FindAll(x =>
{
object[] atr = x.GetCustomAttributes(typeof(MetaProvider), false);
if (atr == null || atr.Length == 0)
return false;
List<Type> interfaces = new List<Type>(x.GetInterfaces());
if (interfaces.Contains(typeof(IMetadataProvider)))
return true;
return false;
});
providers.AddRange(providersPlugins.ConvertAll<IMetadataProvider>(x => Activator.CreateInstance(x) as IMetadataProvider));
}
//public Show MergeShows(Show baseShow, Show newShow)
//{
//}
//For all the following methods, it should use all providers and merge the data.
public Task<Show> GetImages(Show show)
{
return providers[0].GetImages(show);
}
public Task<Season> GetSeason(string showName, int seasonNumber)
{
return providers[0].GetSeason(showName, seasonNumber);
}
public Task<Show> GetShowByID(string id)
{
return providers[0].GetShowByID(id);
}
public Task<Show> GetShowFromName(string showName, string showPath)
{
return providers[0].GetShowFromName(showName, showPath);
}
}
}

16
Kyoo/Models/Season.cs Normal file
View File

@ -0,0 +1,16 @@
namespace Kyoo.Models
{
public class Season
{
public readonly long id;
public readonly long ShowID;
public long seasonNumber;
public string Title;
public string Overview;
public long year;
public string ImgPrimary;
public string ExternalIDs;
}
}

View File

@ -32,7 +32,7 @@ namespace Kyoo
services.AddSingleton<ILibraryManager, LibraryManager>();
services.AddHostedService<Crawler>();
services.AddSingleton<IMetadataProvider, ShowProviderTvDB>(); //Shouldn't use it like that, it won't work with multiple providers.
services.AddSingleton<IMetadataProvider, ProviderManager>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -1,5 +1,6 @@
{
"databasePath": "C://Projects/database.db",
"providerPlugins": "C://Projects/Plugins/Providers",
"libraryPaths": [
"D:\\Videos"
],