public void UpdateServersFromFile(string customFilePath, string customHeaders, char separator, bool skipHeaders, bool overwrite) { if (!File.Exists(customFilePath)) { throw new FileNotFoundException(string.Format(i18n.dug.ER_File_Not_Found, customFilePath)); } if (string.IsNullOrEmpty(customHeaders)) { UpdateServersFromFileDefaultHeaders(customFilePath, overwrite); return; } var tokenizedLines = File .ReadLines(customFilePath, Encoding.UTF8) .Skip(skipHeaders ? 1 : 0) .Select((line, index) => new TokenizedRow(index, line.Split(separator, StringSplitOptions.None))); //Specifically DO NOT remove empty entries var customMapper = new CustomDnsServerMapping(customHeaders); var parsedServers = tokenizedLines.Select(line => customMapper.Map(line)).Where(res => res.IsValid).Select(res => res.Result); int serversAdded = LoadServers(parsedServers.ToList(), overwrite); Console.WriteLine(i18n.dug.Output_Added_X_Servers_From_X, serversAdded, customFilePath); PersistServers(); }
private async Task ExecuteRun(RunOptions opts) { // 0. Validate Arguments (Happening in Options.cs in the set methods) // 1. Determine the servers to be used // - For now just get the top opts.ServerCount most "reliable" servers per continent. Eventually I'll provide cli options to refine this. List <DnsServer> serversToUse = new List <DnsServer>(); if (!string.IsNullOrEmpty(opts.CustomServerFile)) { if (!File.Exists(opts.CustomServerFile)) { Console.WriteLine(i18n.dug.ER_Specified_File_Not_Found, opts.CustomServerFile); System.Environment.Exit(1); } if (!string.IsNullOrEmpty(opts.DataColumns)) { var mapper = new CustomDnsServerMapping(opts.DataColumns); using (var streamReader = File.OpenText(opts.CustomServerFile)) { serversToUse = _dnsServerService.ParseServersFromStream(streamReader.BaseStream, mapper, opts.DataHeadersPresent, opts.DataSeparator ?? ','); } } else { using (var streamReader = File.OpenText(opts.CustomServerFile)) { var serversFromFile = _dnsServerService.ParseServersFromStream(streamReader.BaseStream, DnsServerParser.DefaultLocalParser, true, ','); if (serversFromFile == null || serversFromFile.Count == 0) { throw new Exception(string.Format(i18n.dug.ER_Unable_To_Parse_File, opts.CustomServerFile)); } serversToUse.AddRange(serversFromFile); } } } if (opts.ParsedServers?.Count() > 0) { //TODO: Should we 'decorate' these servers (turn them into DnsServers) before using them? //If yes: We should do things like determine if they have DNSSEC, etc. Maybe this could be a static parse method off of DnsServer or something? // Also when we're rendering the results we shouldnt assume to have anything except the IPAddress... Maybe when you do this the rendering should be way simpler? serversToUse.AddRange(opts.ParsedServers); } if (opts.MultipleServerSources || serversToUse.Count == 0) { var serversByReliability = _dnsServerService.ServersByContinent.SelectMany(group => group.OrderByDescending(server => server.Reliability).Take(opts.ServerCount)); serversToUse.AddRange(serversByReliability .Where(server => opts.ParsedContinents.Contains(server.ContinentCode, new ContinentCodeComparer()))); } DugConsole.VerboseWriteLine(string.Format(i18n.dug.Output_Servers_To_Use, serversToUse.Count)); // 2. Run the queries with any options (any records, specific records, etc) if (opts.OutputFormat == OutputFormats.TABLES) { _percentageAnimator.Start("", serversToUse.Count * opts.ParsedQueryTypes.Count(), Math.Max(Console.WindowWidth - 40, 0)); } var queryResults = await Query(opts, serversToUse); _percentageAnimator.StopIfRunning(); // 3. Draw beautiful results in fancy table if (opts.OutputFormat == OutputFormats.TABLES) { if (!opts.Watch.HasValue) { _consoleTableService.DrawResults(queryResults, opts); } } else { _consoleTemplateService.DrawResults(queryResults, opts); } // 4. Update server reliability depending on results if (string.IsNullOrEmpty(opts.CustomServerFile)) { _dnsServerService.UpdateServerReliabilityFromResults(queryResults, false); } if (opts.Watch.HasValue) { Console.Clear(); await _consoleTableService.DrawLiveTable(queryResults, opts, async() => await Query(opts, serversToUse)); } }