Пример #1
0
        public IActionResult GetDocument([FromQuery] int contractId, [FromQuery] string docName)
        {
            using (var context = new DealerContractContext())
            {
                var contract = context.Contracts.FirstOrDefault(c => c.ContractId == contractId);
                if (contract == null)
                {
                    return(BadRequest());
                }

                var document = context.Documents.FirstOrDefault(c => string.Compare(docName, c.Name, true) == 0);
                if (document == null)
                {
                    return(BadRequest());
                }
                var docFullPath = EnviromentHelper.GetDocumentFullPath(document.Filename);

                if (!(new FileInfo(docFullPath)).Exists)
                {
                    return(NoContent());
                }
                string docContent = System.IO.File.ReadAllText(docFullPath);
                docContent = FillContractDocument(docContent, contract);
                //return Content(docContent);
                return(Content(docContent, "text/html", Encoding.UTF8));
            }
            //return View();
        }
Пример #2
0
        public static IServiceCollection AddDomain(this IServiceCollection services, IConfiguration configuration, ILogger?logger = null)
        {
            services
            .AddTransient <EpisodeSearch>()
            .AddTransient <ShowSearch>()
            .AddTransient <ShowStorage>();

            // Add Config Options.
            var storagePaths = Array.Empty <string>();

            if (EnviromentHelper.TryGetGlobalEnviromentVariable("MEDIAINFO_STORAGE", out string envValue))
            {
                storagePaths = JsonSerializer.Deserialize <string[]>(envValue);
            }
            else
            {
                storagePaths = configuration.GetSection("Storage").Get <string[]>();
            }

            if (storagePaths.Any(path => !Directory.Exists(path)))
            {
                throw new ApplicationException($"STORAGEPATH DOES NOT EXIST: {string.Join(", ", storagePaths.Where(path => !Directory.Exists(path)))}");
            }

            logger?.LogInformation($"[SETTINGS]: Storage - {string.Join(", ", storagePaths)}");

            return(services
                   .AddSingleton(new MediaInfoConfiguration {
                StoragePaths = storagePaths
            }));
        }
        public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration, ILogger?logger = null)
        {
            services
            // Helpers.
            .AddSingleton <ITvDbClient, TvDbClient>()
            .AddSingleton <IMemoryCache, MemoryCache>()
            .AddSingleton <Compiler>(x => new SqlServerCompiler())
            // Repos
            .AddTransient <IShowRepository, ShowRepository>()
            .AddTransient <IEpisodeRepository, EpisodeRepository>()
            // API
            .AddTransient <IApiSearch, TvDbSearch>()
            .AddTransient <IEpisodeApiSearch, TvDbSearch>()
            .AddTransient <IShowApiSearch, TvDbSearch>();

            // Add Config. Prioritize ENV over APPSettings.
            // TVDB Options
            var tvDbOptions = configuration.GetSection("TvDb").Get <TvDbOptions>();

            tvDbOptions.ApiKey = EnviromentHelper.FindGlobalEnviromentVariable("TVDB_APIKEY")
                                 ?? (!string.IsNullOrWhiteSpace(tvDbOptions.ApiKey) ? tvDbOptions.ApiKey : throw new ApplicationException("TVDB_APIKEY NOT SPECIFIED. USE AN ENVIROMENT VAR."));
            // MediaInfo Options
            var mediaInfoConnString = GetMediaInfoDbConnection(configuration);

            logger?.LogInformation($"[SETTINGS]: TVDB_APIKEY - {tvDbOptions.ApiKey}");
            logger?.LogInformation($"[SETTINGS]: MEDIAINFO_DB - {mediaInfoConnString}");

            return(services
                   .AddSingleton <IDbConnectionFactory>(_ => new SqlConnectionFactory(mediaInfoConnString))
                   .AddSingleton(tvDbOptions));
        }
