From 4c29039afd411c452d65d02f2c9b4d9eb2f176f8 Mon Sep 17 00:00:00 2001 From: Dalton Soto Date: Mon, 31 Mar 2025 10:53:17 -0400 Subject: [PATCH 1/2] finished project --- DrinkInfoPractice/DrinkInfoPractice.sln | 22 +++ .../DrinkInfoPractice.csproj | 14 ++ .../Interfaces/ICocktailService.cs | 16 +++ .../DrinkInfoPractice/Models/ApiResponse.cs | 15 ++ .../DrinkInfoPractice/Models/DrinkCategory.cs | 15 ++ .../DrinkInfoPractice/Models/DrinkDetail.cs | 42 ++++++ .../DrinkInfoPractice/Models/DrinkSummary.cs | 21 +++ .../DrinkInfoPractice/Program.cs | 29 ++++ .../Services/CocktailService.cs | 135 ++++++++++++++++++ .../Services/TableVisualization.cs | 53 +++++++ .../DrinkInfoPractice/Services/UserInput.cs | 79 ++++++++++ 11 files changed, 441 insertions(+) create mode 100644 DrinkInfoPractice/DrinkInfoPractice.sln create mode 100644 DrinkInfoPractice/DrinkInfoPractice/DrinkInfoPractice.csproj create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Program.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs create mode 100644 DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs diff --git a/DrinkInfoPractice/DrinkInfoPractice.sln b/DrinkInfoPractice/DrinkInfoPractice.sln new file mode 100644 index 00000000..2b262649 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35707.178 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrinkInfoPractice", "DrinkInfoPractice\DrinkInfoPractice.csproj", "{8FF8B80C-BF62-4C83-9773-1C8728D60E19}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FF8B80C-BF62-4C83-9773-1C8728D60E19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8FF8B80C-BF62-4C83-9773-1C8728D60E19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8FF8B80C-BF62-4C83-9773-1C8728D60E19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8FF8B80C-BF62-4C83-9773-1C8728D60E19}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DrinkInfoPractice/DrinkInfoPractice/DrinkInfoPractice.csproj b/DrinkInfoPractice/DrinkInfoPractice/DrinkInfoPractice.csproj new file mode 100644 index 00000000..e2f26fa9 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/DrinkInfoPractice.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + diff --git a/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs b/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs new file mode 100644 index 00000000..f35778f8 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DrinkInfoPractice.Models; + +namespace DrinkInfoPractice.Interfaces +{ + internal interface ICocktailService + { + Task> GetCategoriesAsync(); + Task> GetDrinksByCategoryAsync(string category); + Task GetDrinkByIdAsync(string id); + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs new file mode 100644 index 00000000..aa8d3013 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace DrinkInfoPractice.Models +{ + internal class ApiResponse + { + [JsonPropertyName("drinks")] + public List Drinks { get; set; } + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs new file mode 100644 index 00000000..7e47236c --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace DrinkInfoPractice.Models +{ + internal class DrinkCategory + { + [JsonPropertyName("strCategory")] + public string StrCategory { get; set; } + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs new file mode 100644 index 00000000..dddcf313 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace DrinkInfoPractice.Models +{ + internal class DrinkDetail + { + [JsonPropertyName("idDrink")] + public string IdDrink { get; set; } + + [JsonPropertyName("strDrink")] + public string StrDrink { get; set; } + + [JsonPropertyName("strCategory")] + public string StrCategory { get; set; } + + [JsonPropertyName("strGlass")] + public string StrGlass { get; set; } + + [JsonPropertyName("strInstructions")] + public string StrInstructions { get; set; } + + private Dictionary _ingredients = new(); + + public IReadOnlyDictionary Ingredients => _ingredients; + + public void AddIngredient(int index, string ingredient, string measure) + { + if(!string.IsNullOrWhiteSpace(ingredient)) + { + _ingredients[index] = (ingredient, measure); + } + } + + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs new file mode 100644 index 00000000..f18b8fa6 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace DrinkInfoPractice.Models +{ + internal class DrinkSummary + { + [JsonPropertyName("idDrink")] + public string IdDrink { get; set; } + + [JsonPropertyName("strDrink")] + public string StrDrink { get; set; } + + [JsonPropertyName("strDrinkThumb")] + public string StrDrinkThumb { get; set; } + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Program.cs b/DrinkInfoPractice/DrinkInfoPractice/Program.cs new file mode 100644 index 00000000..39253aae --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Program.cs @@ -0,0 +1,29 @@ +using DrinkInfoPractice.Services; +UserInput userInput = new UserInput(); +await userInput.Start(); + +//var drinks = await cocktailService.GetDrinksByCategoryAsync("Beer"); + +//foreach (var drink in drinks) +//{ +// Console.WriteLine($"Drink Id: {drink.IdDrink}\n" + +// $"Drink: {drink.StrDrink}\n\n"); + +//} + +//Console.ReadLine(); + +//var drink1 = await cocktailService.GetDrinkByIdAsync("14378"); + +//Console.WriteLine($"Drink ID: {drink1.IdDrink}\n" + +// $"Drink: {drink1.StrDrink}\n" + +// $"Category: {drink1.StrCategory}\n" + +// $"Glass: {drink1.StrGlass}\n" + +// $"Instructions: {drink1.StrInstructions}\n\n"); + +//Console.WriteLine($"Ingredients:"); + +//foreach (var ingredient in drink1.Ingredients) +//{ +// Console.WriteLine($"-{ingredient.Value.Ingredients}: {ingredient.Value.Measure}"); +//} \ No newline at end of file diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs new file mode 100644 index 00000000..ab15ef7c --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Text.Json; +using DrinkInfoPractice.Interfaces; +using DrinkInfoPractice.Models; +using System.Text.Json.Serialization; + + +namespace DrinkInfoPractice.Services +{ + internal class CocktailService : ICocktailService + { + // filed for stroing HttpClient + private readonly HttpClient _httpClient; + + // API's base url + private const string BaseUrl = "http://www.thecocktaildb.com/api/json/v1/1/"; + + public CocktailService() + { + _httpClient = new HttpClient(); + + // setting the base address + _httpClient.BaseAddress = new Uri(BaseUrl); + } + + public async Task> GetCategoriesAsync() + { + try + { + // making the API call + var response = await _httpClient.GetAsync("list.php?c=list"); + + + // check to see if call was successful + response.EnsureSuccessStatusCode(); + + // read the response content + var content = await response.Content.ReadAsStringAsync(); + + + // convert the JSON to our C# objects + // takes the json and creates DrinkCategory object + var result = JsonSerializer.Deserialize>(content); + + + //return list of categories + // if result or Drinks is null, return empty list + return result?.Drinks ?? new List(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting categories: {ex.Message}"); + throw; + } + } + + public async Task> GetDrinksByCategoryAsync(string category) + { + try + { + // API call + var response = await _httpClient.GetAsync($"filter.php?c={category}"); + + response.EnsureSuccessStatusCode(); + + var content = await response.Content.ReadAsStringAsync(); + + var result = JsonSerializer.Deserialize>(content); + + return result?.Drinks ?? new List(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting drink summary: {ex.Message}"); + throw; + } + } + + public async Task GetDrinkByIdAsync(string id) + { + try + { + // API call + var response = await _httpClient.GetAsync($"lookup.php?i={id}"); + + response.EnsureSuccessStatusCode(); + + var content = await response.Content.ReadAsStringAsync(); + + var result = JsonSerializer.Deserialize>(content); + + var drink = result?.Drinks?.FirstOrDefault(); + + if (drink != null) + { + // Then process ingredients from the JSON directly + using (JsonDocument document = JsonDocument.Parse(content)) + { + var drinkElement = document.RootElement.GetProperty("drinks")[0]; + + // Process ingredients + for (int i = 1; i <= 15; i++) + { + if (drinkElement.TryGetProperty($"strIngredient{i}", out JsonElement ingredientElement) && + ingredientElement.ValueKind != JsonValueKind.Null) + { + var ingredient = ingredientElement.GetString(); + var measure = "As needed"; + + if (drinkElement.TryGetProperty($"strMeasure{i}", out JsonElement measureElement) && + measureElement.ValueKind != JsonValueKind.Null) + { + measure = measureElement.GetString(); + } + + drink.AddIngredient(i, ingredient, measure); + } + } + } + } + + return drink ?? new DrinkDetail(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting drink details: {ex.Message}"); + throw; + } + } + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs new file mode 100644 index 00000000..79c2b55c --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DrinkInfoPractice.Models; +using Spectre.Console; + +namespace DrinkInfoPractice.Services +{ + internal class TableVisualization + { + internal static void ShowTable(DrinkDetail drinkDetail) + { + List ingredientList = new List(); + foreach (var ingredient in drinkDetail.Ingredients) + { + ingredientList.Add($"- {ingredient.Value.Ingredients}: {ingredient.Value.Measure}"); + } + + string? ingredients = string.Join("\n", ingredientList); + + Console.WriteLine("\n"); + + Table table = new Table(); + + table.AddColumn("Drink ID"); + table.AddColumn("Drink"); + table.AddColumn("Category"); + table.AddColumn("Glass"); + table.AddColumn("Instructions"); + table.AddColumn("Ingredients"); + + table.AddRow( + drinkDetail.IdDrink, + drinkDetail.StrDrink, + drinkDetail.StrCategory, + drinkDetail.StrGlass, + drinkDetail.StrInstructions, + ingredients + ); + + table.Border(TableBorder.Square); + table.BorderColor(Color.Blue); + + AnsiConsole.Write(table); + + Console.WriteLine("Press Enter"); + Console.ReadLine(); + + } + } +} diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs new file mode 100644 index 00000000..dd8d1873 --- /dev/null +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DrinkInfoPractice.Models; +using Spectre.Console; + +namespace DrinkInfoPractice.Services +{ + internal class UserInput + { + CocktailService cocktailService = new CocktailService(); + + internal async Task Start() + { + bool continueRun = true; + while (continueRun) + { + Console.Clear(); + + string category = await CategoryMenu(); + + string id = await DrinksMenu(category); + + TableVisualization.ShowTable(await cocktailService.GetDrinkByIdAsync(id)); + + continueRun = ContinueRun(); + } + } + + internal bool ContinueRun() + { + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Would you like to find another drink?") + .AddChoices(new[] + { + "Yes", + "No" + })); + return choice == "Yes"; + } + + private async Task DrinksMenu(string category) + { + var drinks = await cocktailService.GetDrinksByCategoryAsync(category); + + Dictionary drinkMapping = drinks.ToDictionary(d => d.StrDrink, d => d.IdDrink); + + var drinkNames = drinkMapping.Keys.ToList(); + + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Select a drink") + .AddChoices(drinkNames)); + + string id = drinkMapping[choice].ToString(); + return id; + } + + internal async Task CategoryMenu() + { + var categories = await cocktailService.GetCategoriesAsync(); + + var categoryNames = categories.Select(c => c.StrCategory).ToList(); + categoryNames.Add("Exit"); + + var category = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Selection the category of drink.") + .AddChoices(categoryNames)); + + if (category == "Exit") Environment.Exit(0); + + return category; + } + } +} From 48b0331b0ffae9189f95c26dd9bc41d3423a1541 Mon Sep 17 00:00:00 2001 From: "Soto, Dalton" Date: Wed, 24 Sep 2025 14:37:10 -0400 Subject: [PATCH 2/2] code clean up --- .../Interfaces/ICocktailService.cs | 20 +- .../DrinkInfoPractice/Models/ApiResponse.cs | 18 +- .../DrinkInfoPractice/Models/DrinkCategory.cs | 18 +- .../DrinkInfoPractice/Models/DrinkDetail.cs | 52 +++-- .../DrinkInfoPractice/Models/DrinkSummary.cs | 26 +-- .../DrinkInfoPractice/Program.cs | 28 +-- .../Services/CocktailService.cs | 179 +++++++++--------- .../Services/TableVisualization.cs | 84 ++++---- .../DrinkInfoPractice/Services/UserInput.cs | 109 +++++------ 9 files changed, 228 insertions(+), 306 deletions(-) diff --git a/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs b/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs index f35778f8..2ce72f79 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Interfaces/ICocktailService.cs @@ -1,16 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DrinkInfoPractice.Models; +using DrinkInfoPractice.Models; -namespace DrinkInfoPractice.Interfaces +namespace DrinkInfoPractice.Interfaces; + +internal interface ICocktailService { - internal interface ICocktailService - { - Task> GetCategoriesAsync(); - Task> GetDrinksByCategoryAsync(string category); - Task GetDrinkByIdAsync(string id); - } + Task> GetCategoriesAsync(); + Task> GetDrinksByCategoryAsync(string category); + Task GetDrinkByIdAsync(string id); } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs index aa8d3013..45af2c39 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/ApiResponse.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Text.Json.Serialization; -namespace DrinkInfoPractice.Models +namespace DrinkInfoPractice.Models; + +internal class ApiResponse { - internal class ApiResponse - { - [JsonPropertyName("drinks")] - public List Drinks { get; set; } - } + [JsonPropertyName("drinks")] + public List Drinks { get; set; } } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs index 7e47236c..56549875 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkCategory.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Text.Json.Serialization; -namespace DrinkInfoPractice.Models +namespace DrinkInfoPractice.Models; + +internal class DrinkCategory { - internal class DrinkCategory - { - [JsonPropertyName("strCategory")] - public string StrCategory { get; set; } - } + [JsonPropertyName("strCategory")] + public string StrCategory { get; set; } } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs index dddcf313..c7226f10 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkDetail.cs @@ -1,42 +1,34 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; - -namespace DrinkInfoPractice.Models +using System.Text.Json.Serialization; + +namespace DrinkInfoPractice.Models; + +internal class DrinkDetail { - internal class DrinkDetail - { - [JsonPropertyName("idDrink")] - public string IdDrink { get; set; } + [JsonPropertyName("idDrink")] + public string IdDrink { get; set; } - [JsonPropertyName("strDrink")] - public string StrDrink { get; set; } + [JsonPropertyName("strDrink")] + public string StrDrink { get; set; } - [JsonPropertyName("strCategory")] - public string StrCategory { get; set; } + [JsonPropertyName("strCategory")] + public string StrCategory { get; set; } - [JsonPropertyName("strGlass")] - public string StrGlass { get; set; } + [JsonPropertyName("strGlass")] + public string StrGlass { get; set; } - [JsonPropertyName("strInstructions")] - public string StrInstructions { get; set; } + [JsonPropertyName("strInstructions")] + public string StrInstructions { get; set; } - private Dictionary _ingredients = new(); + private Dictionary _ingredients = new(); - public IReadOnlyDictionary Ingredients => _ingredients; + public IReadOnlyDictionary Ingredients => _ingredients; - public void AddIngredient(int index, string ingredient, string measure) + public void AddIngredient(int index, string ingredient, string measure) + { + if (!string.IsNullOrWhiteSpace(ingredient)) { - if(!string.IsNullOrWhiteSpace(ingredient)) - { - _ingredients[index] = (ingredient, measure); - } + _ingredients[index] = (ingredient, measure); } - } + } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs index f18b8fa6..11c7504a 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Models/DrinkSummary.cs @@ -1,21 +1,15 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Text.Json.Serialization; -namespace DrinkInfoPractice.Models +namespace DrinkInfoPractice.Models; + +internal class DrinkSummary { - internal class DrinkSummary - { - [JsonPropertyName("idDrink")] - public string IdDrink { get; set; } + [JsonPropertyName("idDrink")] + public string IdDrink { get; set; } - [JsonPropertyName("strDrink")] - public string StrDrink { get; set; } + [JsonPropertyName("strDrink")] + public string StrDrink { get; set; } - [JsonPropertyName("strDrinkThumb")] - public string StrDrinkThumb { get; set; } - } + [JsonPropertyName("strDrinkThumb")] + public string StrDrinkThumb { get; set; } } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Program.cs b/DrinkInfoPractice/DrinkInfoPractice/Program.cs index 39253aae..79f9f570 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Program.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Program.cs @@ -1,29 +1,3 @@ using DrinkInfoPractice.Services; UserInput userInput = new UserInput(); -await userInput.Start(); - -//var drinks = await cocktailService.GetDrinksByCategoryAsync("Beer"); - -//foreach (var drink in drinks) -//{ -// Console.WriteLine($"Drink Id: {drink.IdDrink}\n" + -// $"Drink: {drink.StrDrink}\n\n"); - -//} - -//Console.ReadLine(); - -//var drink1 = await cocktailService.GetDrinkByIdAsync("14378"); - -//Console.WriteLine($"Drink ID: {drink1.IdDrink}\n" + -// $"Drink: {drink1.StrDrink}\n" + -// $"Category: {drink1.StrCategory}\n" + -// $"Glass: {drink1.StrGlass}\n" + -// $"Instructions: {drink1.StrInstructions}\n\n"); - -//Console.WriteLine($"Ingredients:"); - -//foreach (var ingredient in drink1.Ingredients) -//{ -// Console.WriteLine($"-{ingredient.Value.Ingredients}: {ingredient.Value.Measure}"); -//} \ No newline at end of file +await userInput.Start(); \ No newline at end of file diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs index ab15ef7c..340e6329 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/CocktailService.cs @@ -1,135 +1,128 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Text.Json; -using DrinkInfoPractice.Interfaces; +using DrinkInfoPractice.Interfaces; using DrinkInfoPractice.Models; -using System.Text.Json.Serialization; +using System.Text.Json; + +namespace DrinkInfoPractice.Services; -namespace DrinkInfoPractice.Services +internal class CocktailService : ICocktailService { - internal class CocktailService : ICocktailService + // filed for stroing HttpClient + private readonly HttpClient _httpClient; + + // API's base url + private const string BaseUrl = "http://www.thecocktaildb.com/api/json/v1/1/"; + + public CocktailService() { - // filed for stroing HttpClient - private readonly HttpClient _httpClient; + _httpClient = new HttpClient(); - // API's base url - private const string BaseUrl = "http://www.thecocktaildb.com/api/json/v1/1/"; + // setting the base address + _httpClient.BaseAddress = new Uri(BaseUrl); + } - public CocktailService() + public async Task> GetCategoriesAsync() + { + try { - _httpClient = new HttpClient(); + // making the API call + var response = await _httpClient.GetAsync("list.php?c=list"); - // setting the base address - _httpClient.BaseAddress = new Uri(BaseUrl); - } - public async Task> GetCategoriesAsync() - { - try - { - // making the API call - var response = await _httpClient.GetAsync("list.php?c=list"); + // check to see if call was successful + response.EnsureSuccessStatusCode(); + // read the response content + var content = await response.Content.ReadAsStringAsync(); - // check to see if call was successful - response.EnsureSuccessStatusCode(); - // read the response content - var content = await response.Content.ReadAsStringAsync(); - + // convert the JSON to our C# objects + // takes the json and creates DrinkCategory object + var result = JsonSerializer.Deserialize>(content); - // convert the JSON to our C# objects - // takes the json and creates DrinkCategory object - var result = JsonSerializer.Deserialize>(content); - - //return list of categories - // if result or Drinks is null, return empty list - return result?.Drinks ?? new List(); - } - catch (Exception ex) - { - Console.WriteLine($"Error getting categories: {ex.Message}"); - throw; - } + //return list of categories + // if result or Drinks is null, return empty list + return result?.Drinks ?? new List(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting categories: {ex.Message}"); + throw; } + } - public async Task> GetDrinksByCategoryAsync(string category) + public async Task> GetDrinksByCategoryAsync(string category) + { + try { - try - { - // API call - var response = await _httpClient.GetAsync($"filter.php?c={category}"); + // API call + var response = await _httpClient.GetAsync($"filter.php?c={category}"); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - var content = await response.Content.ReadAsStringAsync(); + var content = await response.Content.ReadAsStringAsync(); - var result = JsonSerializer.Deserialize>(content); + var result = JsonSerializer.Deserialize>(content); - return result?.Drinks ?? new List(); - } - catch (Exception ex) - { - Console.WriteLine($"Error getting drink summary: {ex.Message}"); - throw; - } + return result?.Drinks ?? new List(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting drink summary: {ex.Message}"); + throw; } + } - public async Task GetDrinkByIdAsync(string id) + public async Task GetDrinkByIdAsync(string id) + { + try { - try - { - // API call - var response = await _httpClient.GetAsync($"lookup.php?i={id}"); + // API call + var response = await _httpClient.GetAsync($"lookup.php?i={id}"); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - var content = await response.Content.ReadAsStringAsync(); + var content = await response.Content.ReadAsStringAsync(); - var result = JsonSerializer.Deserialize>(content); + var result = JsonSerializer.Deserialize>(content); - var drink = result?.Drinks?.FirstOrDefault(); + var drink = result?.Drinks?.FirstOrDefault(); - if (drink != null) + if (drink != null) + { + // Then process ingredients from the JSON directly + using (JsonDocument document = JsonDocument.Parse(content)) { - // Then process ingredients from the JSON directly - using (JsonDocument document = JsonDocument.Parse(content)) - { - var drinkElement = document.RootElement.GetProperty("drinks")[0]; + var drinkElement = document.RootElement.GetProperty("drinks")[0]; - // Process ingredients - for (int i = 1; i <= 15; i++) + // Process ingredients + for (int i = 1; i <= 15; i++) + { + if (drinkElement.TryGetProperty($"strIngredient{i}", out JsonElement ingredientElement) && + ingredientElement.ValueKind != JsonValueKind.Null) { - if (drinkElement.TryGetProperty($"strIngredient{i}", out JsonElement ingredientElement) && - ingredientElement.ValueKind != JsonValueKind.Null) - { - var ingredient = ingredientElement.GetString(); - var measure = "As needed"; + var ingredient = ingredientElement.GetString(); + var measure = "As needed"; - if (drinkElement.TryGetProperty($"strMeasure{i}", out JsonElement measureElement) && - measureElement.ValueKind != JsonValueKind.Null) - { - measure = measureElement.GetString(); - } - - drink.AddIngredient(i, ingredient, measure); + if (drinkElement.TryGetProperty($"strMeasure{i}", out JsonElement measureElement) && + measureElement.ValueKind != JsonValueKind.Null) + { + measure = measureElement.GetString(); } + + drink.AddIngredient(i, ingredient, measure); } } } - - return drink ?? new DrinkDetail(); - } - catch (Exception ex) - { - Console.WriteLine($"Error getting drink details: {ex.Message}"); - throw; } + + return drink ?? new DrinkDetail(); + } + catch (Exception ex) + { + Console.WriteLine($"Error getting drink details: {ex.Message}"); + throw; } } } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs index 79c2b55c..c2adb00c 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/TableVisualization.cs @@ -1,53 +1,47 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DrinkInfoPractice.Models; +using DrinkInfoPractice.Models; using Spectre.Console; -namespace DrinkInfoPractice.Services +namespace DrinkInfoPractice.Services; + +internal class TableVisualization { - internal class TableVisualization + internal static void ShowTable(DrinkDetail drinkDetail) { - internal static void ShowTable(DrinkDetail drinkDetail) + List ingredientList = new List(); + foreach (var ingredient in drinkDetail.Ingredients) { - List ingredientList = new List(); - foreach (var ingredient in drinkDetail.Ingredients) - { - ingredientList.Add($"- {ingredient.Value.Ingredients}: {ingredient.Value.Measure}"); - } - - string? ingredients = string.Join("\n", ingredientList); - - Console.WriteLine("\n"); - - Table table = new Table(); - - table.AddColumn("Drink ID"); - table.AddColumn("Drink"); - table.AddColumn("Category"); - table.AddColumn("Glass"); - table.AddColumn("Instructions"); - table.AddColumn("Ingredients"); - - table.AddRow( - drinkDetail.IdDrink, - drinkDetail.StrDrink, - drinkDetail.StrCategory, - drinkDetail.StrGlass, - drinkDetail.StrInstructions, - ingredients - ); - - table.Border(TableBorder.Square); - table.BorderColor(Color.Blue); - - AnsiConsole.Write(table); - - Console.WriteLine("Press Enter"); - Console.ReadLine(); - + ingredientList.Add($"- {ingredient.Value.Ingredients}: {ingredient.Value.Measure}"); } + + string? ingredients = string.Join("\n", ingredientList); + + Console.WriteLine("\n"); + + Table table = new Table(); + + table.AddColumn("Drink ID"); + table.AddColumn("Drink"); + table.AddColumn("Category"); + table.AddColumn("Glass"); + table.AddColumn("Instructions"); + table.AddColumn("Ingredients"); + + table.AddRow( + drinkDetail.IdDrink, + drinkDetail.StrDrink, + drinkDetail.StrCategory, + drinkDetail.StrGlass, + drinkDetail.StrInstructions, + ingredients + ); + + table.Border(TableBorder.Square); + table.BorderColor(Color.Blue); + + AnsiConsole.Write(table); + + Console.WriteLine("Press Enter"); + Console.ReadLine(); + } } diff --git a/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs b/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs index dd8d1873..dec34b3c 100644 --- a/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs +++ b/DrinkInfoPractice/DrinkInfoPractice/Services/UserInput.cs @@ -1,79 +1,72 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using DrinkInfoPractice.Models; -using Spectre.Console; - -namespace DrinkInfoPractice.Services +using Spectre.Console; + +namespace DrinkInfoPractice.Services; + +internal class UserInput { - internal class UserInput - { - CocktailService cocktailService = new CocktailService(); + CocktailService cocktailService = new CocktailService(); - internal async Task Start() + internal async Task Start() + { + bool continueRun = true; + while (continueRun) { - bool continueRun = true; - while (continueRun) - { - Console.Clear(); + Console.Clear(); - string category = await CategoryMenu(); + string category = await CategoryMenu(); - string id = await DrinksMenu(category); + string id = await DrinksMenu(category); - TableVisualization.ShowTable(await cocktailService.GetDrinkByIdAsync(id)); + TableVisualization.ShowTable(await cocktailService.GetDrinkByIdAsync(id)); - continueRun = ContinueRun(); - } + continueRun = ContinueRun(); } + } - internal bool ContinueRun() - { - var choice = AnsiConsole.Prompt( - new SelectionPrompt() - .Title("Would you like to find another drink?") - .AddChoices(new[] - { - "Yes", - "No" - })); - return choice == "Yes"; - } + internal bool ContinueRun() + { + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Would you like to find another drink?") + .AddChoices(new[] + { + "Yes", + "No" + })); + return choice == "Yes"; + } - private async Task DrinksMenu(string category) - { - var drinks = await cocktailService.GetDrinksByCategoryAsync(category); + private async Task DrinksMenu(string category) + { + var drinks = await cocktailService.GetDrinksByCategoryAsync(category); - Dictionary drinkMapping = drinks.ToDictionary(d => d.StrDrink, d => d.IdDrink); + Dictionary drinkMapping = drinks.ToDictionary(d => d.StrDrink, d => d.IdDrink); - var drinkNames = drinkMapping.Keys.ToList(); + var drinkNames = drinkMapping.Keys.ToList(); - var choice = AnsiConsole.Prompt( - new SelectionPrompt() - .Title("Select a drink") - .AddChoices(drinkNames)); + var choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Select a drink") + .AddChoices(drinkNames)); - string id = drinkMapping[choice].ToString(); - return id; - } + string id = drinkMapping[choice].ToString(); + return id; + } - internal async Task CategoryMenu() - { - var categories = await cocktailService.GetCategoriesAsync(); + internal async Task CategoryMenu() + { + var categories = await cocktailService.GetCategoriesAsync(); - var categoryNames = categories.Select(c => c.StrCategory).ToList(); - categoryNames.Add("Exit"); + var categoryNames = categories.Select(c => c.StrCategory).ToList(); + categoryNames.Add("Exit"); - var category = AnsiConsole.Prompt( - new SelectionPrompt() - .Title("Selection the category of drink.") - .AddChoices(categoryNames)); + var category = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("Selection the category of drink.") + .AddChoices(categoryNames)); - if (category == "Exit") Environment.Exit(0); + if (category == "Exit") Environment.Exit(0); - return category; - } + return category; } }