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
3
.gitignore
vendored
3
.gitignore
vendored
@ -337,4 +337,5 @@ ASALocalRun/
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
healthchecksdb
|
||||
/Kyoo/TheTVDB-Credentials.json
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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.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>
|
||||
|
||||
|
@ -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,
|
||||
|
@ -2,5 +2,6 @@
|
||||
"databasePath": "C://Projects/database.db",
|
||||
"libraryPaths": [
|
||||
"D:\\Videos"
|
||||
]
|
||||
],
|
||||
"regex": ".*\\\\(?<ShowTitle>.+?) S(?<Season>\\d+)E(?<Episode>\\d+)"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user