using PowerArgs; using Newtonsoft.Json.Linq; using System.Net; namespace SBT_Downloader { internal class Program { static void Main(string[] args) { Console.WriteLine("Welcome to the Sound Booth Theater Personal Archiving Tool!"); try { var parsed = Args.Parse(args); Console.WriteLine("Downloading book now..."); (List mp3Urls, List chapters) = ParseHar(parsed.Har); DownloadMp3s(mp3Urls, chapters, parsed); } catch (ArgException ex) { Console.WriteLine(ex.Message); Console.WriteLine(ArgUsage.GenerateUsageFromTemplate()); } } static (List mp3Urls, List chapters) ParseHar(string har) { try { string harContents = LoadHar(har); JObject harObject = JObject.Parse(harContents); List requestObjects = ParseRequests(harObject); List mp3Urls = ParseUrls(requestObjects); List chapters = ParseChapters(mp3Urls); return (mp3Urls, chapters); } catch (Exception ex) { Console.WriteLine(ex.Message); Environment.Exit(0); return (new List(), new List()); } } private static List ParseRequests(JObject harObject) { List requests = harObject["log"]["entries"] .Where(x => x.SelectToken("_resourceType").ToString() == "media") .Select(y => y.SelectToken("request")) .DistinctBy(z => z.SelectToken("url")).ToList(); return requests; } private static List ParseChapters(List mp3Urls) { List chapters = new(); foreach (string url in mp3Urls) { Uri uri = new(url); string fixedUri = uri.AbsoluteUri.Replace(uri.Query, string.Empty); List urlTokens = fixedUri.Split("/").ToList(); //string series = urlTokens[5]; //string title = urlTokens[6]; //string episode = urlTokens[7]; var chapterTokens = urlTokens.Last().Split("_").ToList(); chapterTokens.RemoveRange(0,5); string chapterLastToken = chapterTokens.Last().Split(".").First(); chapterTokens[^1] = chapterLastToken; chapters.Add(string.Join(" ", chapterTokens)); } return chapters; } static List ParseUrls(List requestList) { List urls = requestList.Select(x => x.SelectToken("url").ToString()).ToList(); Console.WriteLine(urls.Count + " total requests"); return urls; } private static void DownloadMp3s(List mp3Urls, List chapters, MyArgs arguments) { int index = 0; foreach (string url in mp3Urls) { string chapterName = chapters[index]; index++; string fileName = $"{index} {chapterName}.mp3"; using var client = new WebClient(); Console.WriteLine("Downloading file #" + index); client.DownloadFile(url, fileName); TagFile(chapterName, index, chapters.Count, arguments); } } private static void TagFile(string chapterName, int index, int chapterCount, MyArgs arguments) { var file = TagLib.File.Create($"{index} {chapterName}.mp3"); file.Tag.Album = arguments.Title.IsNullOrEmpty() ? string.Empty : arguments.Title; List artistsList = new List(); if (!arguments.Author.IsNullOrEmpty()) artistsList.Add(arguments.Author); if (!arguments.Narrator.IsNullOrEmpty()) artistsList.Add(arguments.Narrator); file.Tag.AlbumArtists = artistsList.ToArray(); file.Tag.Title = chapterName; file.Tag.Track = (uint)index; file.Tag.TrackCount = (uint)chapterCount; file.Save(); } static string LoadHar(string harFileName) { string harContents; try { using StreamReader streamReader = new(harFileName); harContents = streamReader.ReadToEnd(); return harContents; } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); Environment.Exit(0); return string.Empty; } } } }