mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Working with the provider for TheTvDB.
This commit is contained in:
parent
054a2718b7
commit
880434186e
1
.gitignore
vendored
1
.gitignore
vendored
@ -338,3 +338,4 @@ ASALocalRun/
|
|||||||
|
|
||||||
# BeatPulse healthcheck temp database
|
# BeatPulse healthcheck temp database
|
||||||
healthchecksdb
|
healthchecksdb
|
||||||
|
/Kyoo/TheTVDB-Credentials.json
|
||||||
|
@ -40,7 +40,7 @@ namespace Kyoo.InternalAPI
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Scan(string folderPath)
|
public async void Scan(string folderPath)
|
||||||
{
|
{
|
||||||
string[] files = Directory.GetFiles(folderPath);
|
string[] files = Directory.GetFiles(folderPath);
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ namespace Kyoo.InternalAPI
|
|||||||
{
|
{
|
||||||
Debug.WriteLine("&Should insert this: " + file);
|
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);
|
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
||||||
Match match = regex.Match(file);
|
Match match = regex.Match(file);
|
||||||
|
|
||||||
@ -63,7 +63,10 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
if(!libraryManager.IsShowRegistered(ShowPath))
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
string createStatement = @"CREATE TABLE shows(
|
string createStatement = @"CREATE TABLE shows(
|
||||||
id INTEGER PRIMARY KEY UNIQUE,
|
id INTEGER PRIMARY KEY UNIQUE,
|
||||||
uri TEXT UNIQUE,
|
slug TEXT UNIQUE,
|
||||||
title TEXT,
|
title TEXT,
|
||||||
aliases TEXT,
|
aliases TEXT,
|
||||||
path TEXT,
|
path TEXT,
|
||||||
@ -94,7 +94,7 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
CREATE TABLE libraries(
|
CREATE TABLE libraries(
|
||||||
id INTEGER PRIMARY KEY UNIQUE,
|
id INTEGER PRIMARY KEY UNIQUE,
|
||||||
uri TEXT UNIQUE,
|
slug TEXT UNIQUE,
|
||||||
name TEXT
|
name TEXT
|
||||||
);
|
);
|
||||||
CREATE TABLE librariesLinks(
|
CREATE TABLE librariesLinks(
|
||||||
@ -106,7 +106,7 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
CREATE TABLE studios(
|
CREATE TABLE studios(
|
||||||
id INTEGER PRIMARY KEY UNIQUE,
|
id INTEGER PRIMARY KEY UNIQUE,
|
||||||
uri TEXT UNIQUE,
|
slug TEXT UNIQUE,
|
||||||
name TEXT
|
name TEXT
|
||||||
);
|
);
|
||||||
CREATE TABLE studiosLinks(
|
CREATE TABLE studiosLinks(
|
||||||
@ -118,7 +118,7 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
CREATE TABLE people(
|
CREATE TABLE people(
|
||||||
id INTEGER PRIMARY KEY UNIQUE,
|
id INTEGER PRIMARY KEY UNIQUE,
|
||||||
uri TEXT UNIQUE,
|
slug TEXT UNIQUE,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
imgPrimary TEXT,
|
imgPrimary TEXT,
|
||||||
externalIDs TEXT
|
externalIDs TEXT
|
||||||
@ -134,7 +134,7 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
CREATE TABLE genres(
|
CREATE TABLE genres(
|
||||||
id INTEGER PRIMARY KEY UNIQUE,
|
id INTEGER PRIMARY KEY UNIQUE,
|
||||||
uri TEXT UNIQUE,
|
slug TEXT UNIQUE,
|
||||||
name TEXT
|
name TEXT
|
||||||
);
|
);
|
||||||
CREATE TABLE genresLinks(
|
CREATE TABLE genresLinks(
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Kyoo.InternalAPI
|
namespace Kyoo.InternalAPI
|
||||||
{
|
{
|
||||||
public interface IMetadataProvider
|
public interface IMetadataProvider
|
||||||
{
|
{
|
||||||
Show GetShowFromName(string showName);
|
Task<Show> GetShowFromID(string externalIDs);
|
||||||
|
|
||||||
|
Task<Show> GetShowFromName(string showName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,164 @@
|
|||||||
using Kyoo.Models;
|
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
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
Kyoo/InternalAPI/MetadataProvider/ProviderHelper.cs
Normal file
48
Kyoo/InternalAPI/MetadataProvider/ProviderHelper.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@
|
|||||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
|
<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.AspNetCore.SpaServices.Extensions" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" 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" />
|
<PackageReference Include="System.Data.SQLite" Version="1.0.111" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Show
|
public class Show
|
||||||
{
|
{
|
||||||
public readonly long id;
|
public readonly long id = -1;
|
||||||
|
|
||||||
public string Uri;
|
public string Slug;
|
||||||
public string Title;
|
public string Title;
|
||||||
public List<string> Aliases;
|
public List<string> Aliases;
|
||||||
public string Overview;
|
public string Overview;
|
||||||
@ -24,11 +24,12 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public string ExternalIDs;
|
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;
|
this.id = id;
|
||||||
Uri = uri;
|
Slug = slug;
|
||||||
Title = title;
|
Title = title;
|
||||||
Aliases = aliases;
|
Aliases = aliases;
|
||||||
Overview = overview;
|
Overview = overview;
|
||||||
@ -46,7 +47,7 @@ namespace Kyoo.Models
|
|||||||
public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
public static Show FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||||
{
|
{
|
||||||
return new Show((long)reader["id"],
|
return new Show((long)reader["id"],
|
||||||
reader["uri"] as string,
|
reader["slug"] as string,
|
||||||
reader["title"] as string,
|
reader["title"] as string,
|
||||||
(reader["aliases"] as string)?.Split('|').ToList() ?? null,
|
(reader["aliases"] as string)?.Split('|').ToList() ?? null,
|
||||||
reader["overview"] as string,
|
reader["overview"] as string,
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
"databasePath": "C://Projects/database.db",
|
"databasePath": "C://Projects/database.db",
|
||||||
"libraryPaths": [
|
"libraryPaths": [
|
||||||
"D:\\Videos"
|
"D:\\Videos"
|
||||||
]
|
],
|
||||||
|
"regex": ".*\\\\(?<ShowTitle>.+?) S(?<Season>\\d+)E(?<Episode>\\d+)"
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user