.define slightly improved and refactored
This commit is contained in:
parent
fe5c8622dd
commit
3e73dc8ba5
3 changed files with 100 additions and 64 deletions
|
@ -327,71 +327,35 @@ public partial class Searches : EllieModule<SearchesService>
|
||||||
if (!await ValidateQuery(word))
|
if (!await ValidateQuery(word))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
using var http = _httpFactory.CreateClient();
|
|
||||||
string res;
|
var maybeItems = await _service.GetDefinitionsAsync(word);
|
||||||
try
|
|
||||||
|
if (!maybeItems.TryPickT0(out var defs, out var error))
|
||||||
{
|
{
|
||||||
res = await _cache.GetOrCreateAsync($"define_{word}",
|
await HandleErrorAsync(error);
|
||||||
e =>
|
return;
|
||||||
{
|
|
||||||
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 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}", word);
|
|
||||||
await Response().Error(strs.define_unknown).SendAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
.PageSize(1)
|
|
||||||
.Page((items, _) =>
|
|
||||||
{
|
|
||||||
var model = items.First();
|
|
||||||
var embed = _sender.CreateEmbed()
|
|
||||||
.WithDescription(ctx.User.Mention)
|
|
||||||
.AddField(GetText(strs.word), model.Word, true)
|
|
||||||
.AddField(GetText(strs._class), model.WordType, true)
|
|
||||||
.AddField(GetText(strs.definition), model.Definition)
|
|
||||||
.WithOkColor();
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(model.Example))
|
|
||||||
embed.AddField(GetText(strs.example), model.Example);
|
|
||||||
|
|
||||||
return embed;
|
|
||||||
})
|
|
||||||
.SendAsync();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error retrieving definition data for: {Word}", word);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Response()
|
||||||
|
.Paginated()
|
||||||
|
.Items(defs)
|
||||||
|
.PageSize(1)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var model = items.First();
|
||||||
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithDescription(ctx.User.Mention)
|
||||||
|
.AddField(GetText(strs.word), model.Word, true)
|
||||||
|
.AddField(GetText(strs._class), model.WordType, true)
|
||||||
|
.AddField(GetText(strs.definition), model.Definition)
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(model.Example))
|
||||||
|
embed.AddField(GetText(strs.example), model.Example);
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
})
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
|
|
@ -399,7 +399,7 @@ public class SearchesService : IEService
|
||||||
return gamesMap[key];
|
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();
|
query = query.Trim();
|
||||||
if (string.IsNullOrEmpty(query))
|
if (string.IsNullOrEmpty(query))
|
||||||
|
@ -516,4 +516,66 @@ public class SearchesService : IEService
|
||||||
return ErrorType.Unknown;
|
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