diff --git a/Aberwyn/Controllers/TorrentController.cs b/Aberwyn/Controllers/TorrentController.cs index 549216b..919562e 100644 --- a/Aberwyn/Controllers/TorrentController.cs +++ b/Aberwyn/Controllers/TorrentController.cs @@ -70,7 +70,10 @@ public class TorrentController : Controller Leechers = t.Leechers, TorrentUrl = t.TorrentUrl, Metadata = t.Metadata, - IsNew = t.InfoHash != null && !seenHashes.Contains(t.InfoHash) + IsNew = t.InfoHash != null && !seenHashes.Contains(t.InfoHash), + AvailableOn = !string.IsNullOrEmpty(t.Metadata?.Providers) + ? t.Metadata.Providers.Split(',').ToList() + : new List() }) .ToList(); diff --git a/Aberwyn/Data/MovieMetadataService.cs b/Aberwyn/Data/MovieMetadataService.cs index e89809f..6822f59 100644 --- a/Aberwyn/Data/MovieMetadataService.cs +++ b/Aberwyn/Data/MovieMetadataService.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Net.Http; +using System.Text; using System.Text.Json; namespace Aberwyn.Data @@ -7,6 +8,8 @@ namespace Aberwyn.Data { private readonly HttpClient _http; private readonly string _apiKey = "6a666b45"; + private readonly string _tpiKey = "6a666b45"; + public MovieMetadataService(HttpClient httpClient) { @@ -44,59 +47,54 @@ namespace Aberwyn.Data return null; } } - - public async Task SearchMovieAsync(string title, string country = "SE") - { - var query = new - { - query = @" - query SearchTitle($query: String!, $country: Country!) { - searchTitles( - country: $country, - filter: { searchQuery: $query }, - first: 1 - ) { - edges { - node { - id - title - releaseYear - content { - imdbId - } - offers { - provider { - id - clearName - } - monetizationType - } - } - } - } - }", - variables = new - { - query = title, - country = country - } - }; - - var requestBody = new StringContent(JsonSerializer.Serialize(query), Encoding.UTF8, "application/json"); - _http.DefaultRequestHeaders.Add("Accept", "application/json"); - _http.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); - var response = await _http.PostAsync("https://apis.justwatch.com/graphql", requestBody); - - if (!response.IsSuccessStatusCode) - return null; - - var result = await response.Content.ReadFromJsonAsync(); - - return result?.data?.searchTitles?.edges?.FirstOrDefault()?.node; - } - } + public class TmdbService + { + private readonly HttpClient _http = new(); + private readonly string _apiKey = "aef2f49296b77b9b9c269678d04bdbc6"; + private readonly string _country = "SE"; + + public async Task GetWatchProvidersByTitleAsync(string title, int? year = null) + { + var query = Uri.EscapeDataString(title); + var url = $"https://api.themoviedb.org/3/search/movie?api_key={_apiKey}&query={query}"; + if (year.HasValue) + url += $"&year={year.Value}"; + + var searchResult = await _http.GetFromJsonAsync(url); + var movie = searchResult?.Results?.FirstOrDefault(); + if (movie == null) return ""; + + var providersUrl = $"https://api.themoviedb.org/3/movie/{movie.Id}/watch/providers?api_key={_apiKey}"; + var providersResult = await _http.GetFromJsonAsync(providersUrl); + + if (providersResult?.Results?.ContainsKey(_country) == true) + { + var seProviders = providersResult.Results[_country]; + var names = new List(); + if (seProviders.Flatrate != null) names.AddRange(seProviders.Flatrate.Select(p => p.ProviderName)); + if (seProviders.Rent != null) names.AddRange(seProviders.Rent.Select(p => p.ProviderName)); + if (seProviders.Buy != null) names.AddRange(seProviders.Buy.Select(p => p.ProviderName)); + return string.Join(", ", names.Distinct()); + } + + return ""; + } + } + + // JSON-klasser för TMDb + public class TmdbSearchResponse { public List Results { get; set; } = new(); } + public class TmdbMovie { public int Id { get; set; } } + public class WatchProvidersResponse { public Dictionary Results { get; set; } = new(); } + public class CountryProviders + { + public List? Flatrate { get; set; } + public List? Rent { get; set; } + public List? Buy { get; set; } + } + public class Provider { public string ProviderName { get; set; } = ""; } + } diff --git a/Aberwyn/Data/RssProcessor.cs b/Aberwyn/Data/RssProcessor.cs index 9010305..b195a4c 100644 --- a/Aberwyn/Data/RssProcessor.cs +++ b/Aberwyn/Data/RssProcessor.cs @@ -84,15 +84,9 @@ namespace Aberwyn.Data if (metadata != null) { torrentItem.Metadata = metadata; - var movie = await _movieMetadataService.SearchMovieAsync(torrentItem.MovieName); - if (movie?.offers != null) - { - metadata.Providers = movie.offers - .Where(o => o.monetizationType == "FLATRATE") // typ Netflix, Prime - .Select(o => o.provider.clearName) - .Distinct() - .ToString(); - } + var tmdbService = new TmdbService(); + torrentItem.Metadata.Providers = await tmdbService.GetWatchProvidersByTitleAsync(torrentItem.Title, torrentItem.Year); + } _context.TorrentItems.Add(torrentItem); diff --git a/Aberwyn/Models/TorrentInfo.cs b/Aberwyn/Models/TorrentInfo.cs index cba258c..b9cede5 100644 --- a/Aberwyn/Models/TorrentInfo.cs +++ b/Aberwyn/Models/TorrentInfo.cs @@ -106,6 +106,7 @@ public class TorrentListItemViewModel public string? TorrentUrl { get; set; } public MovieMetadata? Metadata { get; set; } public bool IsNew { get; set; } = false; + public List AvailableOn { get; set; } = new(); } public class JustWatchResponse { diff --git a/Aberwyn/Views/Torrent/Index.cshtml b/Aberwyn/Views/Torrent/Index.cshtml index 5c2f9d6..57c3467 100644 --- a/Aberwyn/Views/Torrent/Index.cshtml +++ b/Aberwyn/Views/Torrent/Index.cshtml @@ -75,6 +75,12 @@ ⭐ @main.Metadata.ImdbRating } + @if (main.AvailableOn?.Any() == true) + { +
+ Tillgänglig på: @string.Join(", ", main.AvailableOn) +
+ } diff --git a/Aberwyn/wwwroot/css/torrent.css b/Aberwyn/wwwroot/css/torrent.css index ebaccd5..0a9db08 100644 --- a/Aberwyn/wwwroot/css/torrent.css +++ b/Aberwyn/wwwroot/css/torrent.css @@ -185,4 +185,10 @@ .imdb:hover { text-decoration: underline; - } \ No newline at end of file + } + +.available-on { + font-size: 0.85rem; + color: #888; + margin-top: 4px; +} \ No newline at end of file