diff --git a/src/Apis/Bing/BingVisualSearch.cs b/src/Apis/Bing/BingVisualSearch.cs index 1122d82..54b4c60 100644 --- a/src/Apis/Bing/BingVisualSearch.cs +++ b/src/Apis/Bing/BingVisualSearch.cs @@ -6,7 +6,6 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Fergun.Extensions; namespace Fergun.Apis.Bing; @@ -150,6 +149,7 @@ public void Dispose() private static JsonElement GetImageTag(JsonDocument document, string displayName) => document .RootElement .GetProperty("tags"u8) + .EnumerateArray() .FirstOrDefault(x => x.GetProperty("displayName"u8).ValueEquals(displayName)); private static HttpRequestMessage BuildRequest(string url, string invokedSkill, BingSafeSearchLevel safeSearch = BingSafeSearchLevel.Moderate, string? language = null) diff --git a/src/Apis/Genius/LyricsConverter.cs b/src/Apis/Genius/LyricsConverter.cs index e46935d..08121c1 100644 --- a/src/Apis/Genius/LyricsConverter.cs +++ b/src/Apis/Genius/LyricsConverter.cs @@ -26,7 +26,7 @@ public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonS { var builder = new StringBuilder(); var dom = JsonElement.ParseValue(ref reader) - .GetProperty("dom"); + .GetProperty("dom"u8); IterateContent(dom, builder); return builder.ToString(); @@ -44,15 +44,15 @@ private static void IterateContent(in JsonElement element, StringBuilder builder } else if (element.ValueKind == JsonValueKind.Object) // either tag or tag + children { - string? tag = element.GetProperty("tag").GetString(); - bool realLink = element.TryGetProperty("data", out var data) && data.TryGetProperty("real-link", out var realLinkProp) && realLinkProp.ValueEquals("true"); + string? tag = element.GetProperty("tag"u8).GetString(); + bool realLink = element.TryGetProperty("data"u8, out var data) && data.TryGetProperty("real-link"u8, out var realLinkProp) && realLinkProp.ValueEquals("true"u8); (string? markDownStart, string? markDownEnd) = tag switch { ITALIC => ("*", "*"), BOLD => ("**", "**"), LINE_BREAK or HORIZONTAL_LINE or IMAGE or DFP_UNIT => ("\n", null), - LINK when realLink => ("[", $"]({element.GetProperty("attributes").GetProperty("href").GetString()})"), + LINK when realLink => ("[", $"]({element.GetProperty("attributes"u8).GetProperty("href"u8).GetString()})"), UNDERLINE => ("__", "__"), "h1" => ("\n# ", "\n"), "h2" => ("\n## ", "\n"), @@ -67,7 +67,7 @@ private static void IterateContent(in JsonElement element, StringBuilder builder builder.Append(markDownStart); - if (element.TryGetProperty("children", out var children)) + if (element.TryGetProperty("children"u8, out var children)) { Debug.Assert(children.ValueKind == JsonValueKind.Array); diff --git a/src/Apis/Google/GoogleLensClient.cs b/src/Apis/Google/GoogleLensClient.cs index fb996c6..1948376 100644 --- a/src/Apis/Google/GoogleLensClient.cs +++ b/src/Apis/Google/GoogleLensClient.cs @@ -58,7 +58,7 @@ public async Task OcrAsync(string url, CancellationToken cancellationTok return string.Empty; } - return string.Join('\n', data[0].EnumerateArray().Select(x => x.GetString())); + return string.Join('\n', data[0].Deserialize()!); } /// diff --git a/src/Apis/Musixmatch/MusixmatchClient.cs b/src/Apis/Musixmatch/MusixmatchClient.cs index 7f4c7da..550c354 100644 --- a/src/Apis/Musixmatch/MusixmatchClient.cs +++ b/src/Apis/Musixmatch/MusixmatchClient.cs @@ -64,11 +64,11 @@ public async Task> SearchSongsAsync(string query, return document .RootElement - .GetProperty("message") - .GetProperty("body") - .GetProperty("track_list") + .GetProperty("message"u8) + .GetProperty("body"u8) + .GetProperty("track_list"u8) .EnumerateArray() - .Select(x => x.GetProperty("track").Deserialize()!) + .Select(x => x.GetProperty("track"u8).Deserialize()!) .ToArray(); } @@ -84,15 +84,15 @@ public async Task> SearchSongsAsync(string query, var macroCalls = document .RootElement - .GetProperty("message") - .GetProperty("body") - .GetProperty("macro_calls")[0]; + .GetProperty("message"u8) + .GetProperty("body"u8) + .GetProperty("macro_calls"u8)[0]; var trackStatusCode = (HttpStatusCode)macroCalls - .GetProperty("track.get") - .GetProperty("message") - .GetProperty("header") - .GetProperty("status_code") + .GetProperty("track.get"u8) + .GetProperty("message"u8) + .GetProperty("header"u8) + .GetProperty("status_code"u8) .GetInt32(); if (trackStatusCode == HttpStatusCode.NotFound) @@ -101,43 +101,43 @@ public async Task> SearchSongsAsync(string query, } var lyricsStatusCode = (HttpStatusCode)macroCalls - .GetProperty("track.lyrics.get") - .GetProperty("message") - .GetProperty("header") - .GetProperty("status_code") + .GetProperty("track.lyrics.get"u8) + .GetProperty("message"u8) + .GetProperty("header"u8) + .GetProperty("status_code"u8) .GetInt32(); var lyricsData = lyricsStatusCode == HttpStatusCode.NotFound ? default : macroCalls - .GetProperty("track.lyrics.get") - .GetProperty("message") - .GetProperty("body") - .GetProperty("lyrics"); + .GetProperty("track.lyrics.get"u8) + .GetProperty("message"u8) + .GetProperty("body"u8) + .GetProperty("lyrics"u8); string? lyrics = lyricsStatusCode == HttpStatusCode.NotFound ? null : lyricsData - .GetProperty("lyrics_body") + .GetProperty("lyrics_body"u8) .GetString(); var trackData = macroCalls - .GetProperty("track.get") - .GetProperty("message") - .GetProperty("body") - .GetProperty("track"); + .GetProperty("track.get"u8) + .GetProperty("message"u8) + .GetProperty("body"u8) + .GetProperty("track"u8); bool isRestricted = lyricsStatusCode == HttpStatusCode.NotFound ? trackData - .GetProperty("restricted") + .GetProperty("restricted"u8) .GetInt32() != 0 : lyricsData - .GetProperty("restricted") + .GetProperty("restricted"u8) .GetInt32() != 0; - string artistName = trackData.GetProperty("artist_name").GetString()!; - bool isInstrumental = trackData.GetProperty("instrumental").GetInt32() != 0; - bool hasLyrics = trackData.GetProperty("has_lyrics").GetInt32() != 0; - string? songArtImageUrl = trackData.GetProperty("album_coverart_500x500").GetString(); - string title = trackData.GetProperty("track_name").GetString()!; - int artistId = trackData.GetProperty("artist_id").GetInt32(); + string artistName = trackData.GetProperty("artist_name"u8).GetString()!; + bool isInstrumental = trackData.GetProperty("instrumental"u8).GetInt32() != 0; + bool hasLyrics = trackData.GetProperty("has_lyrics"u8).GetInt32() != 0; + string? songArtImageUrl = trackData.GetProperty("album_coverart_500x500"u8).GetString(); + string title = trackData.GetProperty("track_name"u8).GetString()!; + int artistId = trackData.GetProperty("artist_id"u8).GetInt32(); string? spotifyTrackId = null; - if (trackData.TryGetProperty("track_spotify_id", out var trackIdProp)) + if (trackData.TryGetProperty("track_spotify_id"u8, out var trackIdProp)) { spotifyTrackId = trackIdProp.GetString(); } @@ -167,17 +167,17 @@ public void Dispose() internal static void ThrowIfNotSuccessful(in JsonElement body, string? path = null) { var header = body - .GetProperty("message") - .GetProperty("header"); + .GetProperty("message"u8) + .GetProperty("header"u8); var statusCode = (HttpStatusCode)header - .GetProperty("status_code") + .GetProperty("status_code"u8) .GetInt32(); if (statusCode is HttpStatusCode.OK or HttpStatusCode.NotFound) return; string? hint = header - .GetProperty("hint") + .GetProperty("hint"u8) .GetString(); MusixmatchException.Throw(statusCode, path, hint); @@ -198,8 +198,8 @@ private async Task SendRequestAndValidateAsync(string url, Cancell ThrowIfNotSuccessful(document.RootElement); - var body = document.RootElement.GetProperty("message").GetProperty("body"); - if (body.TryGetProperty("macro_calls", out var macroCalls) && macroCalls.ValueKind == JsonValueKind.Array) + var body = document.RootElement.GetProperty("message"u8).GetProperty("body"u8); + if (body.TryGetProperty("macro_calls"u8, out var macroCalls) && macroCalls.ValueKind == JsonValueKind.Array) { foreach (var prop in macroCalls.EnumerateArray()) { diff --git a/src/Apis/Musixmatch/MusixmatchClientState.cs b/src/Apis/Musixmatch/MusixmatchClientState.cs index 6593bf7..1a3989b 100644 --- a/src/Apis/Musixmatch/MusixmatchClientState.cs +++ b/src/Apis/Musixmatch/MusixmatchClientState.cs @@ -97,9 +97,9 @@ private async Task FetchUserTokenAsync() string? token = document .RootElement - .GetProperty("message") - .GetProperty("body") - .GetProperty("user_token") + .GetProperty("message"u8) + .GetProperty("body"u8) + .GetProperty("user_token"u8) .GetString(); if (string.IsNullOrEmpty(token) || token == "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") diff --git a/src/Apis/Urban/UrbanDictionary.cs b/src/Apis/Urban/UrbanDictionary.cs index 1b83eee..e796bcc 100644 --- a/src/Apis/Urban/UrbanDictionary.cs +++ b/src/Apis/Urban/UrbanDictionary.cs @@ -52,7 +52,7 @@ public async Task> GetDefinitionsAsync(string ter await using var stream = await _httpClient.GetStreamAsync(new Uri($"define?term={Uri.EscapeDataString(term)}", UriKind.Relative), cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - return document.RootElement.GetProperty("list").Deserialize>()!; + return document.RootElement.GetProperty("list"u8).Deserialize>()!; } /// @@ -63,7 +63,7 @@ public async Task> GetRandomDefinitionsAsync(Canc await using var stream = await _httpClient.GetStreamAsync(new Uri("random", UriKind.Relative), cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - return document.RootElement.GetProperty("list").Deserialize>()!; + return document.RootElement.GetProperty("list"u8).Deserialize>()!; } /// @@ -74,7 +74,7 @@ public async Task> GetRandomDefinitionsAsync(Canc await using var stream = await _httpClient.GetStreamAsync(new Uri($"define?defid={id}", UriKind.Relative), cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - var list = document.RootElement.GetProperty("list"); + var list = document.RootElement.GetProperty("list"u8); return list.GetArrayLength() == 0 ? null : list[0].Deserialize()!; } @@ -87,7 +87,7 @@ public async Task> GetWordsOfTheDayAsync(Cancella await using var stream = await _httpClient.GetStreamAsync(new Uri("words_of_the_day", UriKind.Relative), cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - return document.RootElement.GetProperty("list").Deserialize>()!; + return document.RootElement.GetProperty("list"u8).Deserialize>()!; } /// @@ -107,7 +107,7 @@ public async Task> GetAutocompleteResults await using var stream = await _httpClient.GetStreamAsync(new Uri($"autocomplete-extra?term={Uri.EscapeDataString(term)}", UriKind.Relative), cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - return document.RootElement.GetProperty("results").Deserialize>()!; + return document.RootElement.GetProperty("results"u8).Deserialize>()!; } /// diff --git a/src/Apis/Wikipedia/WikipediaClient.cs b/src/Apis/Wikipedia/WikipediaClient.cs index f1a1632..a22e4d1 100644 --- a/src/Apis/Wikipedia/WikipediaClient.cs +++ b/src/Apis/Wikipedia/WikipediaClient.cs @@ -57,10 +57,10 @@ public WikipediaClient(HttpClient httpClient) using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); var page = document.RootElement - .GetProperty("query") - .GetProperty("pages")[0]; + .GetProperty("query"u8) + .GetProperty("pages"u8)[0]; - if (page.TryGetProperty("missing", out var missing) && missing.GetBoolean()) + if (page.TryGetProperty("missing"u8, out var missing) && missing.GetBoolean()) { return null; } @@ -83,8 +83,8 @@ public async Task> SearchArticlesAsync(s return document .RootElement - .GetProperty("query") - .GetProperty("search") + .GetProperty("query"u8) + .GetProperty("search"u8) .Deserialize>()!; } diff --git a/src/Apis/WolframAlpha/WolframAlphaClient.cs b/src/Apis/WolframAlpha/WolframAlphaClient.cs index 1397d3d..363e0c0 100644 --- a/src/Apis/WolframAlpha/WolframAlphaClient.cs +++ b/src/Apis/WolframAlpha/WolframAlphaClient.cs @@ -63,9 +63,9 @@ public async Task> GetAutocompleteResultsAsync(string inpu return document .RootElement - .GetProperty("results") + .GetProperty("results"u8) .EnumerateArray() - .Select(x => x.GetProperty("input").GetString()!) + .Select(x => x.GetProperty("input"u8).GetString()!) .ToArray(); } @@ -87,7 +87,7 @@ public async Task SendQueryAsync(string input, string langu using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - return document.RootElement.GetProperty("queryresult").Deserialize()!; + return document.RootElement.GetProperty("queryresult"u8).Deserialize()!; } /// diff --git a/src/Apis/Yandex/YandexImageSearch.cs b/src/Apis/Yandex/YandexImageSearch.cs index 3bf67d6..76bc302 100644 --- a/src/Apis/Yandex/YandexImageSearch.cs +++ b/src/Apis/Yandex/YandexImageSearch.cs @@ -6,7 +6,6 @@ using System.Threading; using System.Threading.Tasks; using AngleSharp.Html.Parser; -using Fergun.Extensions; namespace Fergun.Apis.Yandex; @@ -70,12 +69,12 @@ public YandexImageSearch(HttpClient httpClient) string? imageId = document .RootElement - .GetProperty("image_id") + .GetProperty("image_id"u8) .GetString(); int imageShard = document .RootElement - .GetProperty("image_shard") + .GetProperty("image_shard"u8) .GetInt32(); // Get OCR text @@ -89,18 +88,18 @@ public YandexImageSearch(HttpClient httpClient) byte[] bytes = await ocrResponse.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false); using var ocrDocument = JsonDocument.Parse(bytes); - if (ocrDocument.RootElement.TryGetProperty("type", out var type) && type.ValueEquals("captcha")) + if (ocrDocument.RootElement.TryGetProperty("type"u8, out var type) && type.ValueEquals("captcha"u8)) { throw new YandexException("Yandex API returned a CAPTCHA. Try again later."); } return ocrDocument .RootElement - .GetProperty("blocks")[0] // There should be a single block, "i-react-ajax-adapter:ajax" - .GetProperty("params") - .GetPropertyOrDefault("adapterData") - .GetPropertyOrDefault("plainText") - .GetStringOrDefault(); + .GetProperty("blocks"u8)[0] // There should be a single block, "i-react-ajax-adapter:ajax" + .GetProperty("params"u8) + .GetProperty("adapterData"u8) + .GetProperty("plainText"u8) + .GetString(); } /// @@ -137,15 +136,15 @@ public async Task> ReverseImageSe await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken).ConfigureAwait(false); - if (document.RootElement.TryGetProperty("type", out var type) && type.ValueEquals("captcha")) + if (document.RootElement.TryGetProperty("type"u8, out var type) && type.ValueEquals("captcha"u8)) { throw new YandexException("Yandex API returned a CAPTCHA. Try again later."); } string html = document .RootElement - .GetProperty("blocks")[0] - .GetProperty("html") + .GetProperty("blocks"u8)[0] + .GetProperty("html"u8) .GetString()!; var htmlDocument = await _parser.ParseDocumentAsync(html, cancellationToken).ConfigureAwait(false); @@ -163,14 +162,14 @@ public async Task> ReverseImageSe using var data = JsonDocument.Parse(json); - if (data.RootElement.TryGetProperty("initialState", out var initialState)) + if (data.RootElement.TryGetProperty("initialState"u8, out var initialState)) { return initialState - .GetProperty("serpList") - .GetProperty("items") - .GetProperty("entities") + .GetProperty("serpList"u8) + .GetProperty("items"u8) + .GetProperty("entities"u8) .EnumerateObject() - .Select(x => x.Value.GetProperty("viewerData").Deserialize()!) + .Select(x => x.Value.GetProperty("viewerData"u8).Deserialize()!) .ToArray(); } @@ -179,7 +178,7 @@ public async Task> ReverseImageSe .GetElementsByClassName("serp-list") .FirstOrDefault()? .GetElementsByClassName("serp-item") - .Select(x => JsonDocument.Parse(x.GetAttribute("data-bem")!).RootElement.GetProperty("serp-item").Deserialize()!) + .Select(x => JsonDocument.Parse(x.GetAttribute("data-bem")!).RootElement.GetProperty("serp-item"u8).Deserialize()!) .ToArray() ?? []; } diff --git a/src/Entities/Constants.cs b/src/Entities/Constants.cs index e958509..ec2e241 100644 --- a/src/Entities/Constants.cs +++ b/src/Entities/Constants.cs @@ -36,5 +36,15 @@ public static class Constants public const string GeniusLogoUrl = "https://cdn.discordapp.com/attachments/838832564583661638/1114311596450254980/genius_logo.png"; + public const string GoogleUrl = "https://google.com"; + + public const string DuckDuckGoUrl = "https://duckduckgo.com"; + + public const string YandexImageSearchUrl = "https://yandex.com/images"; + + public const string BingVisualSearchUrl = "https://www.bing.com/visualsearch"; + + public const string GoogleLensUrl = "https://lens.google.com"; + public const string ChromeUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"; } \ No newline at end of file diff --git a/src/Entities/FergunLocalizer.cs b/src/Entities/FergunLocalizer.cs index 825ab54..9e72153 100644 --- a/src/Entities/FergunLocalizer.cs +++ b/src/Entities/FergunLocalizer.cs @@ -36,11 +36,11 @@ public FergunLocalizer(IStringLocalizer localizer, IStringLocalizer /// Gets a read-only list containing the languages that Fergun supports. /// - public static IReadOnlyList SupportedCultures { get; } = new[] - { + public static IReadOnlyList SupportedCultures { get; } = + [ CultureInfo.GetCultureInfo("en"), CultureInfo.GetCultureInfo("es") - }; + ]; /// /// Setting a value won't have an effect if the value is not in . diff --git a/src/Extensions/JsonExtensions.cs b/src/Extensions/JsonExtensions.cs deleted file mode 100644 index 28dcbc1..0000000 --- a/src/Extensions/JsonExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; - -namespace Fergun.Extensions; - -public static class JsonExtensions -{ - public static IEnumerable EnumerateArrayOrEmpty(this JsonElement element) - => element.ValueKind == JsonValueKind.Array ? element.EnumerateArray() : Enumerable.Empty(); - - public static JsonElement FirstOrDefault(this JsonElement element) - => element.ValueKind == JsonValueKind.Array ? element.EnumerateArray().FirstOrDefault() : default; - - public static JsonElement FirstOrDefault(this JsonElement element, Func predicate) - => element.ValueKind == JsonValueKind.Array ? element.EnumerateArray().FirstOrDefault(predicate) : default; - - public static JsonElement GetPropertyOrDefault(this JsonElement element, string propertyName) - => element.ValueKind == JsonValueKind.Object && element.TryGetProperty(propertyName, out var value) ? value : default; - - public static string? GetStringOrDefault(this JsonElement element) - => element.ValueKind == JsonValueKind.String ? element.GetString() : default; -} \ No newline at end of file diff --git a/src/Modules/Handlers/DuckDuckGoAutocompleteHandler.cs b/src/Modules/Handlers/DuckDuckGoAutocompleteHandler.cs index f6e6cdf..c9405d3 100644 --- a/src/Modules/Handlers/DuckDuckGoAutocompleteHandler.cs +++ b/src/Modules/Handlers/DuckDuckGoAutocompleteHandler.cs @@ -51,7 +51,7 @@ public override async Task GenerateSuggestionsAsync(IInter var results = document .RootElement .EnumerateArray() - .Select(x => new AutocompleteResult(x.GetProperty("phrase").GetString(), x.GetProperty("phrase").GetString())) + .Select(x => new AutocompleteResult(x.GetProperty("phrase"u8).GetString(), x.GetProperty("phrase"u8).GetString())) .Take(25); return AutocompletionResult.FromSuccess(results); diff --git a/src/Modules/ImageModule.cs b/src/Modules/ImageModule.cs index 14009aa..f31651b 100644 --- a/src/Modules/ImageModule.cs +++ b/src/Modules/ImageModule.cs @@ -101,7 +101,7 @@ MultiEmbedPageBuilder GeneratePage(int index) var builders = images.Take(start..(start + count)).Select(result => new EmbedBuilder() .WithTitle(result.Title.Truncate(EmbedBuilder.MaxTitleLength)) .WithDescription(_localizer["GoogleImagesSearch"]) - .WithUrl(multiImages ? "https://google.com" : result.SourceUrl) + .WithUrl(multiImages ? Constants.GoogleUrl : result.SourceUrl) .WithImageUrl(result.Url) .WithFooter(_localizer["PaginatorFooter", index + 1, maxIndex + 1], Constants.GoogleLogoUrl) .WithColor((Color)(result.Color ?? Color.Orange))); @@ -155,7 +155,7 @@ MultiEmbedPageBuilder GeneratePage(int index) var builders = images.Take(start..(start + count)).Select(result => new EmbedBuilder() .WithTitle(result.Title.Truncate(EmbedBuilder.MaxTitleLength)) .WithDescription(_localizer["DuckDuckGoImageSearch"]) - .WithUrl(multiImages ? "https://duckduckgo.com" : result.SourceUrl) + .WithUrl(multiImages ? Constants.DuckDuckGoUrl : result.SourceUrl) .WithImageUrl(result.Url) .WithFooter(_localizer["PaginatorFooter", index + 1, maxIndex + 1], Constants.DuckDuckGoLogoUrl) .WithColor(Color.Orange)); @@ -228,14 +228,14 @@ public async Task ReverseAsync(string url, ReverseImageSearchEngi return engine switch { - ReverseImageSearchEngine.Yandex => await YandexAsync(url, multiImages, interaction, originalInteraction, ephemeral), - ReverseImageSearchEngine.Bing => await BingAsync(url, multiImages, interaction, originalInteraction, ephemeral), - ReverseImageSearchEngine.Google => await GoogleAsync(url, multiImages, interaction, originalInteraction, ephemeral), + ReverseImageSearchEngine.Yandex => await ReverseYandexAsync(url, multiImages, interaction, originalInteraction, ephemeral), + ReverseImageSearchEngine.Bing => await ReverseBingAsync(url, multiImages, interaction, originalInteraction, ephemeral), + ReverseImageSearchEngine.Google => await ReverseGoogleAsync(url, multiImages, interaction, originalInteraction, ephemeral), _ => throw new ArgumentException(_localizer["InvalidImageSearchEngine"], nameof(engine)) }; } - public virtual async Task YandexAsync(string url, bool multiImages, IDiscordInteraction interaction, + public virtual async Task ReverseYandexAsync(string url, bool multiImages, IDiscordInteraction interaction, IDiscordInteraction? originalInteraction = null, bool ephemeral = false) { if (interaction is IComponentInteraction componentInteraction) @@ -304,7 +304,7 @@ MultiEmbedPageBuilder GeneratePage(int index) var builders = results.Take(start..(start + count)).Select(result => new EmbedBuilder() .WithTitle(result.Title?.Truncate(EmbedBuilder.MaxTitleLength) ?? string.Empty) .WithDescription(result.Text) - .WithUrl(multiImages ? "https://yandex.com/images" : result.SourceUrl) + .WithUrl(multiImages ? Constants.YandexImageSearchUrl : result.SourceUrl) .WithThumbnailUrl(url) .WithImageUrl(result.Url) .WithFooter(_localizer["YandexVisualSearchPaginatorFooter", index + 1, maxIndex + 1], Constants.YandexIconUrl) @@ -314,7 +314,7 @@ MultiEmbedPageBuilder GeneratePage(int index) } } - public virtual async Task BingAsync(string url, bool multiImages, IDiscordInteraction interaction, + public virtual async Task ReverseBingAsync(string url, bool multiImages, IDiscordInteraction interaction, IDiscordInteraction? originalInteraction = null, bool ephemeral = false) { if (interaction is IComponentInteraction componentInteraction) @@ -381,7 +381,7 @@ MultiEmbedPageBuilder GeneratePage(int index) var builders = results.Take(start..(start + count)).Select(result => new EmbedBuilder() .WithTitle(result.Text.Truncate(EmbedBuilder.MaxTitleLength)) - .WithUrl(multiImages ? "https://www.bing.com/visualsearch" : result.SourceUrl) + .WithUrl(multiImages ? Constants.BingVisualSearchUrl : result.SourceUrl) .WithThumbnailUrl(url) .WithDescription(result.FriendlyDomainName ?? (Uri.TryCreate(result.SourceUrl, UriKind.Absolute, out var uri) ? uri.Host : null)) .WithImageUrl(result.Url) @@ -392,7 +392,7 @@ MultiEmbedPageBuilder GeneratePage(int index) } } - public virtual async Task GoogleAsync(string url, bool multiImages, IDiscordInteraction interaction, + public virtual async Task ReverseGoogleAsync(string url, bool multiImages, IDiscordInteraction interaction, IDiscordInteraction? originalInteraction = null, bool ephemeral = false) { if (interaction is IComponentInteraction componentInteraction) @@ -458,7 +458,7 @@ MultiEmbedPageBuilder GeneratePage(int index) var builders = results.Take(start..(start + count)).Select(result => new EmbedBuilder() .WithTitle(result.Title.Truncate(EmbedBuilder.MaxTitleLength)) - .WithUrl(multiImages ? "https://lens.google.com/" : result.SourcePageUrl) + .WithUrl(multiImages ? Constants.GoogleLensUrl : result.SourcePageUrl) .WithThumbnailUrl(url) .WithAuthor(result.SourceDomainName, result.SourceIconUrl) .WithImageUrl(result.ThumbnailUrl) diff --git a/tests/Fergun.Tests/Entities/FergunLocalizerTests.cs b/tests/Fergun.Tests/Entities/FergunLocalizerTests.cs index 31bb9b5..c8f8a34 100644 --- a/tests/Fergun.Tests/Entities/FergunLocalizerTests.cs +++ b/tests/Fergun.Tests/Entities/FergunLocalizerTests.cs @@ -109,12 +109,15 @@ private static Mock> CreateMockedLocalizer(string name, s localizerMock .Setup(x => x[It.IsAny(), It.IsAny()]) - .Returns((s, p) => s == name - ? new LocalizedString(s, p.Length == 0 ? value : string.Format(value, p)) - : new LocalizedString(s, string.Empty, true)); + .Returns((s, p) => + { + if (s == name) + return new LocalizedString(s, p.Length == 0 ? value : string.Format(value, p)); + return new LocalizedString(s, string.Empty, true); + }); localizerMock.Setup(x => x.GetAllStrings(It.IsAny())) - .Returns(() => new[] { new LocalizedString(name, value) }); + .Returns(() => [new LocalizedString(name, value)]); localizerMock.SetupAllProperties(); diff --git a/tests/Fergun.Tests/Modules/ImageModuleTests.cs b/tests/Fergun.Tests/Modules/ImageModuleTests.cs index a4f2c6b..c007af0 100644 --- a/tests/Fergun.Tests/Modules/ImageModuleTests.cs +++ b/tests/Fergun.Tests/Modules/ImageModuleTests.cs @@ -134,12 +134,12 @@ public async Task ReverseAsync_Sends_Paginator(string? url, IAttachment? file, R if (engine == ReverseImageSearchEngine.Bing) { - _moduleMock.Verify(x => x.BingAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(b => b == multiImages), It.IsAny(), It.IsAny(), It.Is(b => !b)), Times.Once); + _moduleMock.Verify(x => x.ReverseBingAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(b => b == multiImages), It.IsAny(), It.IsAny(), It.Is(b => !b)), Times.Once); Mock.Get(_bingVisualSearch).Verify(x => x.ReverseImageSearchAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(l => l == (nsfw ? BingSafeSearchLevel.Off : BingSafeSearchLevel.Strict)), It.IsAny(), It.IsAny()), Times.Once); } else if (engine == ReverseImageSearchEngine.Yandex) { - _moduleMock.Verify(x => x.YandexAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(b => b == multiImages), It.IsAny(), It.IsAny(), It.Is(b => !b)), Times.Once); + _moduleMock.Verify(x => x.ReverseYandexAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(b => b == multiImages), It.IsAny(), It.IsAny(), It.Is(b => !b)), Times.Once); Mock.Get(_yandexImageSearch).Verify(x => x.ReverseImageSearchAsync(It.Is(s => s == (file == null ? url : file.Url)), It.Is(l => l == (nsfw ? YandexSearchFilterMode.None : YandexSearchFilterMode.Family)), It.IsAny()), Times.Once); } }