Пример #4
0
        private static ConverterOptions BuildConverterOptions(IConfiguration config)
        {
            // Get.
            var options = config.GetSection("ConverterOptions").Get <ConverterOptions>();

            options.DownloadStore   = EnviromentHelper.GetSetting("CONVERTER_DOWNLOADSTORE", options.DownloadStore);
            options.ProcessingStore = EnviromentHelper.GetSetting("CONVERTER_PROCESSINGSTORE", options.ProcessingStore);
            options.QueueStore      = EnviromentHelper.GetSetting("CONVERTER_QUEUESTORE", options.QueueStore);
            options.ProcessedStore  = EnviromentHelper.GetSetting("CONVERTER_PROCESSEDSTORE", options.ProcessedStore);

            // Validate.
            if (!Directory.Exists(options.DownloadStore))
            {
                throw new ApplicationException($"Download Store does not exist: {options.DownloadStore}");
            }

            if (!Directory.Exists(options.ProcessingStore))
            {
                throw new ApplicationException($"Processing Store does not exist: {options.ProcessingStore}");
            }

            if (!Directory.Exists(options.QueueStore))
            {
                throw new ApplicationException($"Queue Store does not exist: {options.QueueStore}");
            }

            if (!Directory.Exists(options.ProcessedStore))
            {
                throw new ApplicationException($"Processed Store does not exist: {options.ProcessedStore}");
            }

            return(options);
        }
Пример #5
0
        private static BrokerOptions GetBrokerOptions(IConfiguration configuration, ILogger logger = null)
        {
            var output = configuration.GetSection("BrokerOptions").Get <BrokerOptions>();

            output.Address = EnviromentHelper.GetSetting("BROKER_ADDRESS", output.Address);
            logger?.LogInformation($"[SETTINGS]: BROKER_ADDRESS (Message Broker Address) - {output.Address}");

            output.UserName = EnviromentHelper.GetSetting("BROKER_USERNAME", output.UserName, allowEmpty: true);
            if (!string.IsNullOrEmpty(output.UserName))
            {
                logger?.LogInformation($"[SETTINGS]: BROKER_USERNAME - '{output.UserName}'");
            }

            output.Password = EnviromentHelper.GetSetting("BROKER_PASSWORD", output.Password, allowEmpty: true);
            if (!string.IsNullOrEmpty(output.Password))
            {
                logger?.LogInformation($"[SETTINGS]: BROKER_PASSWORD - '{output.Password}'");
            }

            if (!RabbitMqHelper.TryConnect(output.Address, output.UserName, output.Password, out Exception ex))
            {
                throw new ApplicationException($"Unable to connect to Broker: {output.Address}, username: {output.UserName}, password: {output.Password} ({ex.Message})");
            }

            return(output);
        }
Пример #6
0
        private static MediaStorageOptions BuildMediaStorageOptions(IConfiguration config)
        {
            // Get.
            var options = config.GetSection("MediaStorageOptions").Get <MediaStorageOptions>();

            options.Stores = EnviromentHelper.FindGlobalEnviromentJsonVariable <StoreArea[]>("STORAGE_STORES")
                             ?? options.Stores;
            options.ProcessStores = EnviromentHelper.FindGlobalEnviromentJsonVariable <StoreArea[]>("STORAGE_PROCESSSTORES")
                                    ?? options.ProcessStores;

            // Validate.
            if (options?.Stores?.Any() != true)
            {
                throw new ApplicationException("There are no storage option stores found.");
            }
            var missingStores = options.Stores.Where(dir => !Directory.Exists(dir.Path));

            if (missingStores.Any())
            {
                throw new ApplicationException($"Cannot find storage option stores: {string.Join(", ", missingStores)}");
            }

            if (options?.ProcessStores?.Any() != true)
            {
                throw new ApplicationException("There are no storage option -processing- stores found.");
            }
            missingStores = options.ProcessStores.Where(dir => !Directory.Exists(dir.Path));
            if (missingStores.Any())
            {
                throw new ApplicationException($"Cannot find storage option -processing- stores: {string.Join(", ", missingStores)}");
            }

            return(options);
        }
