From 1cce2730579ae8e29a0e548cea6dc2fc0630a89a Mon Sep 17 00:00:00 2001 From: Berack96 Date: Mon, 19 Jan 2026 17:45:01 +0100 Subject: [PATCH 1/4] omdb init --- .gitignore | 3 +++ README.md | 11 ++++++++++- Services/OmdbService.cs | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 Services/OmdbService.cs diff --git a/.gitignore b/.gitignore index 0501afc..6869105 100644 --- a/.gitignore +++ b/.gitignore @@ -396,3 +396,6 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +# ======= +# MINE +APIKey.txt diff --git a/README.md b/README.md index 0a35fb1..798337a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # test-alebro -Test per colloquio \ No newline at end of file +Test per colloquio + +## Istruzioni per l'esecuzione + +Dopo aver clonato il repository, crea un file APIKey.txt nella cartella radice del progetto e inserisci l'API Key di OMDb. + +Poi esegui il progetto con: +```bash +dotnet run +``` diff --git a/Services/OmdbService.cs b/Services/OmdbService.cs new file mode 100644 index 0000000..815304c --- /dev/null +++ b/Services/OmdbService.cs @@ -0,0 +1,24 @@ + + +class OmdbService +{ + private readonly string url; + + public OmdbService() + { + var apiKey = File.ReadAllText("APIKey.txt").Trim(); + apiKey = System.Net.WebUtility.UrlEncode(apiKey); + + url = "http://www.omdbapi.com/?apikey=" + apiKey + "&"; + } + + public async void FetchMovieDetail(string id) + { + // TODO + } + + public async void FetchMovies(string searchTitle) + { + // TODO + } +} \ No newline at end of file -- 2.49.1 From 5a561f9fff5b86b66bbfdc09984b0b710ed2b5d1 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Mon, 19 Jan 2026 18:46:55 +0100 Subject: [PATCH 2/4] Implement movie fetching --- Components/Pages/Favorites.razor | 17 +++++++++++++++++ Program.cs | 3 +++ Services/OmdbService.cs | 22 +++++++++++++++++----- test-alebro.sln | 24 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 test-alebro.sln diff --git a/Components/Pages/Favorites.razor b/Components/Pages/Favorites.razor index a638a0d..932fd64 100644 --- a/Components/Pages/Favorites.razor +++ b/Components/Pages/Favorites.razor @@ -1,7 +1,24 @@ @page "/favorites" +@rendermode InteractiveServer Favorites

TODO

