// application entry point static void Main(string[] ArgsRaw) { try { // task ProgramTask ProgramTask = new ProgramTask(ArgsRaw); Run(ProgramTask); } catch (NoArgumentsException) { PrintUsage(); } catch (ArgumentsException ex) { Console.Error.WriteLine(ex.Message); } catch (Exception ex) { // display the entire exception stack Exception NextEx = ex; while (NextEx != null) { Console.Error.WriteLine(NextEx.GetType().FullName + ": " + NextEx.Message); Console.Error.WriteLine(NextEx.StackTrace); NextEx = NextEx.InnerException; if (NextEx != null) { Console.Error.WriteLine(); } } } }
// main application algorithm static void Run(ProgramTask ProgramTask) { // get the dates List <DateTime> Dates = new List <DateTime> (); if (ProgramTask.dtDay != null) { Dates.Add(ProgramTask.dtDay.Value); } else // file is already assured to be specified { string[] DateLines; try { DateLines = File.ReadAllLines(ProgramTask.DatesFilePath); } catch (FileNotFoundException ex) { throw new AppException($"Failed to read {ProgramTask.DatesFilePath}. File must be missing.", ex); } catch (UnauthorizedAccessException ex) { throw new AppException($"Failed to read {ProgramTask.DatesFilePath}. Must be privileges issue.", ex); } foreach (string DateLine in DateLines) { DateTime?Date = Utils.ReadDateTime.Try(DateLine); if (Date != null) { Dates.Add(Date.Value); } } } if (Dates.Count == 0) { throw new AppException("No dates specified."); } // loading WebClient Client = new WebClient(); int PhotosTotalCount = 0; foreach (DateTime Date in Dates) { // day summary string SummaryUrl = $"https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?earth_date={Date.ToString("yyyy-MM-dd")}&api_key={ProgramTask.ApiKey}"; string SummaryJson; try { SummaryJson = Client.DownloadString(SummaryUrl); } catch (Exception ex) { if (ex is WebException wex && wex.Message == "The remote server returned an error: (403) Forbidden.") { throw new NasaApiForbiddenException(ex); } throw new NasaApiException("Failed to download day photos information.", ex); } // deserialize NasaApi.DaySummary DaySummary; try { DaySummary = JsonConvert.DeserializeObject <NasaApi.DaySummary> (SummaryJson); } catch (Exception ex) { throw new NasaApiException("Error while deserializing day photos information. Must be ill-formatted JSON.", ex); } // verify length if (ProgramTask.PhotoIndex != null && DaySummary.Photos.Length < ProgramTask.PhotoIndex.Value) { throw new AppException($"Photo index ({ProgramTask.PhotoIndex}) exceeds the photos count ({DaySummary.Photos.Length})."); } int MinIndex = 0; int MaxIndexExcl = DaySummary.Photos.Length; // narrow down the range for single photo if (ProgramTask.PhotoIndex != null) { MinIndex = ProgramTask.PhotoIndex.Value - 1; // PhotoIndex is 1-based MaxIndexExcl = MinIndex + 1; } // go through all the photos for (int i = MinIndex; i < MaxIndexExcl; ++i) { NasaApi.Photo Photo = DaySummary.Photos[i]; string DirPath = Path.Combine(ProgramTask.OutputDir, Photo.EarthDate.ToString("yyyy-MM-dd")); try { Directory.CreateDirectory(DirPath); } catch (Exception ex) { throw new AppException($"Failed to create directory at {DirPath}" + (ex is UnauthorizedAccessException ? ". Must be privileges issue." : ""), ex); } // target filename string ImageFileName = $"{Photo.Id}-{Photo.Rover.Name}-{Photo.Camera.Name}.jpg"; string FilePath = Path.Combine(DirPath, ImageFileName); try { // actual downloading Client.DownloadFile(Photo.ImageUrl, FilePath); ++PhotosTotalCount; } catch (Exception ex) { if (ex is WebException wex) { if (wex.Message == "The remote server returned an error: (403) Forbidden.") { throw new NasaApiImageException(Photo.ImageUrl, ex); } if (wex.InnerException.GetType() == typeof(UnauthorizedAccessException)) { throw new AppException($"Failed to save photo at {FilePath}. Must be privileges issue.", ex); } } if (ex is DirectoryNotFoundException) { throw new AppException($"Failed to save photo at {FilePath}", ex); } throw new AppException($"Failed to download photo at {Photo.ImageUrl}. Can be connection fault.", ex); } // open in browser if (ProgramTask.AutoOpen) { Process pOpenImage = new Process(); pOpenImage.StartInfo.UseShellExecute = true; pOpenImage.StartInfo.FileName = Photo.ImageUrl; pOpenImage.Start(); } } } if (PhotosTotalCount == 0) { Console.Error.WriteLine($"No photos are present for the specified date(s)."); } }