Adding people implementations inside the library manager.

This commit is contained in:
Zoe Roux 2019-08-25 23:33:12 +02:00
parent 77990ea9b3
commit 373c05e3c5
15 changed files with 268 additions and 50 deletions

View File

@ -15,5 +15,5 @@
.main .main
{ {
background-color: var(--primary);
} }

View File

@ -1,6 +1,7 @@
using Kyoo.Models; using Kyoo.Models;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -122,6 +123,9 @@ namespace Kyoo.InternalAPI
Show show = await metadataProvider.GetShowFromName(showName, showPath); Show show = await metadataProvider.GetShowFromName(showName, showPath);
showProviderIDs = show.ExternalIDs; showProviderIDs = show.ExternalIDs;
showID = libraryManager.RegisterShow(show); showID = libraryManager.RegisterShow(show);
List<People> actors = await metadataProvider.GetPeople(show.ExternalIDs);
libraryManager.RegisterShowPeople(showID, actors);
} }
else else
showProviderIDs = libraryManager.GetShowExternalIDs(showID); showProviderIDs = libraryManager.GetShowExternalIDs(showID);

View File

@ -8,6 +8,7 @@ namespace Kyoo.InternalAPI
//Read values //Read values
string GetShowExternalIDs(long showID); string GetShowExternalIDs(long showID);
IEnumerable<Show> QueryShows(string selection); IEnumerable<Show> QueryShows(string selection);
List<People> GetPeople(long showID);
//Public read //Public read
IEnumerable<Library> GetLibraries(); IEnumerable<Library> GetLibraries();
@ -24,5 +25,7 @@ namespace Kyoo.InternalAPI
long RegisterShow(Show show); long RegisterShow(Show show);
long RegisterSeason(Season season); long RegisterSeason(Season season);
long RegisterEpisode(Episode episode); long RegisterEpisode(Episode episode);
void RegisterShowPeople(long showID, List<People> actors);
} }
} }

View File

