diff --git a/Configuration.cs b/Configuration.cs new file mode 100644 index 0000000..6bbf878 --- /dev/null +++ b/Configuration.cs @@ -0,0 +1,10 @@ +namespace podcast_agent +{ + using System.Xml.Linq; + public class Configuration + { + public string OutputDir { get; set; } = "../"; + public string UserAgent { get; set; } = "secret-chinese-spy-drone/0.1"; + public List PodcastUrls { get; set; } + } +} \ No newline at end of file diff --git a/Program.cs b/Program.cs index 10bd3d0..fe127cc 100644 --- a/Program.cs +++ b/Program.cs @@ -1,34 +1,73 @@ namespace podcast_agent { using System.Xml.Linq; + using Newtonsoft.Json; class Program { static async Task Main(string[] args) { + var conf = Configure(); var downloader = new HttpClient(); - downloader.DefaultRequestHeaders.UserAgent.ParseAdd("wget-is-not-a-crime"); - - var xml = XDocument.Load("https://feeds.npr.org/500005/podcast.xml"); + downloader.DefaultRequestHeaders.UserAgent.ParseAdd(conf.UserAgent); XNamespace ns = "http://www.itunes.com/dtds/podcast-1.0.dtd"; - foreach (var item in xml.Descendants("item")) + foreach (var feed in conf.PodcastUrls) { - var title = item.Element("title")?.Value; - var ext=".wav"; - var attachmentLink = item.Element("enclosure")?.Attribute("url")?.Value.ToString(); - var probableFilename = attachmentLink.Substring(0, attachmentLink.IndexOf('?')); - if(probableFilename.LastIndexOf('.') > 0) + try { - ext = probableFilename.Substring(probableFilename.LastIndexOf('.')); - } + var xml = XDocument.Load(feed); - Console.WriteLine($"{title}, {attachmentLink}"); - var downloadPath = title + ext; - var dlResult = (await downloader.GetAsync(attachmentLink)); - File.WriteAllBytes(downloadPath, await dlResult.Content.ReadAsByteArrayAsync()); + foreach (var item in xml.Descendants("item")) + { + var title = item.Element("title")?.Value; + var ext = ".wav"; + var attachmentLink = item.Element("enclosure")?.Attribute("url")?.Value.ToString(); + var probableFilename = attachmentLink.Substring(0, attachmentLink.IndexOf('?')); + if (probableFilename.LastIndexOf('.') > 0) + { + ext = probableFilename.Substring(probableFilename.LastIndexOf('.')); + } + + Console.WriteLine($"{title}, {attachmentLink}"); + var downloadPath = Path.Combine(conf.OutputDir, title + ext); + var dlResult = (await downloader.GetAsync(attachmentLink)); + File.WriteAllBytes(downloadPath, await dlResult.Content.ReadAsByteArrayAsync()); + } + } + catch (Exception e) + { + Console.Error.WriteLine($"failed attempting to dl {feed} -"); + Console.Error.WriteLine(e); + } + } + } + static Configuration Configure(string configurationPath = "appsettings.json") + { + if (!File.Exists(configurationPath)) + { + Console.Error.WriteLine($"could not find configuration at {configurationPath}! copying sample to that spot."); + File.Copy("sample-appsettings.json", configurationPath); //and you know what, if that explodes at the OS level, the OS should give you an error + return null; + } + var fileContents = File.ReadAllText(configurationPath); + if (string.IsNullOrWhiteSpace(fileContents)) + { + Console.Error.WriteLine($"configuration file at {configurationPath} was empty! overwriting with sample settings."); + File.Copy("sample-appsettings.json", configurationPath, true); + return null; } + var conf = JsonConvert.DeserializeObject(fileContents); + + if (conf == null) + { + Console.Error.WriteLine($"configuration file at {configurationPath} was empty! overwriting with sample settings."); + File.Copy("sample-appsettings.json", configurationPath, true); + return null; + } + + return conf; } } }