Finished new response system

This commit is contained in:
Kwoth
2024-05-02 06:47:01 +00:00
parent a25adefc65
commit fc4858830c
102 changed files with 1811 additions and 1818 deletions

View File

@@ -24,7 +24,7 @@ public partial class Searches
// return;
// }
//
// var embed = new EmbedBuilder()
// var embed = _sender.CreateEmbed()
// .WithOkColor()
// .WithDescription(novelData.Description.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
// .WithTitle(novelData.Title)
@@ -86,7 +86,7 @@ public partial class Searches
.Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
.ToArray();
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.mal_profile(name)))
.AddField("💚 " + GetText(strs.watching), stats[0], true)
@@ -151,7 +151,7 @@ public partial class Searches
return;
}
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithDescription(animeData.Synopsis.Replace("<br>",
Environment.NewLine,
@@ -183,7 +183,7 @@ public partial class Searches
return;
}
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithDescription(mangaData.Synopsis.Replace("<br>",
Environment.NewLine,

View File

@@ -35,7 +35,7 @@ public partial class Searches
}
var symbol = symbols.First();
var promptEmbed = new EmbedBuilder()
var promptEmbed = _sender.CreateEmbed()
.WithDescription(symbol.Description)
.WithTitle(GetText(strs.did_you_mean(symbol.Symbol)));
@@ -79,7 +79,7 @@ public partial class Searches
var price = stock.Price.ToString("C2", localCulture);
var eb = new EmbedBuilder()
var eb = _sender.CreateEmbed()
.WithOkColor()
.WithAuthor(stock.Symbol)
.WithUrl($"https://www.tradingview.com/chart/?symbol={stock.Symbol}")
@@ -127,7 +127,7 @@ public partial class Searches
if (nearest is not null)
{
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithTitle(GetText(strs.crypto_not_found))
.WithDescription(
GetText(strs.did_you_mean(Format.Bold($"{nearest.Name} ({nearest.Symbol})"))));
@@ -160,7 +160,7 @@ public partial class Searches
await using var sparkline = await _service.GetSparklineAsync(crypto.Id, usd.PercentChange7d >= 0);
var fileName = $"{crypto.Slug}_7d.png";
var toSend = new EmbedBuilder()
var toSend = _sender.CreateEmbed()
.WithOkColor()
.WithAuthor($"#{crypto.CmcRank}")
.WithTitle($"{crypto.Name} ({crypto.Symbol})")

View File

@@ -111,28 +111,36 @@ public partial class Searches
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageMessages)]
public async Task FeedList()
public async Task FeedList(int page = 1)
{
if (--page < 0)
return;
var feeds = _service.GetFeeds(ctx.Guild.Id);
if (!feeds.Any())
{
await Response().Embed(new EmbedBuilder().WithOkColor().WithDescription(GetText(strs.feed_no_feed))).SendAsync();
await Response()
.Embed(_sender.CreateEmbed().WithOkColor().WithDescription(GetText(strs.feed_no_feed)))
.SendAsync();
return;
}
await ctx.SendPaginatedConfirmAsync(0,
cur =>
{
var embed = new EmbedBuilder().WithOkColor();
var i = 0;
var fs = string.Join("\n",
feeds.Skip(cur * 10).Take(10).Select(x => $"`{(cur * 10) + ++i}.` <#{x.ChannelId}> {x.Url}"));
return embed.WithDescription(fs);
},
feeds.Count,
10);
await Response()
.Paginated()
.Items(feeds)
.PageSize(10)
.CurrentPage(page)
.Page((items, cur) =>
{
var embed = _sender.CreateEmbed().WithOkColor();
var i = 0;
var fs = string.Join("\n",
items.Select(x => $"`{(cur * 10) + ++i}.` <#{x.ChannelId}> {x.Url}"));
return embed.WithDescription(fs);
})
.SendAsync();
}
}
}

View File

