mirror of https://github.com/Jackett/Jackett
Feature/omdb api integration (#1509)
* Line endings... * Refactoring how MetaIndexers handle fallbacks Originally this modification was part of a much larger refactoring, however for the sake of reviewability I split it into smaller chunks. Sadly it is still quite large. I wanted to split it even more, however after a certain point there was really no value in creating smaller chunks. The biggest part of this modification would be still huge. So all in all, there're 3 aspects of this modification - It modifies BaseIndexer so that it now implements IIndexer (will be very useful later on) - Resolving most of the warnings currently in Jackett (the only ones remaining are related to Autofac, however if I could I would just burn Autofac altogether rather than fix the warnings. Will open discussion on this.) - Biggest part: refactoring how MetaIndexers handle fallbacks and how they provide the final result set MetaIndexers now accept any kind of fallback and filtering mechanism that implements the necessary interface, so that in the future IMDB fallback and filtering won't be the only one. I know there are not a lot of unit tests around Jackett at the moment, however this renders the class much more unittestable as well. * Integrate OMDB API for the fallback option * Safeguarding when no API key is specified * Autofac started complaining... I don't understand... * How did that not make the previous commit?
This commit is contained in:
parent
345602926e
commit
75e7ce81c2
File diff suppressed because it is too large
Load Diff
|
@ -140,6 +140,10 @@
|
|||
<span class="input-header">Enhanced logging: </span>
|
||||
<input id="jackett-logging" class="form-control input-right" type="checkbox" />
|
||||
</div>
|
||||
<div class="input-area">
|
||||
<span class="input-header">OMDB API key: </span>
|
||||
<input id="jackett-omdbkey" class="form-control input-right" type="text" value="" placeholder="">
|
||||
</div>
|
||||
<hr />
|
||||
<div id="footer">
|
||||
Jackett Version <span id="app-version"></span>
|
||||
|
|
|
@ -332,7 +332,7 @@ namespace Jackett.Controllers
|
|||
cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
|
||||
cfg["logging"] = Startup.TracingEnabled;
|
||||
cfg["basepathoverride"] = serverService.Config.BasePathOverride;
|
||||
|
||||
cfg["omdbkey"] = serverService.Config.OmdbApiKey;
|
||||
|
||||
jsonReply["config"] = cfg;
|
||||
jsonReply["app_version"] = config.GetVersion();
|
||||
|
@ -364,10 +364,12 @@ namespace Jackett.Controllers
|
|||
bool preRelease = (bool)postData["prerelease"];
|
||||
bool logging = (bool)postData["logging"];
|
||||
string basePathOverride = (string)postData["basepathoverride"];
|
||||
string omdbApiKey = (string)postData["omdbkey"];
|
||||
|
||||
Engine.Server.Config.UpdateDisabled = updateDisabled;
|
||||
Engine.Server.Config.UpdatePrerelease = preRelease;
|
||||
Engine.Server.Config.BasePathOverride = basePathOverride;
|
||||
Engine.Server.Config.OmdbApiKey = omdbApiKey;
|
||||
Startup.BasePath = Engine.Server.BasePath();
|
||||
Engine.Server.SaveConfig();
|
||||
|
||||
|
|
|
@ -18,76 +18,67 @@ namespace Jackett
|
|||
{
|
||||
public class JackettModule : Autofac.Module
|
||||
{
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
protected override void Load (ContainerBuilder builder)
|
||||
{
|
||||
// Just register everything!
|
||||
var thisAssembly = typeof(JackettModule).Assembly;
|
||||
builder.RegisterAssemblyTypes(thisAssembly)
|
||||
.Except<IIndexer>()
|
||||
.Except<IImdbResolver>()
|
||||
.Except<IFallbackStrategyProvider>()
|
||||
.Except<ImdbFallbackStrategyProvider>()
|
||||
.Except<IFallbackStrategy>()
|
||||
.Except<ImdbFallbackStrategy>()
|
||||
.Except<IResultFilterProvider>()
|
||||
.Except<ImdbTitleResultFilterProvider>()
|
||||
.Except<IResultFilter>()
|
||||
.Except<ImdbTitleResultFilterProvider>()
|
||||
.Except<BaseMetaIndexer>()
|
||||
.Except<AggregateIndexer>()
|
||||
.AsImplementedInterfaces().SingleInstance();
|
||||
builder.RegisterApiControllers(thisAssembly).InstancePerRequest();
|
||||
builder.RegisterType<HttpWebClient>();
|
||||
var thisAssembly = typeof (JackettModule).Assembly;
|
||||
builder.RegisterAssemblyTypes (thisAssembly)
|
||||
.Except<IIndexer> ()
|
||||
.Except<IImdbResolver> ()
|
||||
.Except<OmdbResolver> ()
|
||||
.Except<IFallbackStrategyProvider> ()
|
||||
.Except<ImdbFallbackStrategyProvider> ()
|
||||
.Except<IFallbackStrategy> ()
|
||||
.Except<ImdbFallbackStrategy> ()
|
||||
.Except<IResultFilterProvider> ()
|
||||
.Except<ImdbTitleResultFilterProvider> ()
|
||||
.Except<IResultFilter> ()
|
||||
.Except<ImdbTitleResultFilterProvider> ()
|
||||
.Except<BaseMetaIndexer> ()
|
||||
.Except<AggregateIndexer> ()
|
||||
.AsImplementedInterfaces ().SingleInstance ();
|
||||
builder.RegisterApiControllers (thisAssembly).InstancePerRequest ();
|
||||
builder.RegisterType<HttpWebClient> ();
|
||||
|
||||
// Register the best web client for the platform or the override
|
||||
switch (Startup.ClientOverride)
|
||||
{
|
||||
case "httpclient":
|
||||
builder.RegisterType<HttpWebClient>().As<IWebClient>();
|
||||
break;
|
||||
case "httpclient2":
|
||||
builder.RegisterType<HttpWebClient2>().As<IWebClient>();
|
||||
break;
|
||||
case "safecurl":
|
||||
builder.RegisterType<UnixSafeCurlWebClient>().As<IWebClient>();
|
||||
break;
|
||||
case "libcurl":
|
||||
builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
|
||||
break;
|
||||
case "automatic":
|
||||
default:
|
||||
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
var usehttpclient = false;
|
||||
try {
|
||||
Type monotype = Type.GetType("Mono.Runtime");
|
||||
if (monotype != null)
|
||||
{
|
||||
MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
if (displayName != null)
|
||||
{
|
||||
var monoVersion = displayName.Invoke(null, null).ToString();
|
||||
var monoVersionO = new Version(monoVersion.Split(' ')[0]);
|
||||
if ((monoVersionO.Major >= 4 && monoVersionO.Minor >= 8) || monoVersionO.Major >= 5)
|
||||
{
|
||||
// check if btls is supported
|
||||
var monoSecurity = Assembly.Load("Mono.Security");
|
||||
Type monoTlsProviderFactory = monoSecurity.GetType("Mono.Security.Interface.MonoTlsProviderFactory");
|
||||
if (monoTlsProviderFactory != null)
|
||||
{
|
||||
MethodInfo isProviderSupported = monoTlsProviderFactory.GetMethod("IsProviderSupported");
|
||||
if(isProviderSupported != null)
|
||||
{
|
||||
var btlsSupported = (bool)isProviderSupported.Invoke(null, new string[] { "btls" });
|
||||
if (btlsSupported)
|
||||
{
|
||||
// initialize btls
|
||||
MethodInfo initialize = monoTlsProviderFactory.GetMethod("Initialize", new[] { typeof(string) });
|
||||
if (initialize != null)
|
||||
{
|
||||
initialize.Invoke(null, new string[] { "btls" });
|
||||
usehttpclient = true;
|
||||
}
|
||||
switch (Startup.ClientOverride) {
|
||||
case "httpclient":
|
||||
builder.RegisterType<HttpWebClient> ().As<IWebClient> ();
|
||||
break;
|
||||
case "httpclient2":
|
||||
builder.RegisterType<HttpWebClient2> ().As<IWebClient> ();
|
||||
break;
|
||||
case "safecurl":
|
||||
builder.RegisterType<UnixSafeCurlWebClient> ().As<IWebClient> ();
|
||||
break;
|
||||
case "libcurl":
|
||||
builder.RegisterType<UnixLibCurlWebClient> ().As<IWebClient> ();
|
||||
break;
|
||||
case "automatic":
|
||||
default:
|
||||
if (System.Environment.OSVersion.Platform == PlatformID.Unix) {
|
||||
var usehttpclient = false;
|
||||
try {
|
||||
Type monotype = Type.GetType ("Mono.Runtime");
|
||||
if (monotype != null) {
|
||||
MethodInfo displayName = monotype.GetMethod ("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
if (displayName != null) {
|
||||
var monoVersion = displayName.Invoke (null, null).ToString ();
|
||||
var monoVersionO = new Version (monoVersion.Split (' ') [0]);
|
||||
if ((monoVersionO.Major >= 4 && monoVersionO.Minor >= 8) || monoVersionO.Major >= 5) {
|
||||
// check if btls is supported
|
||||
var monoSecurity = Assembly.Load ("Mono.Security");
|
||||
Type monoTlsProviderFactory = monoSecurity.GetType ("Mono.Security.Interface.MonoTlsProviderFactory");
|
||||
if (monoTlsProviderFactory != null) {
|
||||
MethodInfo isProviderSupported = monoTlsProviderFactory.GetMethod ("IsProviderSupported");
|
||||
if (isProviderSupported != null) {
|
||||
var btlsSupported = (bool)isProviderSupported.Invoke (null, new string [] { "btls" });
|
||||
if (btlsSupported) {
|
||||
// initialize btls
|
||||
MethodInfo initialize = monoTlsProviderFactory.GetMethod ("Initialize", new [] { typeof (string) });
|
||||
if (initialize != null) {
|
||||
initialize.Invoke (null, new string [] { "btls" });
|
||||
usehttpclient = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,56 +86,45 @@ namespace Jackett
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.Out.WriteLine("Error while deciding which HttpWebClient to use: " + e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Console.Out.WriteLine ("Error while deciding which HttpWebClient to use: " + e);
|
||||
}
|
||||
|
||||
if (usehttpclient)
|
||||
builder.RegisterType<HttpWebClient>().As<IWebClient>();
|
||||
else
|
||||
builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
|
||||
}
|
||||
if (usehttpclient)
|
||||
builder.RegisterType<HttpWebClient> ().As<IWebClient> ();
|
||||
else
|
||||
{
|
||||
builder.RegisterType<HttpWebClient>().As<IWebClient>();
|
||||
}
|
||||
break;
|
||||
builder.RegisterType<UnixLibCurlWebClient> ().As<IWebClient> ();
|
||||
} else {
|
||||
builder.RegisterType<HttpWebClient> ().As<IWebClient> ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Register indexers
|
||||
var indexerTypes = thisAssembly.GetTypes().Where(p => typeof (IIndexer).IsAssignableFrom (p) && !p.IsInterface && !p.IsInNamespace("Jackett.Indexers.Meta"));
|
||||
foreach (var indexer in indexerTypes)
|
||||
{
|
||||
builder.RegisterType(indexer).Named<IIndexer>(BaseIndexer.GetIndexerID(indexer));
|
||||
var indexerTypes = thisAssembly.GetTypes ().Where (p => typeof (IIndexer).IsAssignableFrom (p) && !p.IsInterface && !p.IsInNamespace ("Jackett.Indexers.Meta"));
|
||||
foreach (var indexer in indexerTypes) {
|
||||
builder.RegisterType (indexer).Named<IIndexer> (BaseIndexer.GetIndexerID (indexer));
|
||||
}
|
||||
|
||||
Mapper.CreateMap<WebClientByteResult, WebClientStringResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((be, str) =>
|
||||
{
|
||||
str.Content = Encoding.UTF8.GetString(be.Content);
|
||||
Mapper.CreateMap<WebClientByteResult, WebClientStringResult> ().ForMember (x => x.Content, opt => opt.Ignore ()).AfterMap ((be, str) => {
|
||||
str.Content = Encoding.UTF8.GetString (be.Content);
|
||||
});
|
||||
|
||||
Mapper.CreateMap<WebClientStringResult, WebClientByteResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((str, be) =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(str.Content))
|
||||
{
|
||||
be.Content = Encoding.UTF8.GetBytes(str.Content);
|
||||
Mapper.CreateMap<WebClientStringResult, WebClientByteResult> ().ForMember (x => x.Content, opt => opt.Ignore ()).AfterMap ((str, be) => {
|
||||
if (!string.IsNullOrEmpty (str.Content)) {
|
||||
be.Content = Encoding.UTF8.GetBytes (str.Content);
|
||||
}
|
||||
});
|
||||
|
||||
Mapper.CreateMap<WebClientStringResult, WebClientStringResult>();
|
||||
Mapper.CreateMap<WebClientByteResult, WebClientByteResult>();
|
||||
Mapper.CreateMap<ReleaseInfo, ReleaseInfo>();
|
||||
Mapper.CreateMap<WebClientStringResult, WebClientStringResult> ();
|
||||
Mapper.CreateMap<WebClientByteResult, WebClientByteResult> ();
|
||||
Mapper.CreateMap<ReleaseInfo, ReleaseInfo> ();
|
||||
|
||||
Mapper.CreateMap<ReleaseInfo, TrackerCacheResult>().AfterMap((r, t) =>
|
||||
{
|
||||
if (r.Category != null)
|
||||
{
|
||||
var CategoryDesc = string.Join(", ", r.Category.Select(x => TorznabCatType.GetCatDesc(x)).Where(x => !string.IsNullOrEmpty(x)));
|
||||
Mapper.CreateMap<ReleaseInfo, TrackerCacheResult> ().AfterMap ((r, t) => {
|
||||
if (r.Category != null) {
|
||||
var CategoryDesc = string.Join (", ", r.Category.Select (x => TorznabCatType.GetCatDesc (x)).Where (x => !string.IsNullOrEmpty (x)));
|
||||
t.CategoryDesc = CategoryDesc;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
t.CategoryDesc = "";
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace Jackett.Models.Config
|
|||
public bool UpdateDisabled { get; set; }
|
||||
public bool UpdatePrerelease { get; set; }
|
||||
public string BasePathOverride { get; set; }
|
||||
public string OmdbApiKey { get; set; }
|
||||
|
||||
public string[] GetListenAddresses(bool? external = null)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,8 @@ using System.Threading.Tasks;
|
|||
using System.Web;
|
||||
using CsQuery;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Jackett.Services
|
||||
{
|
||||
|
@ -12,36 +14,34 @@ namespace Jackett.Services
|
|||
Task<IEnumerable<string>> GetAllTitles(string imdbId);
|
||||
}
|
||||
|
||||
public class ImdbResolver : IImdbResolver
|
||||
public struct Movie
|
||||
{
|
||||
public ImdbResolver(IWebClient webClient)
|
||||
public string Title;
|
||||
}
|
||||
|
||||
public class OmdbResolver : IImdbResolver
|
||||
{
|
||||
public OmdbResolver(IWebClient webClient, string omdbApiKey)
|
||||
{
|
||||
WebClient = webClient;
|
||||
apiKey = omdbApiKey;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<string>> GetAllTitles(string imdbId)
|
||||
{
|
||||
if (apiKey == null)
|
||||
return new string[] { };
|
||||
|
||||
if (!imdbId.StartsWith("tt", StringComparison.Ordinal))
|
||||
imdbId = "tt" + imdbId;
|
||||
var request = new WebRequest("http://www.imdb.com/title/" + imdbId + "/releaseinfo");
|
||||
var request = new WebRequest("http://omdbapi.com/?apikey=" + apiKey + "&i=" + imdbId);
|
||||
var result = await WebClient.GetString(request);
|
||||
var movie = JsonConvert.DeserializeObject<Movie>(result.Content);
|
||||
|
||||
CQ dom = result.Content;
|
||||
|
||||
var mainTitle = dom["h3[itemprop=name]"].Find("a")[0].InnerHTML.Replace("\"", "");
|
||||
|
||||
var akas = dom["table#akas"].Find("tbody").Find("tr");
|
||||
var titleList = new List<string>();
|
||||
titleList.Add(mainTitle);
|
||||
foreach (var row in akas) {
|
||||
string title = row.FirstElementChild.InnerHTML;
|
||||
if (title == "(original title)" || title == "")
|
||||
titleList.Add(HttpUtility.HtmlDecode(row.FirstElementChild.NextElementSibling.InnerHTML));
|
||||
}
|
||||
|
||||
return titleList;
|
||||
return new string[] { movie.Title };
|
||||
}
|
||||
|
||||
private IWebClient WebClient;
|
||||
private string apiKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Jackett.Services
|
|||
|
||||
public void InitAggregateIndexer()
|
||||
{
|
||||
var imdbResolver = new ImdbResolver(container.Resolve<IWebClient>());
|
||||
var imdbResolver = new OmdbResolver(container.Resolve<IWebClient>(), container.Resolve<IServerService>().Config.OmdbApiKey);
|
||||
var imdbFallbackStrategyProvider = new ImdbFallbackStrategyProvider(imdbResolver);
|
||||
var imdbTitleResultFilterProvider = new ImdbTitleResultFilterProvider(imdbResolver);
|
||||
|
||||
|
|
Loading…
Reference in New Issue