+ +@inject OmdbService OmdbService +@inject IJSRuntime JSRuntime + +@code { + private async Task FaiCose() + { + await JSRuntime.InvokeVoidAsync("console.log", "Cose fatte!"); + + var movies = await OmdbService.FetchMovies("Matrix"); + var movieDetail = await OmdbService.FetchMovieDetail("tt28228084"); + + await JSRuntime.InvokeVoidAsync("console.log", movies); + await JSRuntime.InvokeVoidAsync("console.log", movieDetail); + } +} diff --git a/Program.cs b/Program.cs index f2f6806..e4ac6c2 100644 --- a/Program.cs +++ b/Program.cs @@ -6,6 +6,9 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +// Mine services +builder.Services.AddSingleton(); + var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/Services/OmdbService.cs b/Services/OmdbService.cs index 815304c..08a21c4 100644 --- a/Services/OmdbService.cs +++ b/Services/OmdbService.cs @@ -1,5 +1,7 @@ +using System.Reflection.Metadata; + class OmdbService { private readonly string url; @@ -9,16 +11,26 @@ class OmdbService var apiKey = File.ReadAllText("APIKey.txt").Trim(); apiKey = System.Net.WebUtility.UrlEncode(apiKey); - url = "http://www.omdbapi.com/?apikey=" + apiKey + "&"; + url = "http://www.omdbapi.com/?apikey=" + apiKey + + "&type=movie" + + "&r=json"; } - public async void FetchMovieDetail(string id) + public async Task FetchMovieDetail(string id) { - // TODO + var requestUrl = url + "i=" + System.Net.WebUtility.UrlEncode(id); + using var httpClient = new HttpClient(); + + var response = await httpClient.GetStringAsync(requestUrl); + return response.ToString(); } - public async void FetchMovies(string searchTitle) + public async Task FetchMovies(string searchTitle) { - // TODO + var requestUrl = url + "&t=" + System.Net.WebUtility.UrlEncode(searchTitle); + using var httpClient = new HttpClient(); + + var response = await httpClient.GetStringAsync(requestUrl); + return response.ToString(); } } \ No newline at end of file diff --git a/test-alebro.sln b/test-alebro.sln new file mode 100644 index 0000000..4dc2df2 --- /dev/null +++ b/test-alebro.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-alebro", "test-alebro.csproj", "{80C175CB-7DB0-93BB-681F-01F9DB017FB2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80C175CB-7DB0-93BB-681F-01F9DB017FB2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4E9E6522-3307-4F89-B6D6-2D4D61E7B65B} + EndGlobalSection +EndGlobal -- 2.49.1 From 2751b4181dc5fe4a39637a6e1338343e58ce5fdb Mon Sep 17 00:00:00 2001 From: Berack96 Date: Mon, 19 Jan 2026 20:22:55 +0100 Subject: [PATCH 3/4] models Movie, MovieSearch --- Components/Pages/Favorites.razor | 4 +--- Models/Movie.cs | 20 +++++++++++++++++++ Models/MovieSearch.cs | 15 ++++++++++++++ Services/OmdbService.cs | 34 ++++++++++++++++++++++---------- 4 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 Models/Movie.cs create mode 100644 Models/MovieSearch.cs diff --git a/Components/Pages/Favorites.razor b/Components/Pages/Favorites.razor index 932fd64..a144f9f 100644 --- a/Components/Pages/Favorites.razor +++ b/Components/Pages/Favorites.razor @@ -13,10 +13,8 @@ @code { private async Task FaiCose() { - await JSRuntime.InvokeVoidAsync("console.log", "Cose fatte!"); - var movies = await OmdbService.FetchMovies("Matrix"); - var movieDetail = await OmdbService.FetchMovieDetail("tt28228084"); + var movieDetail = await OmdbService.FetchMovieDetail("tt11749868"); await JSRuntime.InvokeVoidAsync("console.log", movies); await JSRuntime.InvokeVoidAsync("console.log", movieDetail); diff --git a/Models/Movie.cs b/Models/Movie.cs new file mode 100644 index 0000000..e59d11b --- /dev/null +++ b/Models/Movie.cs @@ -0,0 +1,20 @@ + + +using System.Text.Json.Serialization; + + +/// +/// Rappresenta un film con le sue proprietà principali. +/// Non ho preso tutte le proprietà disponibili dall'API OMDB, solo quelle richieste. +/// +class Movie +{ + public required string Title { get; set; } + public required string Year { get; set; } + [JsonPropertyName("imdbID")] + public required string IdIMDB { get; set; } + public required string Poster { get; set; } + public string Runtime { get; set; } = "N/A"; + public string Plot { get; set; } = "N/A"; + +} \ No newline at end of file diff --git a/Models/MovieSearch.cs b/Models/MovieSearch.cs new file mode 100644 index 0000000..d1a7f83 --- /dev/null +++ b/Models/MovieSearch.cs @@ -0,0 +1,15 @@ + + +using System.Text.Json.Serialization; + + +/// +/// Modello per rappresentare i risultati di una ricerca di film. +/// Ha solo scopo di deserializzazione della risposta JSON dell'API OMDB. +/// +class MovieSearch +{ + public required Movie[] Search { get; set; } + [JsonPropertyName("totalResults")] + public required string TotalResults { get; set; } +} \ No newline at end of file diff --git a/Services/OmdbService.cs b/Services/OmdbService.cs index 08a21c4..0945c02 100644 --- a/Services/OmdbService.cs +++ b/Services/OmdbService.cs @@ -1,7 +1,10 @@ +using System.Net; +using System.Text.Json; - -using System.Reflection.Metadata; - +/// +/// Servizio per interagire con l'API OMDB. +/// Semplifica le richieste per ottenere dettagli sui film. +/// class OmdbService { private readonly string url; @@ -9,28 +12,39 @@ class OmdbService public OmdbService() { var apiKey = File.ReadAllText("APIKey.txt").Trim(); - apiKey = System.Net.WebUtility.UrlEncode(apiKey); + apiKey = WebUtility.UrlEncode(apiKey); url = "http://www.omdbapi.com/?apikey=" + apiKey + "&type=movie" + "&r=json"; } - public async Task FetchMovieDetail(string id) + /// + /// Recupera i dettagli di un film dato il suo ID IMDB. + /// + /// ID IMDB del film da cercare. + /// Un oggetto Movie con i dettagli del film. + public async Task FetchMovieDetail(string id) { - var requestUrl = url + "i=" + System.Net.WebUtility.UrlEncode(id); + var requestUrl = url + "&i=" + WebUtility.UrlEncode(id); using var httpClient = new HttpClient(); var response = await httpClient.GetStringAsync(requestUrl); - return response.ToString(); + return JsonSerializer.Deserialize(response)!; } - public async Task FetchMovies(string searchTitle) + + /// + /// Recupera una lista di film che corrispondono al titolo di ricerca. + /// + /// Titolo dei film da cercare. + /// >Una lista di oggetti Movie che corrispondono alla ricerca. + public async Task FetchMovies(string searchTitle) { - var requestUrl = url + "&t=" + System.Net.WebUtility.UrlEncode(searchTitle); + var requestUrl = url + "&s=" + WebUtility.UrlEncode(searchTitle); using var httpClient = new HttpClient(); var response = await httpClient.GetStringAsync(requestUrl); - return response.ToString(); + return JsonSerializer.Deserialize(response)!; } } \ No newline at end of file -- 2.49.1 From 1ab403b3b3ca25e1161e441f9e7fec39dace2011 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Tue, 20 Jan 2026 12:08:36 +0100 Subject: [PATCH 4/4] Home finished --- Components/Pages/Favorites.razor | 4 --- Components/Pages/Home.razor | 52 ++++++++++++++++++++++++++++++-- Components/Pages/Movie.razor | 11 +++++++ Components/Routes.razor | 3 +- Services/OmdbService.cs | 31 +++++++++++++------ 5 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 Components/Pages/Movie.razor diff --git a/Components/Pages/Favorites.razor b/Components/Pages/Favorites.razor index a144f9f..2662792 100644 --- a/Components/Pages/Favorites.razor +++ b/Components/Pages/Favorites.razor @@ -1,5 +1,4 @@ @page "/favorites" -@rendermode InteractiveServer Favorites @@ -15,8 +14,5 @@ { var movies = await OmdbService.FetchMovies("Matrix"); var movieDetail = await OmdbService.FetchMovieDetail("tt11749868"); - - await JSRuntime.InvokeVoidAsync("console.log", movies); - await JSRuntime.InvokeVoidAsync("console.log", movieDetail); } } diff --git a/Components/Pages/Home.razor b/Components/Pages/Home.razor index 9001e0b..7d5fc28 100644 --- a/Components/Pages/Home.razor +++ b/Components/Pages/Home.razor @@ -2,6 +2,54 @@ Home -

