.define slightly improved and refactored
This commit is contained in:
parent
fe5c8622dd
commit
3e73dc8ba5
3 changed files with 100 additions and 64 deletions
|
@ -327,49 +327,18 @@ public partial class Searches : EllieModule<SearchesService>
|
|||
if (!await ValidateQuery(word))
|
||||
return;
|
||||
|
||||
using var http = _httpFactory.CreateClient();
|
||||
string res;
|
||||
try
|
||||
{
|
||||
res = await _cache.GetOrCreateAsync($"define_{word}",
|
||||
e =>
|
||||
{
|
||||
e.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
|
||||
return http.GetStringAsync("https://api.pearson.com/v2/dictionaries/entries?headword="
|
||||
+ WebUtility.UrlEncode(word));
|
||||
});
|
||||
|
||||
var responseModel = JsonConvert.DeserializeObject<DefineModel>(res);
|
||||
var maybeItems = await _service.GetDefinitionsAsync(word);
|
||||
|
||||
var data = responseModel.Results
|
||||
.Where(x => x.Senses is not null
|
||||
&& x.Senses.Count > 0
|
||||
&& x.Senses[0].Definition is not null)
|
||||
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech))
|
||||
.ToList();
|
||||
|
||||
if (!data.Any())
|
||||
if (!maybeItems.TryPickT0(out var defs, out var error))
|
||||
{
|
||||
Log.Warning("Definition not found: {Word}", word);
|
||||
await Response().Error(strs.define_unknown).SendAsync();
|
||||
await HandleErrorAsync(error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var col = data.Select(x => (
|
||||
Definition: x.Sense.Definition is string
|
||||
? x.Sense.Definition.ToString()
|
||||
: ((JArray)JToken.Parse(x.Sense.Definition.ToString())).First.ToString(),
|
||||
Example: x.Sense.Examples is null || x.Sense.Examples.Count == 0
|
||||
? string.Empty
|
||||
: x.Sense.Examples[0].Text, Word: word,
|
||||
WordType: string.IsNullOrWhiteSpace(x.PartOfSpeech) ? "-" : x.PartOfSpeech))
|
||||
.ToList();
|
||||
|
||||
Log.Information("Sending {Count} definition for: {Word}", col.Count, word);
|
||||
|
||||
await Response()
|
||||
.Paginated()
|
||||
.Items(col)
|
||||
.Items(defs)
|
||||
.PageSize(1)
|
||||
.Page((items, _) =>
|
||||
{
|
||||
|
@ -388,11 +357,6 @@ public partial class Searches : EllieModule<SearchesService>
|
|||
})
|
||||
.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error retrieving definition data for: {Word}", word);
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
public async Task Catfact()
|
||||
|
|
|
@ -399,7 +399,7 @@ public class SearchesService : IEService
|
|||
return gamesMap[key];
|
||||
}
|
||||
|
||||
public async Task<OneOf.OneOf<WikipediaReply, ErrorType>> GetWikipediaPageAsync(string query)
|
||||
public async Task<OneOf<WikipediaReply, ErrorType>> GetWikipediaPageAsync(string query)
|
||||
{
|
||||
query = query.Trim();
|
||||
if (string.IsNullOrEmpty(query))
|
||||
|
@ -516,4 +516,66 @@ public class SearchesService : IEService
|
|||
return ErrorType.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static TypedKey<string> GetDefineKey(string query)
|
||||
=> new TypedKey<string>($"define_{query}");
|
||||
|
||||
public async Task<OneOf<List<DefineData>, ErrorType>> GetDefinitionsAsync(string query)
|
||||
{
|
||||
if (string.IsNullOrEmpty(query))
|
||||
{
|
||||
return ErrorType.InvalidInput;
|
||||
}
|
||||
|
||||
query = Uri.EscapeDataString(query);
|
||||
|
||||
using var http = _httpFactory.CreateClient();
|
||||
string res;
|
||||
try
|
||||
{
|
||||
res = await _c.GetOrAddAsync(GetDefineKey(query),
|
||||
async () => await http.GetStringAsync(
|
||||
$"https://api.pearson.com/v2/dictionaries/entries?headword={query}"),
|
||||
TimeSpan.FromHours(12));
|
||||
|
||||
var responseModel = JsonConvert.DeserializeObject<DefineModel>(res);
|
||||
|
||||
var data = responseModel.Results
|
||||
.Where(x => x.Senses is not null
|
||||
&& x.Senses.Count > 0
|
||||
&& x.Senses[0].Definition is not null)
|
||||
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech))
|
||||
.ToList();
|
||||
|
||||
if (!data.Any())
|
||||
{
|
||||
Log.Warning("Definition not found: {Word}", query);
|
||||
return ErrorType.NotFound;
|
||||
}
|
||||
|
||||
var items = new List<DefineData>();
|
||||
|
||||
foreach (var d in data)
|
||||
{
|
||||
items.Add(new DefineData
|
||||
{
|
||||
Definition = d.Sense.Definition is JArray { Count: > 0 } defs
|
||||
? defs[0].ToString()
|
||||
: d.Sense.Definition.ToString(),
|
||||
Example = d.Sense.Examples is null || d.Sense.Examples.Count == 0
|
||||
? string.Empty
|
||||
: d.Sense.Examples[0].Text,
|
||||
WordType = string.IsNullOrWhiteSpace(d.PartOfSpeech) ? "-" : d.PartOfSpeech,
|
||||
Word = query,
|
||||
});
|
||||
}
|
||||
|
||||
return items.OrderByDescending(x => !string.IsNullOrWhiteSpace(x.Example)).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error retrieving definition data for: {Word}", query);
|
||||
return ErrorType.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
10
src/EllieBot/Modules/Searches/_common/DefineData.cs
Normal file
10
src/EllieBot/Modules/Searches/_common/DefineData.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
#nullable disable
|
||||
namespace EllieBot.Modules.Searches.Services;
|
||||
|
||||
public sealed class DefineData
|
||||
{
|
||||
public required string Definition { get; init; }
|
||||
public required string Example { get; init; }
|
||||
public required string WordType { get; init; }
|
||||
public required string Word { get; init; }
|
||||
}
|
Loading…
Reference in a new issue