Пример #7
0
        public static IServiceCollection AddDefaultServices(this IServiceCollection services, IConfiguration config)
        {
            string dbConnString = EnviromentHelper.FindGlobalEnviromentVariable("STORAGE_DB")
                                  ?? (!string.IsNullOrWhiteSpace(config.GetConnectionString("StorageFactory"))
                        ? config.GetConnectionString("StorageFactory")
                        : throw new ApplicationException("STORAGE_DB NOT SPECIFIED. USE AN ENVIROMENT VAR."));

            return(services
                   // Services
                   .AddSingleton <EpisodeProcessor>()
                   .AddSingleton <IShowStore, ShowPhysicalStore>()
                   .AddSingleton <IEpisodeStore, EpisodePhysicalStore>()
                   .AddSingleton <StorageService>()
                   .AddSingleton <EpisodeProcessor>()
                   // Config
                   .AddLogging(configure => configure.AddConsole())
                   .AddSingleton(BuildMediaStorageOptions(config))
                   .AddSingleton(BuildBrokerOptions(config))
                   .AddSingleton(BuildMediaInfoClientOptions(config))
                   // Infrastructure
                   .AddSingleton <IMessageBroker, RabbitBroker>(provider => {
                var options = provider.GetRequiredService <BrokerOptions>();
                return new RabbitBroker(options.Address, options.UserName, options.Password, provider.GetRequiredService <ILogger <RabbitBroker> >());
            })
                   .AddSingleton <IMediaInfoClient, MediaInfoClient>()
                   .AddSingleton <IProcessedEpisodeRepository, ProcessedEpisodesRepository>()
                   .AddSingleton <IMemoryCache, MemoryCache>()
                   .AddSingleton <Compiler>(x => new SqlServerCompiler())
                   .AddSingleton <IDbConnectionFactory>(_ => new SqlConnectionFactory(dbConnString))
                   .AddSingleton <HttpClient>());
        }
Пример #8
0
        private static MediaInfoClientOptions BuildMediaInfoClientOptions(IConfiguration config)
        {
            // Get.
            var options = config.GetSection("MediaInfoOptions").Get <MediaInfoClientOptions>();

            options.Address = EnviromentHelper.GetSetting("STORAGE_MEDIAINFOADDRESS", options.Address);

            return(options);
        }
        private static string GetMediaInfoDbConnection(IConfiguration configuration, ILogger?logger = null)
        {
            var connection = EnviromentHelper.FindGlobalEnviromentVariable("MEDIAINFO_DB")
                             ?? (!string.IsNullOrWhiteSpace(configuration.GetConnectionString("MediaInfo")) ? configuration.GetConnectionString("MediaInfo") : throw new ApplicationException("MEDIAINFO_DB NOT SPECIFIED. USE AN ENVIROMENT VAR."));

            // Ensure we can connect..
            using (var db = new SqlConnectionFactory(connection).Create()) {
                int result = db.QueryFirst <int>("SELECT 1");
            }

            return(connection);
        }
Пример #10
0
        private static DiscordOptions GetDiscordOptions(IConfiguration configuration, ILogger logger = null)
        {
            var output = configuration.GetSection("DiscordOptions").Get <DiscordOptions>();

            output.Token = EnviromentHelper.GetSetting("DISCORD_TOKEN", output.Token);
            logger?.LogInformation($"[SETTINGS]: DISCORD_TOKEN (Auth Token) - {output.Token}");

            output.AlertChannelName = EnviromentHelper.GetSetting("DISCORD_ALERTCHANNELNAME", output.AlertChannelName);
            logger?.LogInformation($"[SETTINGS]: DISCORD_ALERTCHANNELNAME (Channel names to show alerts) - {output.AlertChannelName}");

            output.ViewerDomain = EnviromentHelper.GetSetting("DISCORD_VIEWERDOMAIN", output.ViewerDomain);
            logger?.LogInformation($"[SETTINGS]: DISCORD_VIEWERDOMAIN (Web Address to view media) - {output.ViewerDomain}");

            return(output);
        }
Пример #11
0
        private static BrokerOptions BuildBrokerOptions(IConfiguration config)
        {
            // Get.
            var options = config.GetSection("BrokerOptions").Get <BrokerOptions>();

            options.Address  = EnviromentHelper.GetSetting("BROKER_ADDRESS", options.Address);
            options.UserName = EnviromentHelper.GetSetting("BROKER_USERNAME", options.UserName, allowEmpty: true);
            options.Password = EnviromentHelper.GetSetting("BROKER_PASSWORD", options.Password, allowEmpty: true);

            // Validate.
            if (!RabbitMqHelper.TryConnect(options.Address, options.UserName, options.Password, out Exception ex))
            {
                throw new ApplicationException($"Could not connect to RabbitMq Server on the hostname: {options.Address}, username: {options.UserName}, password: {options.Password} ({ex.Message})");
            }

            return(options);
        }
        public IActionResult GetScan([FromQuery] int?contractId)
        {
            if (contractId == null)
            {
                return(BadRequest());
            }
            if ((contractId ?? -1) < 0)
            {
                return(BadRequest());                      //auto increment index cant be negative
            }
            int    id = contractId ?? -1;
            int    index;
            string dbFilename = string.Empty;

            using (var context = new DealerContractContext())
            {
                var contract = context.Contracts.FirstOrDefault(c => c.ContractId == id);
                if (contract == null)
                {
                    return(BadRequest());
                }
                index      = contract.ContractId;
                dbFilename = contract.ScannedContractUrl;
                if (string.IsNullOrEmpty(dbFilename))
                {
                    return(BadRequest("This contract has not uploaded scan yet."));
                }
            }
            string fullPath = EnviromentHelper.GetScanfileFullPath(dbFilename, index);

            if (!(new FileInfo(fullPath)).Exists)
            {
                return(NoContent());
            }

            //https://stackoverflow.com/questions/42460198/return-file-in-asp-net-core-web-api
            var stream = new FileStreamResult(new FileStream(fullPath, FileMode.Open, FileAccess.Read), "application/pdf")
            {
                FileDownloadName = $"contract_{id}.pdf"
            };
            //to return file use File()
            var response = File(stream.FileStream, "application/pdf");

            return(response);
        }
