Working with the provider for TheTvDB.

This commit is contained in:
Zoe Roux 2019-08-05 04:00:31 +02:00
parent 054a2718b7
commit 880434186e
9 changed files with 229 additions and 19 deletions

3
.gitignore vendored
View File

@ -337,4 +337,5 @@ ASALocalRun/
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb
/Kyoo/TheTVDB-Credentials.json

View File

@ -40,7 +40,7 @@ namespace Kyoo.InternalAPI
return null;
}
public void Scan(string folderPath)
public async void Scan(string folderPath)
{
string[] files = Directory.GetFiles(folderPath);
@ -50,7 +50,7 @@ namespace Kyoo.InternalAPI
{
Debug.WriteLine("&Should insert this: " + file);
string patern = @".*\\(?<ShowTitle>.+?) S(?<Season>\d+)E(?<Episode>\d+)";
string patern = config.GetValue<string>("regex");
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
Match match = regex.Match(file);
@ -63,7 +63,10 @@ namespace Kyoo.InternalAPI
if(!libraryManager.IsShowRegistered(ShowPath))
{
Show show = metadataProvider.GetShowFromName(ShowTitle);
Show show = await metadataProvider.GetShowFromName(ShowTitle);
Debug.WriteLine("&Show Name: " + show.Title + " Overview: " + show.Overview);
//long showID = libraryManager.RegisterShow(show);
}
}
}

View File

@ -27,7 +27,7 @@ namespace Kyoo.InternalAPI
string createStatement = @"CREATE TABLE shows(
id INTEGER PRIMARY KEY UNIQUE,
uri TEXT UNIQUE,
slug TEXT UNIQUE,
title TEXT,
aliases TEXT,
path TEXT,
@ -94,7 +94,7 @@ namespace Kyoo.InternalAPI
CREATE TABLE libraries(
id INTEGER PRIMARY KEY UNIQUE,
uri TEXT UNIQUE,
slug TEXT UNIQUE,
name TEXT
);
CREATE TABLE librariesLinks(
@ -106,7 +106,7 @@ namespace Kyoo.InternalAPI
CREATE TABLE studios(
id INTEGER PRIMARY KEY UNIQUE,
uri TEXT UNIQUE,
slug TEXT UNIQUE,
name TEXT
);
CREATE TABLE studiosLinks(
@ -118,7 +118,7 @@ namespace Kyoo.InternalAPI
CREATE TABLE people(
id INTEGER PRIMARY KEY UNIQUE,
uri TEXT UNIQUE,
slug TEXT UNIQUE,
name TEXT,
imgPrimary TEXT,
externalIDs TEXT
@ -134,7 +134,7 @@ namespace Kyoo.InternalAPI
CREATE TABLE genres(
id INTEGER PRIMARY KEY UNIQUE,
uri TEXT UNIQUE,
slug TEXT UNIQUE,
name TEXT
);
CREATE TABLE genresLinks(

View File

@ -1,9 +1,12 @@
using Kyoo.Models;
using System.Threading.Tasks;
namespace Kyoo.InternalAPI
{
public interface IMetadataProvider
{
Show GetShowFromName(string showName);
Task<Show> GetShowFromID(string externalIDs);
Task<Show> GetShowFromName(string showName);
}
}

View File

@ -1,12 +1,164 @@
using Kyoo.Models;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace Kyoo.InternalAPI.MetadataProvider
{
public class ProviderTheTvDB : IMetadataProvider
public class ProviderTheTvDB : ProviderHelper, IMetadataProvider
{
public Show GetShowFromName(string showName)
public override string Provider => "TvDB";
private struct DataTvDB
{
throw new System.NotImplementedException();
public string seriesName;
public string overview;
public string slug;
public string network;
public string status;
public int id;
public string firstAired;
public string banner;
public string[] aliases;
}
async Task<string> Authentificate()
{
WebRequest request = WebRequest.Create("https://api.thetvdb.com/login");
request.Method = "POST";
request.Timeout = 12000;
request.ContentType = "application/json";
string json = "{ \"apikey\": \"IM2OXA8UHUIU0GH6\" }";
byte[] bytes = Encoding.ASCII.GetBytes(json);
request.ContentLength = bytes.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
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();
var obj = new { Token = "" };
return JsonConvert.DeserializeAnonymousType(content, obj).Token;
}
}
else
Debug.WriteLine("&Couldn't authentificate in TheTvDB API.\nError status: " + response.StatusCode + " Message: " + response.StatusDescription);
return null;
}
public async Task<Show> GetShowFromName(string showName)
{
string token = await Authentificate();
Debug.WriteLine("&Sucess, token = " + token);
if (token != null)
{
WebRequest request = WebRequest.Create("https://api.thetvdb.com/search/series?name=" + HttpUtility.HtmlEncode(showName));
request.Method = "GET";
request.Timeout = 12000;
request.ContentType = "application/json";
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
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();
var model = new { data = new DataTvDB[0] };
DataTvDB data = JsonConvert.DeserializeAnonymousType(content, model).data[0];
long? startYear = null;
if (!long.TryParse(data.firstAired?.Substring(4), out long year))
startYear = year;
Show show = new Show(-1, ToSlug(showName), data.seriesName, data.aliases?.ToList(), data.overview, null, startYear, null, null, null, null, null, null, string.Format("{0}={1}|", Provider, data.id));
return await GetShowFromID(show.ExternalIDs) ?? show;
}
}
else
{
Debug.WriteLine("&TheTvDB Provider couldn't work for this show: " + showName + ".\nError Code: " + response.StatusCode + " Message: " + response.StatusDescription);
response.Close();
}
}
return new Show() { Slug = ToSlug(showName), Title = showName };
}
public async Task<Show> GetShowFromID(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/search/series/" + id);
request.Method = "GET";
request.Timeout = 12000;
request.ContentType = "application/json";
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
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();
var model = new { data = new DataTvDB[0] };
DataTvDB data = JsonConvert.DeserializeAnonymousType(content, model).data[0];
long? startYear = null;
if (!long.TryParse(data.firstAired?.Substring(4), out long year))
startYear = year;
Show show = new Show(-1, ToSlug(showName), data.seriesName, data.aliases?.ToList(), data.overview, null, startYear, null, null, null, null, null, null, string.Format("TvDB={0}|", data.id));
return await GetShowFromID(show.ExternalIDs) ?? show;
}
}
else
{
Debug.WriteLine("&TheTvDB Provider couldn't work for the show with the id: " + id + ".\nError Code: " + response.StatusCode + " Message: " + response.StatusDescription);
response.Close();
return null;
}
}
}
}

