mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
Feature/netcore preparation (#2072)
* Use platform detection that works on mono 4.6+ * Move to use package reference for restoring nuget packages. * DateTimeRoutines does not have Nuget packages that support .NET Standard (and therefore .NET Core). We will have to include them for now until we can get rid of this dependency. * Start spliting some interfaces into their own files - this will help by allowing us to split them out in the future into a seperate project so the actual implementations can stay within their respective architectures when required * Move out common libraries * Few more tidy up tasks to get things working with .NET Standard * Restructure the solution layout * Encoding work to reduce rework later on platforms without Windows codepages (or require compliance with RFC1345) * Move folder structure around to have more natural layout of the solutions * DI server configuration to get rid of "temporary" hack and dependency circle for serverservice * Make all encoding consistent to match the expected encoding casing for earlier versions of mono.
This commit is contained in:

committed by
flightlevel

parent
47a2ffa313
commit
571c52a0f2
237
src/Jackett.Common/Services/IndexerManagerService.cs
Normal file
237
src/Jackett.Common/Services/IndexerManagerService.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using Jackett.Indexers;
|
||||
using Jackett.Models;
|
||||
using Jackett.Utils;
|
||||
using Jackett.Utils.Clients;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jackett.Indexers.Meta;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using Jackett.Services.Interfaces;
|
||||
using Jackett.Models.Config;
|
||||
|
||||
namespace Jackett.Services
|
||||
{
|
||||
|
||||
public class IndexerManagerService : IIndexerManagerService
|
||||
{
|
||||
private ICacheService cacheService;
|
||||
private IIndexerConfigurationService configService;
|
||||
private IProtectionService protectionService;
|
||||
private WebClient webClient;
|
||||
private IProcessService processService;
|
||||
private IConfigurationService globalConfigService;
|
||||
private ServerConfig serverConfig;
|
||||
private Logger logger;
|
||||
|
||||
private Dictionary<string, IIndexer> indexers = new Dictionary<string, IIndexer>();
|
||||
private AggregateIndexer aggregateIndexer;
|
||||
|
||||
public IndexerManagerService(IIndexerConfigurationService config, IProtectionService protectionService, WebClient webClient, Logger l, ICacheService cache, IProcessService processService, IConfigurationService globalConfigService, ServerConfig serverConfig)
|
||||
{
|
||||
configService = config;
|
||||
this.protectionService = protectionService;
|
||||
this.webClient = webClient;
|
||||
this.processService = processService;
|
||||
this.globalConfigService = globalConfigService;
|
||||
this.serverConfig = serverConfig;
|
||||
logger = l;
|
||||
cacheService = cache;
|
||||
}
|
||||
|
||||
public void InitIndexers(IEnumerable<string> path)
|
||||
{
|
||||
InitIndexers();
|
||||
InitCardigannIndexers(path);
|
||||
InitAggregateIndexer();
|
||||
}
|
||||
|
||||
private void InitIndexers()
|
||||
{
|
||||
logger.Info("Using HTTP Client: " + webClient.GetType().Name);
|
||||
|
||||
var allTypes = GetType().Assembly.GetTypes();
|
||||
var allIndexerTypes = allTypes.Where(p => typeof(IIndexer).IsAssignableFrom(p));
|
||||
var allInstantiatableIndexerTypes = allIndexerTypes.Where(p => !p.IsInterface && !p.IsAbstract);
|
||||
var allNonMetaInstantiatableIndexerTypes = allInstantiatableIndexerTypes.Where(p => !typeof(BaseMetaIndexer).IsAssignableFrom(p));
|
||||
var indexerTypes = allNonMetaInstantiatableIndexerTypes.Where(p => p.Name != "CardigannIndexer");
|
||||
var ixs = indexerTypes.Select(type =>
|
||||
{
|
||||
var constructorArgumentTypes = new Type[] { typeof(IIndexerConfigurationService), typeof(WebClient), typeof(Logger), typeof(IProtectionService) };
|
||||
var constructor = type.GetConstructor(constructorArgumentTypes);
|
||||
if (constructor != null)
|
||||
{
|
||||
// create own webClient instance for each indexer (seperate cookies stores, etc.)
|
||||
var indexerWebClientInstance = (WebClient)Activator.CreateInstance(webClient.GetType(), processService, logger, globalConfigService, serverConfig);
|
||||
|
||||
var arguments = new object[] { configService, indexerWebClientInstance, logger, protectionService };
|
||||
var indexer = (IIndexer)constructor.Invoke(arguments);
|
||||
return indexer;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Cannot instantiate " + type.Name);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
foreach (var idx in ixs)
|
||||
{
|
||||
if (idx == null)
|
||||
continue;
|
||||
indexers.Add(idx.ID, idx);
|
||||
configService.Load(idx);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitCardigannIndexers(IEnumerable<string> path)
|
||||
{
|
||||
logger.Info("Loading Cardigann definitions from: " + string.Join(", ", path));
|
||||
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.WithNamingConvention(new CamelCaseNamingConvention())
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build();
|
||||
|
||||
try
|
||||
{
|
||||
var directoryInfos = path.Select(p => new DirectoryInfo(p));
|
||||
var existingDirectories = directoryInfos.Where(d => d.Exists);
|
||||
var files = existingDirectories.SelectMany(d => d.GetFiles("*.yml"));
|
||||
var definitions = files.Select(file =>
|
||||
{
|
||||
logger.Info("Loading Cardigann definition " + file.FullName);
|
||||
|
||||
try {
|
||||
string DefinitionString = File.ReadAllText(file.FullName);
|
||||
var definition = deserializer.Deserialize<IndexerDefinition>(DefinitionString);
|
||||
return definition;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Error while parsing Cardigann definition " + file.FullName + ": " + ex.Message);
|
||||
return null;
|
||||
}
|
||||
}).Where(definition => definition != null);
|
||||
|
||||
List<IIndexer> cardigannIndexers = definitions.Select(definition =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// create own webClient instance for each indexer (seperate cookies stores, etc.)
|
||||
var indexerWebClientInstance = (WebClient)Activator.CreateInstance(webClient.GetType(), processService, logger, globalConfigService, serverConfig);
|
||||
|
||||
IIndexer indexer = new CardigannIndexer(configService, indexerWebClientInstance, logger, protectionService, definition);
|
||||
configService.Load(indexer);
|
||||
return indexer;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Error while creating Cardigann instance from Definition: " + ex.Message);
|
||||
return null;
|
||||
}
|
||||
}).Where(cardigannIndexer => cardigannIndexer != null).ToList(); // Explicit conversion to list to avoid repeated resource loading
|
||||
|
||||
foreach (var indexer in cardigannIndexers)
|
||||
{
|
||||
if (indexers.ContainsKey(indexer.ID))
|
||||
{
|
||||
logger.Debug(string.Format("Ignoring definition ID={0}: Indexer already exists", indexer.ID));
|
||||
continue;
|
||||
}
|
||||
|
||||
indexers.Add(indexer.ID, indexer);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Error while loading Cardigann definitions: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitAggregateIndexer()
|
||||
{
|
||||
var omdbApiKey = serverConfig.OmdbApiKey;
|
||||
IFallbackStrategyProvider fallbackStrategyProvider = null;
|
||||
IResultFilterProvider resultFilterProvider = null;
|
||||
if (!omdbApiKey.IsNullOrEmptyOrWhitespace())
|
||||
{
|
||||
var imdbResolver = new OmdbResolver(webClient, omdbApiKey.ToNonNull());
|
||||
fallbackStrategyProvider = new ImdbFallbackStrategyProvider(imdbResolver);
|
||||
resultFilterProvider = new ImdbTitleResultFilterProvider(imdbResolver);
|
||||
}
|
||||
else
|
||||
{
|
||||
fallbackStrategyProvider = new NoFallbackStrategyProvider();
|
||||
resultFilterProvider = new NoResultFilterProvider();
|
||||
}
|
||||
|
||||
logger.Info("Adding aggregate indexer");
|
||||
aggregateIndexer = new AggregateIndexer(fallbackStrategyProvider, resultFilterProvider, configService, webClient, logger, protectionService);
|
||||
aggregateIndexer.Indexers = indexers.Values;
|
||||
}
|
||||
|
||||
public IIndexer GetIndexer(string name)
|
||||
{
|
||||
if (indexers.ContainsKey(name))
|
||||
{
|
||||
return indexers[name];
|
||||
}
|
||||
else if (name == "all")
|
||||
{
|
||||
return aggregateIndexer;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Request for unknown indexer: " + name);
|
||||
throw new Exception("Unknown indexer: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public IWebIndexer GetWebIndexer(string name)
|
||||
{
|
||||
if (indexers.ContainsKey(name))
|
||||
{
|
||||
return indexers[name] as IWebIndexer;
|
||||
}
|
||||
else if (name == "all")
|
||||
{
|
||||
return aggregateIndexer as IWebIndexer;
|
||||
}
|
||||
|
||||
logger.Error("Request for unknown indexer: " + name);
|
||||
throw new Exception("Unknown indexer: " + name);
|
||||
}
|
||||
|
||||
public IEnumerable<IIndexer> GetAllIndexers()
|
||||
{
|
||||
return indexers.Values.OrderBy(_ => _.DisplayName);
|
||||
}
|
||||
|
||||
public async Task TestIndexer(string name)
|
||||
{
|
||||
var indexer = GetIndexer(name);
|
||||
var browseQuery = new TorznabQuery();
|
||||
browseQuery.QueryType = "search";
|
||||
browseQuery.SearchTerm = "";
|
||||
browseQuery.IsTest = true;
|
||||
var result = await indexer.ResultsForQuery(browseQuery);
|
||||
logger.Info(string.Format("Found {0} releases from {1}", result.Releases.Count(), indexer.DisplayName));
|
||||
if (result.Releases.Count() == 0)
|
||||
throw new Exception("Found no results while trying to browse this tracker");
|
||||
cacheService.CacheRssResults(indexer, result.Releases);
|
||||
}
|
||||
|
||||
public void DeleteIndexer(string name)
|
||||
{
|
||||
var indexer = GetIndexer(name);
|
||||
configService.Delete(indexer);
|
||||
indexer.Unconfigure();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user