Пример #13
0
        private static MediaInfoClientOptions GetMediaInfoOptions(IConfiguration configuration, ILogger logger = null)
        {
            var output = configuration.GetSection("MediaInfoOptions").Get <MediaInfoClientOptions>();

            output.Address = EnviromentHelper.GetSetting("MEDIAINFO_ADDRESS", output.Address);

            // Ensure we can send a message!
            try {
                new MediaInfoClient(new HttpClient(), output)
                .GetEpisode(100);
            }
            catch (Exception ex) {
                logger?.LogCritical($"Error with setup request to MediaInfo: {output.Address}");
                throw ex;
            }

            logger?.LogInformation($"[SETTINGS]: MEDIAINFO_ADDRESS - {output.Address}");
            return(output);
        }
Пример #14
0
        private static HandbrakeOptions BuildHandbrakeOptions(IConfiguration config)
        {
            // Get.
            var options = config.GetSection("HandbrakeOptions").Get <HandbrakeOptions>();

            options.CmdPath      = EnviromentHelper.GetSetting("HANDBRAKE_CMDPATH", options.CmdPath);
            options.StandardArgs = EnviromentHelper.GetSetting("HANDBRAKE_STANDARDARGS", options.StandardArgs);
            options.SubtitleArgs = EnviromentHelper.GetSetting("HANDBRAKE_SUBTITLEARGS", options.SubtitleArgs);

            // Validate.
            if (!File.Exists(options.CmdPath))
            {
                throw new ApplicationException($"Path to handbrake CLI not found: {options.CmdPath}");
            }

            // Check Args point at a valid json configuration file (if they are pointing at one).
            int pathIndex = options.SubtitleArgs.IndexOf(".json");

            if (pathIndex > -1)
            {
                string path = StringHelper.GetWordAtIndex(options.SubtitleArgs, pathIndex);
                if (!string.IsNullOrWhiteSpace(path) && !File.Exists(path))
                {
                    throw new ApplicationException($"File used in SubtitleArgs cannot be found: {path} (Full Args: {options.SubtitleArgs}).");
                }
            }

            pathIndex = options.StandardArgs.IndexOf(".json");
            if (pathIndex > -1)
            {
                string path = StringHelper.GetWordAtIndex(options.StandardArgs, pathIndex);
                if (!string.IsNullOrWhiteSpace(path) && !File.Exists(path))
                {
                    throw new ApplicationException($"File used in StandardArgs cannot be found: {path} (Full Args: {options.StandardArgs}).");
                }
            }

            return(options);
        }
        private bool SaveScan(IFormFile file, int index)
        {
            //do save
            //if file exists?
            var path = Path.Combine(EnviromentHelper.RootPath, EnviromentHelper.ScanFolder);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var fileName = Path.Combine(path, EnviromentHelper.ScanFilePathMaker(file.FileName, index));

            if ((new FileInfo(fileName)).Exists)
            {
                return(false);
            }
            using (var stream = new FileStream(fileName, FileMode.Create))
            {
                file.CopyTo(stream);
            }
            return(true);
        }
        public IActionResult UploadScan([FromQuery] int contractId)
        {
            var files = Request.Form.Files;

            if (files.Count < 1 || files.Count > 1)
            {
                return(BadRequest("Invalid file count."));
            }
            var file = files.First();

            if (file.Length < (int)MinFileLength)
            {
                return(BadRequest("File is too small"));
            }
            if (string.Compare(file.ContentType, AcceptedUploadType, true) != 0)
            {
                return(BadRequest("Invalid file type."));
            }
            using (var context = new DealerContractContext())
            {
                var contract = context.Contracts.FirstOrDefault(c => c.ContractId == contractId);
                if (contract == null)
                {
                    return(BadRequest("Contract not found"));
                }
                if (!string.IsNullOrEmpty(contract.ScannedContractUrl))
                {
                    return(BadRequest("Contract has scan uploaded already"));
                }

                if (!SaveScan(file, contract.ContractId))
                {
                    throw new InvalidOperationException();
                }
                contract.ScannedContractUrl = EnviromentHelper.ScanFilePathMaker(file.FileName, contract.ContractId);
                context.SaveChanges();
            }
            return(Ok());
        }
        public override void OnException(ExceptionContext context)
        {
            var logger = LogManager.GetLogger(context.ActionDescriptor.DisplayName);

            EnviromentHelper.LogException(context.Exception, logger);
        }