View File

@ -0,0 +1,48 @@
using System.Text;
using System.Text.RegularExpressions;
namespace Kyoo.InternalAPI.MetadataProvider
{
public abstract class ProviderHelper
{
public abstract string Provider { get; }
public string GetId(string externalIDs)
{
if (externalIDs.Contains(Provider))
{
int startIndex = externalIDs.IndexOf(Provider) + Provider.Length;
return externalIDs.Substring(startIndex, externalIDs.IndexOf('|', startIndex) - startIndex);
}
else
return null;
}
public string ToSlug(string showTitle)
{
if (showTitle == null)
return null;
//First to lower case
showTitle = showTitle.ToLowerInvariant();
//Remove all accents
//var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(showTitle);
//showTitle = Encoding.ASCII.GetString(bytes);
//Replace spaces
showTitle = Regex.Replace(showTitle, @"\s", "-", RegexOptions.Compiled);
//Remove invalid chars
showTitle = Regex.Replace(showTitle, @"[^\w\s\p{Pd}]", "", RegexOptions.Compiled);
//Trim dashes from end
showTitle = showTitle.Trim('-', '_');
//Replace double occurences of - or \_
showTitle = Regex.Replace(showTitle, @"([-_]){2,}", "$1", RegexOptions.Compiled);
return showTitle;
}
}
}

View File

@ -17,6 +17,7 @@
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Data.SQLite" Version="1.0.111" />
</ItemGroup>

View File

@ -5,9 +5,9 @@ namespace Kyoo.Models
{
public class Show
{
public readonly long id;
public readonly long id = -1;
public string Uri;
public string Slug;
public string Title;
public List<string> Aliases;
public string Overview;
@ -24,11 +24,12 @@ namespace Kyoo.Models
public string ExternalIDs;
public Show() { }
public Show(long id, string uri, string title, List<string> aliases, string overview, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgBanner, string imgLogo, string imgBackdrop, string externalIDs)
public Show(long id, string slug, string title, List<string> aliases, string overview, Status? status, long? startYear, long? endYear, string imgPrimary, string imgThumb, string imgBanner, string imgLogo, string imgBackdrop, string externalIDs)
{
this.id = id;
Uri = uri;
Slug = slug;
Title = title;
Aliases = aliases;
Overview = overview;
@ -46,7 +47,7 @@ namespace Kyoo.Models
public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader)
{
return new Show((long)reader["id"],
reader["uri"] as string,
reader["slug"] as string,
reader["title"] as string,
(reader["aliases"] as string)?.Split('|').ToList() ?? null,
reader["overview"] as string,

View File

@ -2,5 +2,6 @@
"databasePath": "C://Projects/database.db",
"libraryPaths": [
"D:\\Videos"
]
],
"regex": ".*\\\\(?<ShowTitle>.+?) S(?<Season>\\d+)E(?<Episode>\\d+)"
}