From 6fefce4c4d22d6990d49abf4d0e75bbc3f5560fe Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 30 Jul 2024 14:12:16 +0000 Subject: [PATCH] dev: refactored .bible and .quran, moved to their own folder and created ReligiousApiService for their logic --- src/NadekoBot/.editorconfig | 1 - .../Searches/Religious/Common/BibleVerse.cs | 13 +++ .../Searches/Religious/Common/BibleVerses.cs | 7 ++ .../Searches/Religious/Common/QuranAyah.cs | 20 ++++ .../Religious/Common/QuranResponse.cs | 15 +++ .../Searches/Religious/ReligiousApiService.cs | 63 +++++++++++ .../Searches/Religious/ReligiousCommands.cs | 60 +++++++++++ .../Modules/Searches/ReligiousCommands.cs | 102 ------------------ .../Modules/Searches/_common/BibleVerses.cs | 21 ---- 9 files changed, 178 insertions(+), 124 deletions(-) create mode 100644 src/NadekoBot/Modules/Searches/Religious/Common/BibleVerse.cs create mode 100644 src/NadekoBot/Modules/Searches/Religious/Common/BibleVerses.cs create mode 100644 src/NadekoBot/Modules/Searches/Religious/Common/QuranAyah.cs create mode 100644 src/NadekoBot/Modules/Searches/Religious/Common/QuranResponse.cs create mode 100644 src/NadekoBot/Modules/Searches/Religious/ReligiousApiService.cs create mode 100644 src/NadekoBot/Modules/Searches/Religious/ReligiousCommands.cs delete mode 100644 src/NadekoBot/Modules/Searches/ReligiousCommands.cs delete mode 100644 src/NadekoBot/Modules/Searches/_common/BibleVerses.cs diff --git a/src/NadekoBot/.editorconfig b/src/NadekoBot/.editorconfig index 019cc435d..9f35ed645 100644 --- a/src/NadekoBot/.editorconfig +++ b/src/NadekoBot/.editorconfig @@ -77,7 +77,6 @@ csharp_style_var_when_type_is_apparent = true:suggestion # Expression-bodied members csharp_style_expression_bodied_accessors = true:suggestion -csharp_style_expression_bodied_constructors = when_on_single_line:suggestion csharp_style_expression_bodied_indexers = true:suggestion csharp_style_expression_bodied_lambdas = true:suggestion csharp_style_expression_bodied_local_functions = true:suggestion diff --git a/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerse.cs b/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerse.cs new file mode 100644 index 000000000..135afa196 --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerse.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace NadekoBot.Modules.Searches; + +public class BibleVerse +{ + [JsonPropertyName("book_name")] + public required string BookName { get; set; } + + public required int Chapter { get; set; } + public required int Verse { get; set; } + public required string Text { get; set; } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerses.cs b/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerses.cs new file mode 100644 index 000000000..03218be97 --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/Common/BibleVerses.cs @@ -0,0 +1,7 @@ +namespace NadekoBot.Modules.Searches; + +public class BibleVerses +{ + public string? Error { get; set; } + public BibleVerse[]? Verses { get; set; } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Religious/Common/QuranAyah.cs b/src/NadekoBot/Modules/Searches/Religious/Common/QuranAyah.cs new file mode 100644 index 000000000..cd83f3332 --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/Common/QuranAyah.cs @@ -0,0 +1,20 @@ +#nullable disable + +using System.Text.Json.Serialization; + +namespace NadekoBot.Modules.Searches; + +public sealed class QuranAyah +{ + [JsonPropertyName("number")] + public int Number { get; set; } + + [JsonPropertyName("audio")] + public string Audio { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("text")] + public string Text { get; set; } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Religious/Common/QuranResponse.cs b/src/NadekoBot/Modules/Searches/Religious/Common/QuranResponse.cs new file mode 100644 index 000000000..582981432 --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/Common/QuranResponse.cs @@ -0,0 +1,15 @@ +using System.Text.Json.Serialization; + +namespace NadekoBot.Modules.Searches; + +public sealed class QuranResponse +{ + [JsonPropertyName("code")] + public required int Code { get; set; } + + [JsonPropertyName("status")] + public required string Status { get; set; } + + [JsonPropertyName("data")] + public required T[] Data { get; set; } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Religious/ReligiousApiService.cs b/src/NadekoBot/Modules/Searches/Religious/ReligiousApiService.cs new file mode 100644 index 000000000..c66f2877a --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/ReligiousApiService.cs @@ -0,0 +1,63 @@ +using NadekoBot.Modules.Searches.Common; +using OneOf; +using OneOf.Types; +using System.Net; +using System.Net.Http.Json; + +namespace NadekoBot.Modules.Searches; + +public sealed class ReligiousApiService : INService +{ + private readonly IHttpClientFactory _httpFactory; + + public ReligiousApiService(IHttpClientFactory httpFactory) + { + _httpFactory = httpFactory; + } + + public async Task>> GetBibleVerseAsync(string book, string chapterAndVerse) + { + if (string.IsNullOrWhiteSpace(book) || string.IsNullOrWhiteSpace(chapterAndVerse)) + return new Error("Invalid input."); + + + book = Uri.EscapeDataString(book); + chapterAndVerse = Uri.EscapeDataString(chapterAndVerse); + + using var http = _httpFactory.CreateClient(); + try + { + var res = await http.GetFromJsonAsync($"https://bible-api.com/{book} {chapterAndVerse}"); + + if (res is null || res.Error is not null || res.Verses is null || res.Verses.Length == 0) + { + return new Error(res?.Error ?? "No verse found."); + } + + return res.Verses[0]; + } + catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound) + { + return new Error("No verse found."); + } + } + + public async Task, Error>> GetQuranVerseAsync(string ayah) + { + if (string.IsNullOrWhiteSpace(ayah)) + return new Error(strs.invalid_input); + + ayah = Uri.EscapeDataString(ayah); + + using var http = _httpFactory.CreateClient(); + var res = await http.GetFromJsonAsync>( + $"https://api.alquran.cloud/v1/ayah/{ayah}/editions/en.asad,ar.alafasy"); + + if (res is null or not { Code: 200 }) + { + return new Error(strs.not_found); + } + + return res; + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/Religious/ReligiousCommands.cs b/src/NadekoBot/Modules/Searches/Religious/ReligiousCommands.cs new file mode 100644 index 000000000..791ab008a --- /dev/null +++ b/src/NadekoBot/Modules/Searches/Religious/ReligiousCommands.cs @@ -0,0 +1,60 @@ +namespace NadekoBot.Modules.Searches; + +public partial class Searches +{ + public partial class ReligiousCommands : NadekoModule + { + private readonly IHttpClientFactory _httpFactory; + + public ReligiousCommands(IHttpClientFactory httpFactory) + => _httpFactory = httpFactory; + + [Cmd] + [RequireContext(ContextType.Guild)] + public async Task Bible(string book, string chapterAndVerse) + { + var res = await _service.GetBibleVerseAsync(book, chapterAndVerse); + + if (!res.TryPickT0(out var verse, out var error)) + { + await Response().Error(error.Value).SendAsync(); + return; + } + + await Response() + .Embed(_sender.CreateEmbed() + .WithOkColor() + .WithTitle($"{verse.BookName} {verse.Chapter}:{verse.Verse}") + .WithDescription(verse.Text)) + .SendAsync(); + } + + [Cmd] + [RequireContext(ContextType.Guild)] + public async Task Quran(string ayah) + { + var res = await _service.GetQuranVerseAsync(ayah); + + if (!res.TryPickT0(out var qr, out var error)) + { + await Response().Error(error.Value).SendAsync(); + return; + } + + var english = qr.Data[0]; + var arabic = qr.Data[1]; + + using var http = _httpFactory.CreateClient(); + await using var audio = await http.GetStreamAsync(arabic.Audio); + + await Response() + .Embed(_sender.CreateEmbed() + .WithOkColor() + .AddField("Arabic", arabic.Text) + .AddField("English", english.Text) + .WithFooter(arabic.Number.ToString())) + .File(audio, Uri.EscapeDataString(ayah) + ".mp3") + .SendAsync(); + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/ReligiousCommands.cs b/src/NadekoBot/Modules/Searches/ReligiousCommands.cs deleted file mode 100644 index ae8cd250d..000000000 --- a/src/NadekoBot/Modules/Searches/ReligiousCommands.cs +++ /dev/null @@ -1,102 +0,0 @@ -using NadekoBot.Modules.Searches.Common; -using System.Net.Http.Json; -using System.Text.Json.Serialization; - -namespace NadekoBot.Modules.Searches; - -public partial class Searches -{ - public partial class ReligiousCommands : NadekoModule - { - private readonly IHttpClientFactory _httpFactory; - - public ReligiousCommands(IHttpClientFactory httpFactory) - { - _httpFactory = httpFactory; - } - - [Cmd] - [RequireContext(ContextType.Guild)] - public async Task Bible(string book, string chapterAndVerse) - { - var obj = new BibleVerses(); - try - { - using var http = _httpFactory.CreateClient(); - obj = await http.GetFromJsonAsync($"https://bible-api.com/{book} {chapterAndVerse}"); - } - catch - { - } - - if (obj.Error is not null || obj.Verses is null || obj.Verses.Length == 0) - await Response().Error(obj.Error ?? "No verse found.").SendAsync(); - else - { - var v = obj.Verses[0]; - await Response() - .Embed(_sender.CreateEmbed() - .WithOkColor() - .WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}") - .WithDescription(v.Text)) - .SendAsync(); - } - } - - [Cmd] - [RequireContext(ContextType.Guild)] - public async Task Quran(string ayah) - { - using var http = _httpFactory.CreateClient(); - - var obj = await http.GetFromJsonAsync>($"https://api.alquran.cloud/v1/ayah/{Uri.EscapeDataString(ayah)}/editions/en.asad,ar.alafasy"); - if(obj is null or not { Code: 200 }) - { - await Response().Error("No verse found.").SendAsync(); - return; - } - - var english = obj.Data[0]; - var arabic = obj.Data[1]; - - await using var audio = await http.GetStreamAsync(arabic.Audio); - - await Response() - .Embed(_sender.CreateEmbed() - .WithOkColor() - .AddField("Arabic", arabic.Text) - .AddField("English", english.Text) - .WithFooter(arabic.Number.ToString())) - .File(audio, Uri.EscapeDataString(ayah) + ".mp3") - .SendAsync(); - } - } -} - -public sealed class QuranResponse -{ - [JsonPropertyName("code")] - public int Code { get; set; } - - [JsonPropertyName("status")] - public string Status { get; set; } - - [JsonPropertyName("data")] - public T[] Data { get; set; } -} - -public sealed class QuranAyah -{ - [JsonPropertyName("number")] - public int Number { get; set; } - - [JsonPropertyName("audio")] - public string Audio { get; set; } - - [JsonPropertyName("name")] - public string Name { get; set; } - - [JsonPropertyName("text")] - public string Text { get; set; } - -} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Searches/_common/BibleVerses.cs b/src/NadekoBot/Modules/Searches/_common/BibleVerses.cs deleted file mode 100644 index 5b5509239..000000000 --- a/src/NadekoBot/Modules/Searches/_common/BibleVerses.cs +++ /dev/null @@ -1,21 +0,0 @@ -#nullable disable - -using System.Text.Json.Serialization; - -namespace NadekoBot.Modules.Searches.Common; - -public class BibleVerses -{ - public string Error { get; set; } - public BibleVerse[] Verses { get; set; } -} - -public class BibleVerse -{ - [JsonPropertyName("book_name")] - public string BookName { get; set; } - - public int Chapter { get; set; } - public int Verse { get; set; } - public string Text { get; set; } -} \ No newline at end of file