Пример #18
0
        //Unhandle exception wont crash app
        //No point using async here...
        public void Execute(IJobExecutionContext context)
        {
            //logger.Info("Execute job....");
            try
            {
                var schedulerContext = context.Scheduler.Context;
                var conStr           = (string)schedulerContext.Get(EnviromentHelper.ConnectionStringKey);
                if (string.IsNullOrEmpty(conStr))
                {
                    throw new ArgumentException("Invalid connection string");
                }
                var url = (string)schedulerContext.Get(EnviromentHelper.ApiUrlKey);
                if (string.IsNullOrEmpty(url))
                {
                    throw new ArgumentException("Invalid API URL");
                }
                using (var dbContext = new CLToolContext(conStr))
                {
                    var newRequests = dbContext.Request
                                      .Where(w => w.Response.Count == 0);

                    //Debug.Print(newRequests.Count().ToString());
                    if (newRequests.Count() == 0)
                    {
                        //logger.Info("Nothing new...back to sleep Zzzz");
                        return;
                    }
                    logger.Info("New requests count: " + newRequests.Count().ToString());
                    newRequests = newRequests.Include(customer => customer.CustomerInfo)
                                  .Include(username => username.UsernameNavigation)
                                  .ThenInclude(division => division.DivisionNameNavigation);
                    //ToList to close read connection
                    foreach (var request in newRequests.ToList())
                    {
                        //Update rq send time
                        request.RequestSendTime = DateTime.Now;
                        ////Must have customer info at this point
                        var hdssRq = RequestWrapper.ToHDSSRequest(request, request.CustomerInfo.Single());
                        //Log raw rq
                        logger.Info("Request:");
                        logger.Info(JsonConvert.SerializeObject(hdssRq));
                        //var test = JsonConvert.SerializeObject(hdssRq);
                        //If network fail, rq wont get update with response & guid
                        var  result     = HDB.Program.PostToHDBank(url, hdssRq);
                        var  response   = RequestWrapper.DeserializeResponse(result);
                        bool skipVerify = false;
                        //00: success
                        //01: có tài khoản cũ rồi nhưng tên sai so với tên đã lưu tại hdb
                        //09: trả về tài khoản cũ
                        //03: tạo tài khoản thất bại, tham số input truyền qua không hợp lệ
                        //05: invalid sig
                        switch (response.ResponseCode)
                        {
                        case "00":
                            //Continue to check sig & save response
                            break;

                        case "09":
                            //Continue to check sig & save response
                            break;

                        case "01":
                            //Doesnt have sig in response => skip verify & store response to check later
                            skipVerify = true;
                            break;

                        case "03":
                            throw new InvalidOperationException($"Server response 03. Invalid format: {response.ResponseMessage}");

                        case "05":
                            throw new InvalidOperationException("Invalid signature 05. Check keys then restart app");

                        default:
                            throw new InvalidOperationException($"Unknown response code {response.ResponseCode}");
                        }

                        if (!skipVerify)
                        {
                            if (!HdbRSA.Verify(response.VerificationHash, response.Signature))
                            {
                                throw new UnauthorizedAccessException($"Verification failed for request: {request.RequestId}");
                            }
                            logger.Info("Verify OK!");
                        }
                        //Log raw response
                        logger.Info("Response:");
                        logger.Info(result);
                        //Update GUID, sig
                        request.Guid      = hdssRq.requestId;
                        request.Signature = hdssRq.signature;
                        //Add response to this request
                        request.Response.Add(response);
                        //try save each sucessful API calls
                        //MultipleActiveResultSets=true;
                        //To allow multiple operations in single connection
                        dbContext.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                EnviromentHelper.LogException(ex, logger);
                logger.Fatal("************** Unhandle exception in Scheduler => Stop scheduler **************");
                var jobEx = new JobExecutionException(ex);
                //Stop all trigger
                jobEx.UnscheduleAllTriggers      = true;
                EnviromentHelper.IsSchedulerDown = true;
                //Apply effect
                throw jobEx;
            }
        }
Пример #19
0
        public static IServiceCollection AddDependencies(this IServiceCollection services, IConfiguration configuration, ILogger logger)
        {
            services
            // Services
            .AddTransient <ITorrentClient, QBitService>()
            .AddTransient <DownloaderService>()
            .AddTransient <TorrentService>()
            .AddTransient <HorribleSubsFeed>()
            .AddTransient <IReadOnlyCollection <IFeed> >(builder => new[] { builder.GetRequiredService <HorribleSubsFeed>() })
            // Repos
            .AddTransient <HistoryRepository>()
            .AddSingleton <IMemoryCache, MemoryCache>()
            .AddSingleton <Compiler>(x => new SqlServerCompiler())
            .AddSingleton <HttpClient>()
            // Config
            .AddLogging(configure => configure.AddConsole());

            // Add Config Options.
            var torrentOptions = configuration.GetSection("TorrentServiceOptions").Get <TorrentServiceOptions>();

            torrentOptions.DownloadTorrentPath = EnviromentHelper.GetLoggedSetting(logger, "DOWNLOAD_PATH", torrentOptions.DownloadTorrentPath);

            if (!Directory.Exists(torrentOptions.DownloadTorrentPath))
            {
                throw new ApplicationException($"Download Directory does not exist: {torrentOptions.DownloadTorrentPath} (FULL PATH: {Path.GetFullPath(torrentOptions.DownloadTorrentPath)}");
            }

            // HorribleSubs options.
            var horribleOptions = configuration.GetSection("HorribleSubsOptions").Get <HorribleSubsOptions>();

            horribleOptions.Quality = EnviromentHelper.GetLoggedSetting(logger, "HORRIBLESUBS_QUALITY", horribleOptions.Quality);

            // QBitTorrent Options
            var qbitOptions = configuration.GetSection("QBitOptions").Get <QBitOptions>();

            qbitOptions.Address  = EnviromentHelper.GetLoggedSetting(logger, "QBITTORRENT_ADDRESS", qbitOptions.Address);
            qbitOptions.UserName = EnviromentHelper.GetLoggedSetting(logger, "QBITTORRENT_USERNAME", qbitOptions.UserName);
            qbitOptions.Password = EnviromentHelper.GetLoggedSetting(logger, "QBITTORRENT_PASSWORD", qbitOptions.Password);

            // Broker Options
            var brokerOptions = configuration.GetSection("BrokerOptions").Get <BrokerOptions>();

            brokerOptions.Address  = EnviromentHelper.GetLoggedSetting(logger, "BROKER_ADDRESS", brokerOptions.Address);
            brokerOptions.UserName = EnviromentHelper.GetLoggedSetting(logger, "BROKER_USERNAME", brokerOptions.UserName, allowEmpty: true);
            brokerOptions.Password = EnviromentHelper.GetLoggedSetting(logger, "BROKER_PASSWORD", brokerOptions.Password, allowEmpty: true);

            if (!RabbitMqHelper.TryConnect(brokerOptions.Address, brokerOptions.UserName, brokerOptions.Password, out Exception ex))
            {
                throw new ApplicationException($"Could not connect to RabbitMq Server on the hostname: {brokerOptions.Address} ({ex.Message})");
            }

            // DB String
            var downloaderConnString = EnviromentHelper.GetLoggedSetting(logger, "DOWNLOADFACTORY_DB", configuration.GetConnectionString("DownloaderFactory"));

            services
            .AddSingleton(torrentOptions)
            .AddSingleton(horribleOptions)
            .AddSingleton(qbitOptions)
            .AddSingleton(brokerOptions)
            .AddSingleton <IMessageBroker, RabbitBroker>(provider => {
                var options = provider.GetRequiredService <BrokerOptions>();
                return(new RabbitBroker(options.Address, options.UserName, options.Password, provider.GetRequiredService <ILogger <RabbitBroker> >()));
            })
            .AddSingleton <IDbConnectionFactory>(_ => new SqlConnectionFactory(downloaderConnString));

            return(services);
        }