@ -224,11 +224,29 @@ namespace Kyoo.InternalAPI
SQLiteDataReader reader = cmd.ExecuteReader(); SQLiteDataReader reader = cmd.ExecuteReader();
if (reader.Read()) if (reader.Read())
return Show.FromReader(reader); return Show.FromReader(reader).SetPeople(this);
else else
return null; return null;
} }
} }
public List<People> GetPeople(long showID)
{
string query = "SELECT people.id, people.slug, people.name, people.imgPrimary, people.externalIDs, l.role, l.type FROM people JOIN peopleLinks l ON l.peopleID = people.id WHERE l.showID = $showID;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$showID", showID);
SQLiteDataReader reader = cmd.ExecuteReader();
List<People> people = new List<People>();
while (reader.Read())
people.Add(People.FromReader(reader));
return people;
}
}
#endregion #endregion
#region Check if items exists #region Check if items exists
@ -298,20 +316,20 @@ namespace Kyoo.InternalAPI
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);"; 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);";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{ {
cmd.Parameters.AddWithValue("slug", show.Slug); cmd.Parameters.AddWithValue("$slug", show.Slug);
cmd.Parameters.AddWithValue("title", show.Title); cmd.Parameters.AddWithValue("$title", show.Title);
cmd.Parameters.AddWithValue("aliases", show.GetAliases()); cmd.Parameters.AddWithValue("$aliases", show.GetAliases());
cmd.Parameters.AddWithValue("path", show.Path); cmd.Parameters.AddWithValue("$path", show.Path);
cmd.Parameters.AddWithValue("overview", show.Overview); cmd.Parameters.AddWithValue("$overview", show.Overview);
cmd.Parameters.AddWithValue("genres", show.GetGenres()); cmd.Parameters.AddWithValue("$genres", show.GetGenres());
cmd.Parameters.AddWithValue("status", show.Status); cmd.Parameters.AddWithValue("$status", show.Status);
cmd.Parameters.AddWithValue("startYear", show.StartYear); cmd.Parameters.AddWithValue("$startYear", show.StartYear);
cmd.Parameters.AddWithValue("endYear", show.EndYear); cmd.Parameters.AddWithValue("$endYear", show.EndYear);
cmd.Parameters.AddWithValue("imgPrimary", show.ImgPrimary); cmd.Parameters.AddWithValue("$imgPrimary", show.ImgPrimary);
cmd.Parameters.AddWithValue("imgThumb", show.ImgThumb); cmd.Parameters.AddWithValue("$imgThumb", show.ImgThumb);
cmd.Parameters.AddWithValue("imgLogo", show.ImgLogo); cmd.Parameters.AddWithValue("$imgLogo", show.ImgLogo);
cmd.Parameters.AddWithValue("imgBackdrop", show.ImgBackdrop); cmd.Parameters.AddWithValue("$imgBackdrop", show.ImgBackdrop);
cmd.Parameters.AddWithValue("externalIDs", show.ExternalIDs); cmd.Parameters.AddWithValue("$externalIDs", show.ExternalIDs);
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT LAST_INSERT_ROWID()"; cmd.CommandText = "SELECT LAST_INSERT_ROWID()";
@ -344,9 +362,9 @@ namespace Kyoo.InternalAPI
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{ {
cmd.Parameters.AddWithValue("$showID", episode.ShowID); cmd.Parameters.AddWithValue("$showID", episode.ShowID);
cmd.Parameters.AddWithValue("seasonID", episode.SeasonID); cmd.Parameters.AddWithValue("$seasonID", episode.SeasonID);
cmd.Parameters.AddWithValue("episodeNumber", episode.episodeNumber); cmd.Parameters.AddWithValue("$episodeNumber", episode.episodeNumber);
cmd.Parameters.AddWithValue("path", episode.Path); cmd.Parameters.AddWithValue("$path", episode.Path);
cmd.Parameters.AddWithValue("$title", episode.Title); cmd.Parameters.AddWithValue("$title", episode.Title);
cmd.Parameters.AddWithValue("$overview", episode.Overview); cmd.Parameters.AddWithValue("$overview", episode.Overview);
cmd.Parameters.AddWithValue("$releaseDate", episode.ReleaseDate); cmd.Parameters.AddWithValue("$releaseDate", episode.ReleaseDate);
@ -359,6 +377,38 @@ namespace Kyoo.InternalAPI
return (long)cmd.ExecuteScalar(); return (long)cmd.ExecuteScalar();
} }
} }
public void RegisterShowPeople(long showID, List<People> people)
{
string query = "INSERT INTO people (slug, name, imgPrimary, externalIDs) VALUES($slug, $name, $imgPrimary, $externalIDs);";
string linkQuery = "INSERT INTO peopleLinks (peopleID, showID, role, type) VALUES($peopleID, $showID, $role, $type);";
for (int i = 0; i < people.Count; i++)
{
long peopleID;
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{
cmd.Parameters.AddWithValue("$slug", people[i].slug);
cmd.Parameters.AddWithValue("$name", people[i].Name);
cmd.Parameters.AddWithValue("$imgPrimary", people[i].imgPrimary);
cmd.Parameters.AddWithValue("$externalIDs", people[i].externalIDs);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT LAST_INSERT_ROWID()";
peopleID = (long)cmd.ExecuteScalar();
}
using (SQLiteCommand cmd = new SQLiteCommand(linkQuery, sqlConnection))
{
cmd.Parameters.AddWithValue("$peopleID", peopleID);
cmd.Parameters.AddWithValue("$showID", showID);
cmd.Parameters.AddWithValue("$role", people[i].Role);
cmd.Parameters.AddWithValue("$type", people[i].Type);
cmd.ExecuteNonQuery();
}
}
}
#endregion #endregion
} }
} }

View File

@ -1,4 +1,5 @@
using Kyoo.Models; using Kyoo.Models;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Kyoo.InternalAPI namespace Kyoo.InternalAPI
@ -9,6 +10,7 @@ namespace Kyoo.InternalAPI
Task<Show> GetShowByID(string id); Task<Show> GetShowByID(string id);
Task<Show> GetShowFromName(string showName, string showPath); Task<Show> GetShowFromName(string showName, string showPath);
Task<Show> GetImages(Show show); Task<Show> GetImages(Show show);
Task<List<People>> GetPeople(string id);
//For the seasons //For the seasons
Task<Season> GetSeason(string showName, long seasonNumber); Task<Season> GetSeason(string showName, long seasonNumber);

View File