@@ -31,14 +31,14 @@ public class FeedsService : INService
{
var guildConfigIds = bot.AllGuildConfigs.Select(x => x.Id).ToList();
_subs = uow.Set<GuildConfig>()
.AsQueryable()
.Where(x => guildConfigIds.Contains(x.Id))
.Include(x => x.FeedSubs)
.ToList()
.SelectMany(x => x.FeedSubs)
.GroupBy(x => x.Url.ToLower())
.ToDictionary(x => x.Key, x => x.ToList())
.ToConcurrent();
.AsQueryable()
.Where(x => guildConfigIds.Contains(x.Id))
.Include(x => x.FeedSubs)
.ToList()
.SelectMany(x => x.FeedSubs)
.GroupBy(x => x.Url.ToLower())
.ToDictionary(x => x.Key, x => x.ToList())
.ToConcurrent();
}
_client = client;
@@ -61,7 +61,7 @@ public class FeedsService : INService
// remove from db
await using var ctx = _db.GetDbContext();
await ctx.GetTable<FeedSub>()
.DeleteAsync(x => ids.Contains(x.Id));
.DeleteAsync(x => ids.Contains(x.Id));
// remove from the local cache
_subs.TryRemove(url, out _);
@@ -95,14 +95,14 @@ public class FeedsService : INService
var feed = await FeedReader.ReadAsync(rssUrl);
var items = feed
.Items.Select(item => (Item: item,
LastUpdate: item.PublishingDate?.ToUniversalTime()
?? (item.SpecificItem as AtomFeedItem)?.UpdatedDate?.ToUniversalTime()))
.Where(data => data.LastUpdate is not null)
.Select(data => (data.Item, LastUpdate: (DateTime)data.LastUpdate))
.OrderByDescending(data => data.LastUpdate)
.Reverse() // start from the oldest
.ToList();
.Items.Select(item => (Item: item,
LastUpdate: item.PublishingDate?.ToUniversalTime()
?? (item.SpecificItem as AtomFeedItem)?.UpdatedDate?.ToUniversalTime()))
.Where(data => data.LastUpdate is not null)
.Select(data => (data.Item, LastUpdate: (DateTime)data.LastUpdate))
.OrderByDescending(data => data.LastUpdate)
.Reverse() // start from the oldest
.ToList();
if (!_lastPosts.TryGetValue(kvp.Key, out var lastFeedUpdate))
{
@@ -115,7 +115,7 @@ public class FeedsService : INService
if (itemUpdateDate <= lastFeedUpdate)
continue;
var embed = new EmbedBuilder().WithFooter(rssUrl);
var embed = _sender.CreateEmbed().WithFooter(rssUrl);
_lastPosts[kvp.Key] = itemUpdateDate;
@@ -141,12 +141,12 @@ public class FeedsService : INService
if (!gotImage && feedItem.SpecificItem is AtomFeedItem afi)
{
var previewElement = afi.Element.Elements()
.FirstOrDefault(x => x.Name.LocalName == "preview");
.FirstOrDefault(x => x.Name.LocalName == "preview");
if (previewElement is null)
{
previewElement = afi.Element.Elements()
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
}
if (previewElement is not null)
@@ -170,11 +170,23 @@ public class FeedsService : INService
//send the created embed to all subscribed channels
var feedSendTasks = kvp.Value
.Where(x => x.GuildConfig is not null)
.Select(x => _client.GetGuild(x.GuildConfig.GuildId)
?.GetTextChannel(x.ChannelId)
?.EmbedAsync(embed, string.IsNullOrWhiteSpace(x.Message) ? "" : x.Message))
.Where(x => x is not null);
.Where(x => x.GuildConfig is not null)
.Select(x =>
{
var ch = _client.GetGuild(x.GuildConfig.GuildId)
?.GetTextChannel(x.ChannelId);
if (ch is null)
return null;
return _sender.Response(ch)
.Embed(embed)
.Text(string.IsNullOrWhiteSpace(x.Message)
? string.Empty
: x.Message)
.SendAsync();
})
.Where(x => x is not null);
allSendTasks.Add(feedSendTasks.WhenAll());
@@ -202,11 +214,15 @@ public class FeedsService : INService
{
using var uow = _db.GetDbContext();
return uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
.FeedSubs.OrderBy(x => x.Id)
.ToList();
.FeedSubs.OrderBy(x => x.Id)
.ToList();
}
public FeedAddResult AddFeed(ulong guildId, ulong channelId, string rssFeed, string message)
public FeedAddResult AddFeed(
ulong guildId,
ulong channelId,
string rssFeed,
string message)
{
ArgumentNullException.ThrowIfNull(rssFeed, nameof(rssFeed));
@@ -252,8 +268,8 @@ public class FeedsService : INService
using var uow = _db.GetDbContext();
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
.FeedSubs.OrderBy(x => x.Id)
.ToList();
.FeedSubs.OrderBy(x => x.Id)
.ToList();
if (items.Count <= index)
return false;

View File

@@ -40,18 +40,21 @@ public partial class Searches
var data = JsonConvert.DeserializeObject<List<MemegenTemplate>>(rawJson)!;
await ctx.SendPaginatedConfirmAsync(page,
curPage =>
{
var templates = string.Empty;
foreach (var template in data.Skip(curPage * 15).Take(15))
templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
var embed = new EmbedBuilder().WithOkColor().WithDescription(templates);
await Response()
.Paginated()
.Items(data)
.PageSize(15)
.CurrentPage(page)
.Page((items, curPage) =>
{
var templates = string.Empty;
foreach (var template in items)
templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
var embed = _sender.CreateEmbed().WithOkColor().WithDescription(templates);
return embed;
},
data.Count,
15);
return embed;
})
.SendAsync();
}
[Cmd]

View File

@@ -49,7 +49,7 @@ public partial class Searches
var obj = objs[0];
var userId = obj.UserId;
await Response().Embed(new EmbedBuilder()
await Response().Embed(_sender.CreateEmbed()
.WithOkColor()
.WithTitle($"osu! {smode} profile for {user}")
.WithThumbnailUrl($"https://a.ppy.sh/{userId}")
@@ -95,7 +95,7 @@ public partial class Searches
var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
var userStats = statsResponse.Stats;
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithTitle($"osu!Gatari {modeStr} profile for {user}")
.WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
@@ -166,7 +166,7 @@ public partial class Searches
return (title, desc);
});
var eb = new EmbedBuilder().WithOkColor().WithTitle($"Top 5 plays for {user}");
var eb = _sender.CreateEmbed().WithOkColor().WithTitle($"Top 5 plays for {user}");
var mapData = await mapTasks.WhenAll();
foreach (var (title, desc) in mapData.Where(x => x != default))

View File

@@ -135,7 +135,7 @@ public partial class Searches
}
catch
{
var embed = new EmbedBuilder().WithDescription(GetText(strs.account_not_found)).WithErrorColor();
var embed = _sender.CreateEmbed().WithDescription(GetText(strs.account_not_found)).WithErrorColor();
await Response().Embed(embed).SendAsync();
return;
@@ -144,37 +144,38 @@ public partial class Searches
if (!string.IsNullOrWhiteSpace(league))
characters.RemoveAll(c => c.League != league);
await ctx.SendPaginatedConfirmAsync(page,
curPage =>
{
var embed = new EmbedBuilder()
.WithAuthor($"Characters on {usr}'s account",
"https://web.poecdn.com/image/favicon/ogimage.png",
$"{PROFILE_URL}{usr}")
.WithOkColor();
await Response()
.Paginated()
.Items(characters)
.PageSize(9)
.CurrentPage(page)
.Page((items, curPage) =>
{
var embed = _sender.CreateEmbed()
.WithAuthor($"Characters on {usr}'s account",
"https://web.poecdn.com/image/favicon/ogimage.png",
$"{PROFILE_URL}{usr}")
.WithOkColor();
var tempList = characters.Skip(curPage * 9).Take(9).ToList();
if (characters.Count == 0)
return embed.WithDescription("This account has no characters.");
if (characters.Count == 0)
return embed.WithDescription("This account has no characters.");
var sb = new StringBuilder();
sb.AppendLine($"```{"#",-5}{"Character Name",-23}{"League",-10}{"Class",-13}{"Level",-3}");
for (var i = 0; i < items.Count; i++)
{
var character = items[i];
var sb = new StringBuilder();
sb.AppendLine($"```{"#",-5}{"Character Name",-23}{"League",-10}{"Class",-13}{"Level",-3}");
for (var i = 0; i < tempList.Count; i++)
{
var character = tempList[i];
sb.AppendLine(
$"#{i + 1 + (curPage * 9),-4}{character.Name,-23}{ShortLeagueName(character.League),-10}{character.Class,-13}{character.Level,-3}");
}
sb.AppendLine(
$"#{i + 1 + (curPage * 9),-4}{character.Name,-23}{ShortLeagueName(character.League),-10}{character.Class,-13}{character.Level,-3}");
}
sb.AppendLine("```");
embed.WithDescription(sb.ToString());
sb.AppendLine("```");
embed.WithDescription(sb.ToString());
return embed;
},
characters.Count,
9);
return embed;
})
.SendAsync();
}
[Cmd]
@@ -190,17 +191,17 @@ public partial class Searches
}
catch
{
var eembed = new EmbedBuilder().WithDescription(GetText(strs.leagues_not_found)).WithErrorColor();
var eembed = _sender.CreateEmbed().WithDescription(GetText(strs.leagues_not_found)).WithErrorColor();
await Response().Embed(eembed).SendAsync();
return;
}
var embed = new EmbedBuilder()
.WithAuthor("Path of Exile Leagues",
"https://web.poecdn.com/image/favicon/ogimage.png",
"https://www.pathofexile.com")
.WithOkColor();
var embed = _sender.CreateEmbed()
.WithAuthor("Path of Exile Leagues",
"https://web.poecdn.com/image/favicon/ogimage.png",
"https://www.pathofexile.com")
.WithOkColor();
var sb = new StringBuilder();
sb.AppendLine($"```{"#",-5}{"League Name",-23}");
@@ -273,19 +274,19 @@ public partial class Searches
CultureInfo.InvariantCulture);
}
var embed = new EmbedBuilder()
.WithAuthor($"{leagueName} Currency Exchange",
"https://web.poecdn.com/image/favicon/ogimage.png",
"http://poe.ninja")
.AddField("Currency Type", cleanCurrency, true)
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
.WithOkColor();
var embed = _sender.CreateEmbed()
.WithAuthor($"{leagueName} Currency Exchange",
"https://web.poecdn.com/image/favicon/ogimage.png",
"http://poe.ninja")
.AddField("Currency Type", cleanCurrency, true)
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
.WithOkColor();
await Response().Embed(embed).SendAsync();
}
catch
{
var embed = new EmbedBuilder().WithDescription(GetText(strs.ninja_not_found)).WithErrorColor();
var embed = _sender.CreateEmbed().WithDescription(GetText(strs.ninja_not_found)).WithErrorColor();
await Response().Embed(embed).SendAsync();
}

