From 22eabff276b572e0cada6f17ae89f6c1a6d68738 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Mon, 7 Feb 2022 08:13:55 +0100 Subject: [PATCH] Added search for .stock, it now supports company name search --- .../Modules/Searches/Crypto/CryptoCommands.cs | 5 +- ...aService.cs => DefaultStockDataService.cs} | 57 +++++++++++-------- .../Searches/Crypto/_Common/SymbolData.cs | 3 + .../_Common/YahooFinanceSearchResponse.cs | 19 +++++++ .../_Common/YahooFinanceSearchResponseItem.cs | 25 ++++++++ 5 files changed, 81 insertions(+), 28 deletions(-) rename src/NadekoBot/Modules/Searches/Crypto/_Common/{YahooFinanceStockDataService.cs => DefaultStockDataService.cs} (64%) create mode 100644 src/NadekoBot/Modules/Searches/Crypto/_Common/SymbolData.cs create mode 100644 src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponse.cs create mode 100644 src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponseItem.cs diff --git a/src/NadekoBot/Modules/Searches/Crypto/CryptoCommands.cs b/src/NadekoBot/Modules/Searches/Crypto/CryptoCommands.cs index fe827b73b..42d3c3f25 100644 --- a/src/NadekoBot/Modules/Searches/Crypto/CryptoCommands.cs +++ b/src/NadekoBot/Modules/Searches/Crypto/CryptoCommands.cs @@ -4,6 +4,8 @@ using System.Globalization; namespace NadekoBot.Modules.Searches; +// todo weighted warnings fix +// todo autoplay/fairplay public partial class Searches { public partial class CryptoCommands : NadekoSubmodule @@ -18,9 +20,6 @@ public partial class Searches [Cmd] public async partial Task Stock([Leftover]string query) { - if (!query.IsAlphaNumeric()) - return; - using var typing = ctx.Channel.EnterTypingState(); var stocks = await _stocksService.GetStockDataAsync(query); diff --git a/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceStockDataService.cs b/src/NadekoBot/Modules/Searches/Crypto/_Common/DefaultStockDataService.cs similarity index 64% rename from src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceStockDataService.cs rename to src/NadekoBot/Modules/Searches/Crypto/_Common/DefaultStockDataService.cs index 8fe006250..b234ca94b 100644 --- a/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceStockDataService.cs +++ b/src/NadekoBot/Modules/Searches/Crypto/_Common/DefaultStockDataService.cs @@ -1,4 +1,5 @@ using System.Net.Http.Json; +using System.Text.Json; using YahooFinanceApi; namespace NadekoBot.Modules.Searches; @@ -16,6 +17,9 @@ public sealed class DefaultStockDataService : IStockDataService, INService { try { + if (!query.IsAlphaNumeric()) + return Array.Empty(); + var symbols = await Yahoo.Symbols(query) .Fields(Field.LongName, Field.Symbol, @@ -27,7 +31,7 @@ public sealed class DefaultStockDataService : IStockDataService, INService Field.AverageDailyVolume10Day, Field.FullExchangeName) .QueryAsync(); - + return symbols .Select(static x => x.Value) .Select(static x => new StockData() @@ -52,32 +56,35 @@ public sealed class DefaultStockDataService : IStockDataService, INService } } - public Task> SearchSymbolAsync(string query) + public async Task> SearchSymbolAsync(string query) { - return Task.FromResult>(Array.Empty()); + if (string.IsNullOrWhiteSpace(query)) + throw new ArgumentNullException(nameof(query)); + + query = Uri.EscapeDataString(query); - // try - // { - // query = Uri.EscapeDataString(query); - // using var http = _httpClientFactory.CreateClient(); - // var response = await http.GetFromJsonAsync($"https://finnhub.io/api/v1/search" - // + $"?q={query}" - // + $"&token="); - // - // if (response is null) - // return Array.Empty(); - // - // return response.Result - // .Where(x => x.Type == "Common Stock") - // .Select(static x => new SymbolData(x.Symbol, x.Description)) - // .ToList(); - // } - // catch (Exception ex) - // { - // Log.Warning(ex, "Error searching stock symbol: {ErrorMessage}", ex.Message); - // return Array.Empty(); - // } + using var http = _httpClientFactory.CreateClient(); + + var res = await http.GetStringAsync( + "https://finance.yahoo.com/_finance_doubledown/api/resource/searchassist" + + $";searchTerm={query}" + + "?device=console"); + + var data = JsonSerializer.Deserialize(res); + + if (data is null or { Items: null }) + return Array.Empty(); + + return data.Items + .Where(x => x.Type == "S") + .Select(x => new SymbolData(x.Symbol, x.Name)) + .ToList(); } + + // public async Task> GetCandleDataAsync(string query) + // { + // + // } } -public record SymbolData(string Symbol, string Description); \ No newline at end of file +public record CandleData(); \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Crypto/_Common/SymbolData.cs b/src/NadekoBot/Modules/Searches/Crypto/_Common/SymbolData.cs new file mode 100644 index 000000000..7d160e7d6 --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Crypto/_Common/SymbolData.cs @@ -0,0 +1,3 @@ +namespace NadekoBot.Modules.Searches; + +public record SymbolData(string Symbol, string Description); \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponse.cs b/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponse.cs new file mode 100644 index 000000000..3e6c2d89a --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponse.cs @@ -0,0 +1,19 @@ +#nullable disable +using System.Text.Json.Serialization; + +namespace NadekoBot.Modules.Searches; + +public class YahooFinanceSearchResponse +{ + [JsonPropertyName("suggestionTitleAccessor")] + public string SuggestionTitleAccessor { get; set; } + + [JsonPropertyName("suggestionMeta")] + public List SuggestionMeta { get; set; } + + [JsonPropertyName("hiConf")] + public bool HiConf { get; set; } + + [JsonPropertyName("items")] + public List Items { get; set; } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponseItem.cs b/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponseItem.cs new file mode 100644 index 000000000..f0323dbad --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Crypto/_Common/YahooFinanceSearchResponseItem.cs @@ -0,0 +1,25 @@ +#nullable disable +using System.Text.Json.Serialization; + +namespace NadekoBot.Modules.Searches; + +public class YahooFinanceSearchResponseItem +{ + [JsonPropertyName("symbol")] + public string Symbol { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("exch")] + public string Exch { get; set; } + + [JsonPropertyName("type")] + public string Type { get; set; } + + [JsonPropertyName("exchDisp")] + public string ExchDisp { get; set; } + + [JsonPropertyName("typeDisp")] + public string TypeDisp { get; set; } +} \ No newline at end of file