@ -90,7 +90,7 @@ namespace Kyoo.InternalAPI.MetadataProvider
if (token != null) if (token != null)
{ {
WebRequest request = WebRequest.Create("https://api.thetvdb.com/search/series?name=" + HttpUtility.HtmlEncode(showName)); WebRequest request = WebRequest.Create("https://api.thetvdb.com/search/series?name=" + HttpUtility.UrlEncode(showName));
request.Method = "GET"; request.Method = "GET";
request.Timeout = 12000; request.Timeout = 12000;
request.ContentType = "application/json"; request.ContentType = "application/json";
@ -138,7 +138,7 @@ namespace Kyoo.InternalAPI.MetadataProvider
} }
} }
return new Show() { Slug = ToSlug(showName), Title = showName }; return new Show() { Slug = ToSlug(showName), Title = showName, Path = showPath };
} }
public async Task<Show> GetShowByID(string id) public async Task<Show> GetShowByID(string id)
@ -323,5 +323,54 @@ namespace Kyoo.InternalAPI.MetadataProvider
return null; return null;
} }
} }
public async Task<List<People>> GetPeople(string externalIDs)
{
string id = GetID(externalIDs);
if (id == null)
return null;
string token = await Authentificate();
if (token == null)
return null;
WebRequest request = WebRequest.Create("https://api.thetvdb.com/series/" + id + "/actors");
request.Method = "GET";
request.Timeout = 12000;
request.ContentType = "application/json";
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
try
{
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
if (response.StatusCode == HttpStatusCode.OK)
{
Stream stream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(stream))
{
string content = await reader.ReadToEndAsync();
stream.Close();
response.Close();
dynamic data = JsonConvert.DeserializeObject(content);
return (((IEnumerable<dynamic>)data.data).OrderBy(x => x.sortOrder)).ToList().ConvertAll(x => { return new People(-1, ToSlug((string)x.name), (string)x.name, (string)x.role, null, "https://www.thetvdb.com/banners/" + (string)x.image, string.Format("TvDB={0}|", x.id)); });
}
}
else
{
Debug.WriteLine("&TheTvDB Provider couldn't work for the actors of the show: " + id + ".\nError Code: " + response.StatusCode + " Message: " + response.StatusDescription);
response.Close();
return null;
}
}
catch (WebException ex)
{
Debug.WriteLine("&TheTvDB Provider couldn't work for the actors of the show: " + id + ".\nError Code: " + ex.Status);
return null;
}
}
} }
} }

View File

@ -148,5 +148,11 @@ namespace Kyoo.InternalAPI
episode.Path = episodePath; episode.Path = episodePath;
return thumbnailsManager.Validate(episode); return thumbnailsManager.Validate(episode);
} }
public async Task<List<People>> GetPeople(string id)
{
List<People> actors = await providers[0].GetPeople(id);
return thumbnailsManager.Validate(actors);
}
} }
} }

View File

@ -1,10 +1,12 @@
using Kyoo.Models; using Kyoo.Models;
using System.Collections.Generic;
namespace Kyoo.InternalAPI.ThumbnailsManager namespace Kyoo.InternalAPI.ThumbnailsManager
{ {
public interface IThumbnailsManager public interface IThumbnailsManager
{ {
Show Validate(Show show); Show Validate(Show show);
List<People> Validate(List<People> actors);
Episode Validate(Episode episode); Episode Validate(Episode episode);
} }
} }

View File