Hello, world!

+
+ +
+ +

@((movies == null) ? "" : movies.TotalResults + " results found")

+
+
-Welcome to your new app. + + + + + + + + + + @if (movies?.Search != null) + { + @foreach (var movie in movies.Search) + { + + + + + + } + } + +
TitleYear
@movie.Title@movie.Year
+ + +@inject OmdbService OmdbService +@inject NavigationManager NavigationManager + +@code { + private string searchTitle = ""; + private MovieSearch? movies = null; + + private async Task OnMovieSelected(string imdbID) + { + NavigationManager.NavigateTo($"/movie/{imdbID}"); + } + + private async Task OnSearch() + { + movies = await OmdbService.FetchMovies(searchTitle); + } +} \ No newline at end of file diff --git a/Components/Pages/Movie.razor b/Components/Pages/Movie.razor new file mode 100644 index 0000000..a415d3b --- /dev/null +++ b/Components/Pages/Movie.razor @@ -0,0 +1,11 @@ +@page "/movie/{id}" + +Movie Details + +

TODO

+

Movie ID: @id

+ +@code { + [Parameter] + public string id { get; set; } +} diff --git a/Components/Routes.razor b/Components/Routes.razor index 105855d..43d695d 100644 --- a/Components/Routes.razor +++ b/Components/Routes.razor @@ -1,4 +1,5 @@ - +@rendermode InteractiveServer + diff --git a/Services/OmdbService.cs b/Services/OmdbService.cs index 0945c02..1b0d66b 100644 --- a/Services/OmdbService.cs +++ b/Services/OmdbService.cs @@ -8,6 +8,7 @@ using System.Text.Json; class OmdbService { private readonly string url; + private readonly HttpClient httpClient = new(); public OmdbService() { @@ -24,13 +25,9 @@ class OmdbService /// /// ID IMDB del film da cercare. /// Un oggetto Movie con i dettagli del film. - public async Task FetchMovieDetail(string id) + public async Task FetchMovieDetail(string id) { - var requestUrl = url + "&i=" + WebUtility.UrlEncode(id); - using var httpClient = new HttpClient(); - - var response = await httpClient.GetStringAsync(requestUrl); - return JsonSerializer.Deserialize(response)!; + return await FetchAsync("i", id); } @@ -39,12 +36,26 @@ class OmdbService /// /// Titolo dei film da cercare. /// >Una lista di oggetti Movie che corrispondono alla ricerca. - public async Task FetchMovies(string searchTitle) + public async Task FetchMovies(string searchTitle) { - var requestUrl = url + "&s=" + WebUtility.UrlEncode(searchTitle); - using var httpClient = new HttpClient(); + return await FetchAsync("s", searchTitle); + } + /// + /// Esegue una richiesta HTTP GET e deserializza la risposta JSON in un oggetto del tipo specificato. + /// + /// Tipo dell'oggetto di ritorno. + /// Parametro della query HTTP. + /// Valore del parametro della query HTTP. + /// Un oggetto del tipo specificato deserializzato dalla risposta JSON. + private async Task FetchAsync(string query, string value) + { + var requestUrl = url + "&" + query + "=" + WebUtility.UrlEncode(value); var response = await httpClient.GetStringAsync(requestUrl); - return JsonSerializer.Deserialize(response)!; + try { + return JsonSerializer.Deserialize(response)!; + } catch (JsonException) { + return default; + } } } \ No newline at end of file -- 2.49.1