using System; using System.Drawing; using System.Net; using System.Windows.Forms; using CarManagerV3.Forms; namespace CarManagerV3 { /// /// The ImageManager class is responsible for managing car images, including fetching and storing them locally. /// internal class ImageManager { private static string _imagePath = Properties.Settings.Default.DataLocation + "\\images"; private static NetworkCredential myNetCred = null; private static bool disableImageFetch = false; /// /// Initializes the image folder by creating it if it does not exist. /// public static void InitializeImageFolder() { _imagePath = Properties.Settings.Default.DataLocation + "\\images"; string path = _imagePath; if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } // Do not catch here. If we cannot create our images folder, the program wont work. } /// /// Generates the image path for a given car based on its attributes. /// /// The car. /// The image path for this Car. public static string GetImagePath(Car car) { _imagePath = Properties.Settings.Default.DataLocation + "\\images"; string basePath = $"{_imagePath}/"; string fileName = $"{car.Make}_{car.Model}_{car.Year}_{car.Color}.png"; return basePath + fileName; } /// /// Gets the image for a given car, fetching it if necessary. /// /// The car. /// The object for the car. public static Image GetImage(Car car) { InitializeImageFolder(); FetchImage(car); string path = GetImagePath(car); // does image exist? try { if (System.IO.File.Exists(path)) { return Image.FromFile(path); } } catch (Exception ex) { Console.Error.WriteLine($"Error loading image: {ex.Message}"); } try { return Image.FromFile($"{_imagePath}/no_image_available.png"); } catch (Exception ex) { Console.Error.WriteLine($"Error loading fallback image: {ex.Message}"); return null; } } /// /// Fetches an image for a Car from https://cdn.imagin.studio/getimage if it does not already exist locally and saves it to images/Make_Model_Year_Color.webp. /// If the image cannot be fetched, a placeholder image is used instead. /// Uses example customer id "hrjavascript-mastery", because they wouldn't give me one. Stole this from a tutorial page. :) /// /// The car. public static void FetchImage(Car car) { // Fetch the image from https://cdn.imagin.studio/getimage and save it to images/Make_Model_Year.webp // use params like this: ?customer=hrjavascript-mastery&zoomType=fullscreen&make={make}&modelFamily={model}&modelYear={year}&angle=front&paintDescription={color}&fileType=png // check if the image already exists string path = GetImagePath(car); if (System.IO.File.Exists(path)) { return; } if (disableImageFetch) return; string url = $"https://cdn.imagin.studio/getimage?customer=hrjavascript-mastery&zoomType=fullscreen&make={car.Make}&modelFamily={car.Model}&modelYear={car.Year}&angle=front&paintDescription={car.Color}&fileType=png"; //add Referer header to avoid 403 error using (var client = new System.Net.WebClient()) { client.Headers.Add("Referer", "http://localhost"); try { client.Credentials = myNetCred; client.Proxy.Credentials = myNetCred; //DEBUG:: if (myNetCred == null) throw new WebException(); client.DownloadFile(url, path); } catch (WebException ex) { // is status code 407? //if (ex.Response is HttpWebResponse response && response.StatusCode == HttpStatusCode.ProxyAuthenticationRequired) //{ // Console.Error.WriteLine("Proxy authentication required. Prompting for credentials."); //} if (myNetCred != null) { DialogResult disableImgDialogRetry = MessageBox.Show("Something went wrong when fetching images. Are you credentials correct? Do you want to disable Image fetching for this session or rety with different credentials?", "Invalid Credentials", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if(disableImgDialogRetry == DialogResult.Cancel) { disableImageFetch = true; return; } } NetCredentials netCredForm = new NetCredentials(); DialogResult dialogRes = netCredForm.ShowDialog(); netCredForm.BringToFront(); netCredForm.Focus(); if (dialogRes == DialogResult.OK) { NetworkCredential netcred = netCredForm.GetCredentails(); myNetCred = netcred; FetchImage(car); return; } else { DialogResult disableImgDialog = MessageBox.Show("Do you want to disable image fetching for this session?", "Disable Image fetching?", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if(disableImgDialog == DialogResult.Yes) { disableImageFetch = true; } else { FetchImage(car); return; } } } catch (Exception ex) { Console.Error.WriteLine(ex.Message); // if error, use fallback image no_image_available.png //System.IO.File.Copy($"{_imagePath}/no_image_available.png", path); } } } } }