View File

@@ -25,7 +25,7 @@ public partial class Searches
if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
{
var p = kvp.Value;
await Response().Embed(new EmbedBuilder()
await Response().Embed(_sender.CreateEmbed()
.WithOkColor()
.WithTitle(kvp.Key.ToTitleCase())
.WithDescription(p.BaseStats.ToString())
@@ -55,7 +55,7 @@ public partial class Searches
{
if (kvp.Key.ToUpperInvariant() == ability)
{
await Response().Embed(new EmbedBuilder()
await Response().Embed(_sender.CreateEmbed()
.WithOkColor()
.WithTitle(kvp.Value.Name)
.WithDescription(string.IsNullOrWhiteSpace(kvp.Value.Desc)

View File

@@ -59,7 +59,7 @@ public partial class Searches
descStr = descStr.TrimTo(4096);
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithAuthor(ctx.User)
.WithTitle(query.TrimTo(64)!)
@@ -98,7 +98,7 @@ public partial class Searches
EmbedBuilder CreateEmbed(IImageSearchResultEntry entry)
{
return new EmbedBuilder()
return _sender.CreateEmbed()
.WithOkColor()
.WithAuthor(ctx.User)
.WithTitle(query)
@@ -190,7 +190,7 @@ public partial class Searches
//
// var descStr = string.Join("\n\n", desc);
//
// var embed = new EmbedBuilder()
// var embed = _sender.CreateEmbed()
// .WithAuthor(ctx.User.ToString(),
// "https://upload.wikimedia.org/wikipedia/en/9/90/The_DuckDuckGo_Duck.png")
// .WithDescription($"{GetText(strs.search_for)} **{query}**\n\n" + descStr)

View File

@@ -54,7 +54,7 @@ public partial class Searches : NadekoModule<SearchesService>
if (!await ValidateQuery(query))
return;
var embed = new EmbedBuilder();
var embed = _sender.CreateEmbed();
var data = await _service.GetWeatherDataAsync(query);
if (data is null)
@@ -134,7 +134,7 @@ public partial class Searches : NadekoModule<SearchesService>
return;
}
var eb = new EmbedBuilder()
var eb = _sender.CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.time_new))
.WithDescription(Format.Code(data.Time.ToString(Culture)))
@@ -160,7 +160,7 @@ public partial class Searches : NadekoModule<SearchesService>
}
await Response()
.Embed(new EmbedBuilder()
.Embed(_sender.CreateEmbed()
.WithOkColor()
.WithTitle(movie.Title)
.WithUrl($"https://www.imdb.com/title/{movie.ImdbId}/")
@@ -191,7 +191,7 @@ public partial class Searches : NadekoModule<SearchesService>
private Task InternalRandomImage(SearchesService.ImageTag tag)
{
var url = _service.GetRandomImageUrl(tag);
return Response().Embed(new EmbedBuilder().WithOkColor().WithImageUrl(url)).SendAsync();
return Response().Embed(_sender.CreateEmbed().WithOkColor().WithImageUrl(url)).SendAsync();
}
[Cmd]
@@ -242,7 +242,7 @@ public partial class Searches : NadekoModule<SearchesService>
}
await Response()
.Embed(new EmbedBuilder()
.Embed(_sender.CreateEmbed()
.WithOkColor()
.AddField(GetText(strs.original_url), $"<{query}>")
.AddField(GetText(strs.short_url), $"<{shortLink}>"))
@@ -264,7 +264,7 @@ public partial class Searches : NadekoModule<SearchesService>
return;
}
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithTitle(card.Name)
.WithDescription(card.Description)
@@ -297,7 +297,7 @@ public partial class Searches : NadekoModule<SearchesService>
return;
}
var embed = new EmbedBuilder().WithOkColor().WithImageUrl(card.Img);
var embed = _sender.CreateEmbed().WithOkColor().WithImageUrl(card.Img);
if (!string.IsNullOrWhiteSpace(card.Flavor))
embed.WithDescription(card.Flavor);
@@ -318,21 +318,24 @@ public partial class Searches : NadekoModule<SearchesService>
$"https://api.urbandictionary.com/v0/define?term={Uri.EscapeDataString(query)}");
try
{
var items = JsonConvert.DeserializeObject<UrbanResponse>(res).List;
if (items.Any())
var allItems = JsonConvert.DeserializeObject<UrbanResponse>(res).List;
if (allItems.Any())
{
await ctx.SendPaginatedConfirmAsync(0,
p =>
{
var item = items[p];
return new EmbedBuilder()
.WithOkColor()
.WithUrl(item.Permalink)
.WithTitle(item.Word)
.WithDescription(item.Definition);
},
items.Length,
1);
await Response()
.Paginated()
.Items(allItems)
.PageSize(1)
.CurrentPage(0)
.Page((items, _) =>
{
var item = items[0];
return _sender.CreateEmbed()
.WithOkColor()
.WithUrl(item.Permalink)
.WithTitle(item.Word)
.WithDescription(item.Definition);
})
.SendAsync();
return;
}
}
@@ -362,52 +365,54 @@ public partial class Searches : NadekoModule<SearchesService>
+ WebUtility.UrlEncode(word));
});
var data = JsonConvert.DeserializeObject<DefineModel>(res);
var responseModel = JsonConvert.DeserializeObject<DefineModel>(res);
var datas = data.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();
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 (!datas.Any())
if (!data.Any())
{
Log.Warning("Definition not found: {Word}", word);
await Response().Error(strs.define_unknown).SendAsync();
}
var col = datas.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();
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 ctx.SendPaginatedConfirmAsync(0,
page =>
{
var model = col.Skip(page).First();
var embed = new EmbedBuilder()
.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();
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);
if (!string.IsNullOrWhiteSpace(model.Example))
embed.AddField(GetText(strs.example), model.Example);
return embed;
},
col.Count,
1);
return embed;
})
.SendAsync();
}
catch (Exception ex)
{
@@ -474,7 +479,7 @@ public partial class Searches : NadekoModule<SearchesService>
await Response()
.Embed(
new EmbedBuilder()
_sender.CreateEmbed()
.WithOkColor()
.AddField("Username", usr.ToString())
.AddField("Avatar Url", avatarUrl)
@@ -542,7 +547,7 @@ public partial class Searches : NadekoModule<SearchesService>
{
var v = obj.Verses[0];
await Response()
.Embed(new EmbedBuilder()
.Embed(_sender.CreateEmbed()
.WithOkColor()
.WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}")
.WithDescription(v.Text))
@@ -565,7 +570,7 @@ public partial class Searches : NadekoModule<SearchesService>
return;
}
//var embed = new EmbedBuilder()
//var embed = _sender.CreateEmbed()
// .WithOkColor()
// .WithDescription(gameData.ShortDescription)
// .WithTitle(gameData.Name)

View File

@@ -95,9 +95,9 @@ public partial class Searches
.Page((elements, cur) =>
{
if (elements.Count == 0)
return new EmbedBuilder().WithDescription(GetText(strs.streams_none)).WithErrorColor();
return _sender.CreateEmbed().WithDescription(GetText(strs.streams_none)).WithErrorColor();
var eb = new EmbedBuilder().WithTitle(GetText(strs.streams_follow_title)).WithOkColor();
var eb = _sender.CreateEmbed().WithTitle(GetText(strs.streams_follow_title)).WithOkColor();
for (var index = 0; index < elements.Count; index++)
{
var elem = elements[index];

View File

@@ -73,34 +73,34 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
{
var ids = client.GetGuildIds();
var guildConfigs = uow.Set<GuildConfig>()
.AsQueryable()
.Include(x => x.FollowedStreams)
.Where(x => ids.Contains(x.GuildId))
.ToList();
.AsQueryable()
.Include(x => x.FollowedStreams)
.Where(x => ids.Contains(x.GuildId))
.ToList();
_offlineNotificationServers = new(guildConfigs
.Where(gc => gc.NotifyStreamOffline)
.Select(x => x.GuildId)
.ToList());
.Where(gc => gc.NotifyStreamOffline)
.Select(x => x.GuildId)
.ToList());
_deleteOnOfflineServers = new(guildConfigs
.Where(gc => gc.DeleteStreamOnlineMessage)
.Select(x => x.GuildId)
.ToList());
.Where(gc => gc.DeleteStreamOnlineMessage)
.Select(x => x.GuildId)
.ToList());
var followedStreams = guildConfigs.SelectMany(x => x.FollowedStreams).ToList();
_shardTrackedStreams = followedStreams.GroupBy(x => new
{
x.Type,
Name = x.Username.ToLower()
})
.ToList()
.ToDictionary(
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
x => x.GroupBy(y => y.GuildId)
.ToDictionary(y => y.Key,
y => y.AsEnumerable().ToHashSet()));
{
x.Type,
Name = x.Username.ToLower()
})
.ToList()
.ToDictionary(
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
x => x.GroupBy(y => y.GuildId)
.ToDictionary(y => y.Key,
y => y.AsEnumerable().ToHashSet()));
// shard 0 will keep track of when there are no more guilds which track a stream
if (client.ShardId == 0)
@@ -111,12 +111,12 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
_streamTracker.AddLastData(fs.CreateKey(), null, false);
_trackCounter = allFollowedStreams.GroupBy(x => new
{
x.Type,
Name = x.Username.ToLower()
})
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
x => x.Select(fs => fs.GuildId).ToHashSet());
{
x.Type,
Name = x.Username.ToLower()
})
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
x => x.Select(fs => fs.GuildId).ToHashSet());
}
}
@@ -156,7 +156,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
continue;
var deleteGroups = failingStreams.GroupBy(x => x.Type)
.ToDictionary(x => x.Key, x => x.Select(y => y.Name).ToList());
.ToDictionary(x => x.Key, x => x.Select(y => y.Name).ToList());
await using var uow = _db.GetDbContext();
foreach (var kvp in deleteGroups)
@@ -169,9 +169,9 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
string.Join(", ", kvp.Value));
var toDelete = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
.ToList();
.AsQueryable()
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
.ToList();
uow.RemoveRange(toDelete);
await uow.SaveChangesAsync();
@@ -250,13 +250,20 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
if (_shardTrackedStreams.TryGetValue(key, out var fss))
{
await fss
// send offline stream notifications only to guilds which enable it with .stoff
.SelectMany(x => x.Value)
.Where(x => _offlineNotificationServers.Contains(x.GuildId))
.Select(fs => _client.GetGuild(fs.GuildId)
?.GetTextChannel(fs.ChannelId)
?.EmbedAsync(GetEmbed(fs.GuildId, stream)))
.WhenAll();
// send offline stream notifications only to guilds which enable it with .stoff
.SelectMany(x => x.Value)
.Where(x => _offlineNotificationServers.Contains(x.GuildId))
.Select(fs =>
{
var ch = _client.GetGuild(fs.GuildId)
?.GetTextChannel(fs.ChannelId);
if (ch is null)
return Task.CompletedTask;
return _sender.Response(ch).Embed(GetEmbed(fs.GuildId, stream)).SendAsync();
})
.WhenAll();
}
}
}
@@ -270,33 +277,35 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
if (_shardTrackedStreams.TryGetValue(key, out var fss))
{
var messages = await fss.SelectMany(x => x.Value)
.Select(async fs =>
{
var textChannel = _client.GetGuild(fs.GuildId)?.GetTextChannel(fs.ChannelId);
.Select(async fs =>
{
var textChannel = _client.GetGuild(fs.GuildId)
?.GetTextChannel(fs.ChannelId);
if (textChannel is null)
return default;
if (textChannel is null)
return default;
var repCtx = new ReplacementContext(guild: textChannel.Guild, client: _client)
.WithOverride("%platform%", () => fs.Type.ToString());
var repCtx = new ReplacementContext(guild: textChannel.Guild,
client: _client)
.WithOverride("%platform%", () => fs.Type.ToString());
var message = string.IsNullOrWhiteSpace(fs.Message)
? ""
: await _repSvc.ReplaceAsync(fs.Message, repCtx);
var message = string.IsNullOrWhiteSpace(fs.Message)
? ""
: await _repSvc.ReplaceAsync(fs.Message, repCtx);
var msg = await _sender.Response(textChannel)
.Embed(GetEmbed(fs.GuildId, stream, false))
.Text(message)
.SendAsync();
var msg = await _sender.Response(textChannel)
.Embed(GetEmbed(fs.GuildId, stream, false))
.Text(message)
.SendAsync();
// only cache the ids of channel/message pairs
if (_deleteOnOfflineServers.Contains(fs.GuildId))
return (textChannel.Id, msg.Id);
else
return default;
})
.WhenAll();
// only cache the ids of channel/message pairs
if (_deleteOnOfflineServers.Contains(fs.GuildId))
return (textChannel.Id, msg.Id);
else
return default;
})
.WhenAll();
// push online stream messages to redis
@@ -306,9 +315,9 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
try
{
var pairs = messages
.Where(x => x != default)
.Select(x => (x.Item1, x.Item2))
.ToList();
.Where(x => x != default)
.Select(x => (x.Item1, x.Item2))
.ToList();
if (pairs.Count > 0)
await OnlineMessagesSent(key.Type, key.Name, pairs);
@@ -330,9 +339,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
{
using (var uow = _db.GetDbContext())
{
var gc = uow.Set<GuildConfig>().AsQueryable()
.Include(x => x.FollowedStreams)
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);
var gc = uow.Set<GuildConfig>()
.AsQueryable()
.Include(x => x.FollowedStreams)
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);
if (gc is null)
return Task.CompletedTask;
@@ -392,10 +402,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
await using (var uow = _db.GetDbContext())
{
var fss = uow.Set<FollowedStream>()
.AsQueryable()
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
.AsQueryable()
.Where(x => x.GuildId == guildId)
.OrderBy(x => x.Id)
.ToList();
// out of range
if (fss.Count <= index)
@@ -484,11 +494,11 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
public EmbedBuilder GetEmbed(ulong guildId, StreamData status, bool showViewers = true)
{
var embed = new EmbedBuilder()
.WithTitle(status.Name)
.WithUrl(status.StreamUrl)
.WithDescription(status.StreamUrl)
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
var embed = _sender.CreateEmbed()
.WithTitle(status.Name)
.WithUrl(status.StreamUrl)
.WithDescription(status.StreamUrl)
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
if (showViewers)
{

View File

@@ -69,7 +69,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|| msg.Content.Equals(output, StringComparison.InvariantCultureIgnoreCase))
return;
var embed = new EmbedBuilder().WithOkColor();
var embed = _sender.CreateEmbed().WithOkColor();
if (autoDelete)
{

View File

@@ -20,7 +20,7 @@ public partial class Searches
await ctx.Channel.TriggerTypingAsync();
var translation = await _service.Translate(from, to, text);
var embed = new EmbedBuilder().WithOkColor().AddField(from, text).AddField(to, translation);
var embed = _sender.CreateEmbed().WithOkColor().AddField(from, text).AddField(to, translation);
await Response().Embed(embed).SendAsync();
}
@@ -80,7 +80,7 @@ public partial class Searches
{
var langs = _service.GetLanguages().ToList();
var eb = new EmbedBuilder()
var eb = _sender.CreateEmbed()
.WithTitle(GetText(strs.supported_languages))
.WithOkColor();

View File

@@ -25,7 +25,7 @@ public partial class Searches
using var http = _httpFactory.CreateClient();
var res = await http.GetStringAsync($"{XKCD_URL}/info.0.json");
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithImageUrl(comic.ImageLink)
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{comic.Num}")
@@ -60,7 +60,7 @@ public partial class Searches
var res = await http.GetStringAsync($"{XKCD_URL}/{num}/info.0.json");
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
var embed = new EmbedBuilder()
var embed = _sender.CreateEmbed()
.WithOkColor()
.WithImageUrl(comic.ImageLink)
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{num}")