@ -1,5 +1,8 @@
using Kyoo.Models; using Kyoo.Models;
using Microsoft.Extensions.Configuration;
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
@ -7,31 +10,64 @@ namespace Kyoo.InternalAPI.ThumbnailsManager
{ {
public class ThumbnailsManager : IThumbnailsManager public class ThumbnailsManager : IThumbnailsManager
{ {
private readonly IConfiguration config;
public ThumbnailsManager(IConfiguration configuration)
{
config = configuration;
}
public Show Validate(Show show) public Show Validate(Show show)
{ {
string localThumb = Path.Combine(show.Path, "poster.jpg"); if (show.ImgPrimary != null)
if (!File.Exists(localThumb))
{ {
using (WebClient client = new WebClient()) string localThumb = Path.Combine(show.Path, "poster.jpg");
if (!File.Exists(localThumb))
{ {
client.DownloadFileAsync(new Uri(show.ImgPrimary), localThumb); using (WebClient client = new WebClient())
{
client.DownloadFileAsync(new Uri(show.ImgPrimary), localThumb);
}
} }
show.ImgPrimary = localThumb;
} }
string localBackdrop = Path.Combine(show.Path, "backdrop.jpg"); if(show.ImgBackdrop != null)
if (!File.Exists(localBackdrop))
{ {
using (WebClient client = new WebClient()) string localBackdrop = Path.Combine(show.Path, "backdrop.jpg");
if (!File.Exists(localBackdrop))
{ {
client.DownloadFileAsync(new Uri(show.ImgBackdrop), localBackdrop); using (WebClient client = new WebClient())
{
client.DownloadFileAsync(new Uri(show.ImgBackdrop), localBackdrop);
}
} }
show.ImgBackdrop = localBackdrop;
} }
show.ImgPrimary = localThumb;
show.ImgBackdrop = localBackdrop;
return show; return show;
} }
public List<People> Validate(List<People> people)
{
for (int i = 0; i < people?.Count; i++)
{
string localThumb = config.GetValue<string>("peoplePath") + "/" + people[i].slug + ".jpg";
if (!File.Exists(localThumb))
{
using (WebClient client = new WebClient())
{
Debug.WriteLine("&" + localThumb);
client.DownloadFileAsync(new Uri(people[i].imgPrimary), localThumb);
}
}
people[i].imgPrimary = localThumb;
}
return people;
}
public Episode Validate(Episode episode) public Episode Validate(Episode episode)
{ {
string localThumb = Path.ChangeExtension(episode.Path, "jpg"); string localThumb = Path.ChangeExtension(episode.Path, "jpg");

View File

@ -1,22 +1,23 @@
using System; using Newtonsoft.Json;
using System;
namespace Kyoo.Models namespace Kyoo.Models
{ {
public class Episode public class Episode
{ {
public readonly long id; [JsonIgnore] public readonly long id;
public long ShowID; [JsonIgnore] public long ShowID;
public long SeasonID; [JsonIgnore] public long SeasonID;
public long episodeNumber; public long episodeNumber;
public string Path; [JsonIgnore] public string Path;
public string Title; public string Title;
public string Overview; public string Overview;
public DateTime ReleaseDate; public DateTime ReleaseDate;
public long Runtime; //This runtime variable should be in seconds (used by the video manager so we need precisions) public long Runtime; //This runtime variable should be in seconds (used by the video manager so we need precisions)
public string ImgPrimary; [JsonIgnore] public string ImgPrimary;
public string ExternalIDs; public string ExternalIDs;
public long RuntimeInMinutes public long RuntimeInMinutes

View File

@ -1,8 +1,10 @@
namespace Kyoo.Models using Newtonsoft.Json;
namespace Kyoo.Models
{ {
public struct Library public struct Library
{ {
public readonly long id; [JsonIgnore] public readonly long id;
public string Slug; public string Slug;
public string Name; public string Name;

38
Kyoo/Models/People.cs Normal file
View File

@ -0,0 +1,38 @@
using Newtonsoft.Json;
namespace Kyoo.Models
{
public class People
{
[JsonIgnore] public long id;
public string slug;
public string Name;
public string Role; //Dynamic data not stored as it in the database
public string Type; //Dynamic data not stored as it in the database ---- Null for now
[JsonIgnore] public string imgPrimary;
public string externalIDs;
public People(long id, string slug, string name, string role, string type, string imgPrimary, string externalIDs)
{
this.id = id;
this.slug = slug;
Name = name;
Role = role;
Type = type;
this.imgPrimary = imgPrimary;
this.externalIDs = externalIDs;
}
public static People FromReader(System.Data.SQLite.SQLiteDataReader reader)
{
return new People((long)reader["id"],
reader["slug"] as string,
reader["name"] as string,
reader["role"] as string,
reader["type"] as string,
reader["imgPrimary"] as string,
reader["externalIDs"] as string);
}
}
}

View File

@ -1,16 +1,18 @@
namespace Kyoo.Models using Newtonsoft.Json;
namespace Kyoo.Models
{ {
public class Season public class Season
{ {
public readonly long id; [JsonIgnore] public readonly long id;
public long ShowID; [JsonIgnore] public long ShowID;
public long seasonNumber; public long seasonNumber;
public string Title; public string Title;
public string Overview; public string Overview;
public long? year; public long? year;
public string ImgPrimary; [JsonIgnore] public string ImgPrimary;
public string ExternalIDs; public string ExternalIDs;
public Season() { } public Season() { }

View File

@ -1,16 +1,18 @@
using System.Collections.Generic; using Kyoo.InternalAPI;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Kyoo.Models namespace Kyoo.Models
{ {
public class Show public class Show
{ {
public readonly long id = -1; [JsonIgnore] public readonly long id = -1;
public string Slug; public string Slug;
public string Title; public string Title;
public IEnumerable<string> Aliases; public IEnumerable<string> Aliases;
public string Path; [JsonIgnore] public string Path;
public string Overview; public string Overview;
public IEnumerable<string> Genres; public IEnumerable<string> Genres;
public Status? Status; public Status? Status;
@ -18,21 +20,29 @@ namespace Kyoo.Models
public long? StartYear; public long? StartYear;
public long? EndYear; public long? EndYear;
public string ImgPrimary; [JsonIgnore] public string ImgPrimary;
public string ImgThumb; [JsonIgnore] public string ImgThumb;
public string ImgLogo; [JsonIgnore] public string ImgLogo;
public string ImgBackdrop; [JsonIgnore] public string ImgBackdrop;
public string ExternalIDs; public string ExternalIDs;
public IEnumerable<People> people; //Used in the rest API excusively.
public string GetAliases() public string GetAliases()
{ {
if (Aliases == null)
return null;
return string.Join('|', Aliases); return string.Join('|', Aliases);
} }
public string GetGenres() public string GetGenres()
{ {
if (Genres == null)
return null;
return string.Join('|', Genres); return string.Join('|', Genres);
} }
@ -98,6 +108,18 @@ namespace Kyoo.Models
Path = path; Path = path;
return this; return this;
} }
public Show SetPeople(People[] people)
{
this.people = people;
return this;
}
public Show SetPeople(ILibraryManager manager)
{
people = manager.GetPeople(id);
return this;
}
} }
public enum Status { Finished, Airing } public enum Status { Finished, Airing }

View File

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