mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-03 16:24:27 -05:00 
			
		
		
		
	Split stream deleter service into a separate file, there will no longer be a viewer count when the stream comes online, as it will (almost?) always show 0
This commit is contained in:
		@@ -1,6 +1,4 @@
 | 
				
			|||||||
#nullable disable
 | 
					#nullable disable
 | 
				
			||||||
using LinqToDB;
 | 
					 | 
				
			||||||
using LinqToDB.EntityFrameworkCore;
 | 
					 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Nadeko.Common;
 | 
					using Nadeko.Common;
 | 
				
			||||||
using NadekoBot.Common.ModuleBehaviors;
 | 
					using NadekoBot.Common.ModuleBehaviors;
 | 
				
			||||||
@@ -12,95 +10,6 @@ using NadekoBot.Services.Database.Models;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Searches.Services;
 | 
					namespace NadekoBot.Modules.Searches.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public sealed class StreamOnlineMessageDeleterService : INService, IReadyExecutor
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    private readonly StreamNotificationService _notifService;
 | 
					 | 
				
			||||||
    private readonly DbService _db;
 | 
					 | 
				
			||||||
    private readonly DiscordSocketClient _client;
 | 
					 | 
				
			||||||
    private readonly IPubSub _pubSub;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public StreamOnlineMessageDeleterService(
 | 
					 | 
				
			||||||
        StreamNotificationService notifService,
 | 
					 | 
				
			||||||
        DbService db,
 | 
					 | 
				
			||||||
        IPubSub pubSub,
 | 
					 | 
				
			||||||
        DiscordSocketClient client)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        _notifService = notifService;
 | 
					 | 
				
			||||||
        _db = db;
 | 
					 | 
				
			||||||
        _client = client;
 | 
					 | 
				
			||||||
        _pubSub = pubSub;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public async Task OnReadyAsync()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        _notifService.OnlineMessagesSent += OnOnlineMessagesSent;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if(_client.ShardId == 0)
 | 
					 | 
				
			||||||
            await _pubSub.Sub(_notifService.StreamsOfflineKey, OnStreamsOffline);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async Task OnOnlineMessagesSent(FollowedStream.FType type, string name, IReadOnlyCollection<(ulong, ulong)> pairs)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        await using var ctx = _db.GetDbContext();
 | 
					 | 
				
			||||||
        foreach (var (channelId, messageId) in pairs)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            await ctx.GetTable<StreamOnlineMessage>()
 | 
					 | 
				
			||||||
                     .InsertAsync(() => new()
 | 
					 | 
				
			||||||
                     {
 | 
					 | 
				
			||||||
                         Name = name,
 | 
					 | 
				
			||||||
                         Type = type,
 | 
					 | 
				
			||||||
                         MessageId = messageId,
 | 
					 | 
				
			||||||
                         ChannelId = channelId,
 | 
					 | 
				
			||||||
                         DateAdded = DateTime.UtcNow,
 | 
					 | 
				
			||||||
                     });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async ValueTask OnStreamsOffline(List<StreamData> streamDatas)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (_client.ShardId != 0)
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var pairs = await GetMessagesToDelete(streamDatas);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var (channelId, messageId) in pairs)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var textChannel = await _client.GetChannelAsync(channelId) as ITextChannel;
 | 
					 | 
				
			||||||
                if (textChannel is null)
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                await textChannel.DeleteMessageAsync(messageId);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            catch
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async Task<IEnumerable<(ulong, ulong)>> GetMessagesToDelete(List<StreamData> streamDatas)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        await using var ctx = _db.GetDbContext();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var toReturn = new List<(ulong, ulong)>();
 | 
					 | 
				
			||||||
        foreach (var sd in streamDatas)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var key = sd.CreateKey();
 | 
					 | 
				
			||||||
            var toDelete = await ctx.GetTable<StreamOnlineMessage>()
 | 
					 | 
				
			||||||
                                    .Where(x => (x.Type == key.Type && x.Name == key.Name)
 | 
					 | 
				
			||||||
                                                || Sql.DateDiff(Sql.DateParts.Day, x.DateAdded, DateTime.UtcNow) > 1)
 | 
					 | 
				
			||||||
                                    .DeleteWithOutputAsync();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            toReturn.AddRange(toDelete.Select(x => (x.ChannelId, x.MessageId)));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return toReturn;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public sealed class StreamNotificationService : INService, IReadyExecutor
 | 
					public sealed class StreamNotificationService : INService, IReadyExecutor
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private readonly DbService _db;
 | 
					    private readonly DbService _db;
 | 
				
			||||||
@@ -370,7 +279,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                             var message = string.IsNullOrWhiteSpace(fs.Message) ? "" : rep.Replace(fs.Message);
 | 
					                             var message = string.IsNullOrWhiteSpace(fs.Message) ? "" : rep.Replace(fs.Message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                             var msg = await textChannel.EmbedAsync(GetEmbed(fs.GuildId, stream), message);
 | 
					                             var msg = await textChannel.EmbedAsync(GetEmbed(fs.GuildId, stream, false), message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                             // only cache the ids of channel/message pairs 
 | 
					                             // only cache the ids of channel/message pairs 
 | 
				
			||||||
                             if(_deleteOnOfflineServers.Contains(fs.GuildId))
 | 
					                             if(_deleteOnOfflineServers.Contains(fs.GuildId))
 | 
				
			||||||
@@ -563,18 +472,22 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
 | 
				
			|||||||
        return data;
 | 
					        return data;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public IEmbedBuilder GetEmbed(ulong guildId, StreamData status)
 | 
					    public IEmbedBuilder GetEmbed(ulong guildId, StreamData status, bool showViewers = true)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var embed = _eb.Create()
 | 
					        var embed = _eb.Create()
 | 
				
			||||||
                       .WithTitle(status.Name)
 | 
					                       .WithTitle(status.Name)
 | 
				
			||||||
                       .WithUrl(status.StreamUrl)
 | 
					                       .WithUrl(status.StreamUrl)
 | 
				
			||||||
                       .WithDescription(status.StreamUrl)
 | 
					                       .WithDescription(status.StreamUrl)
 | 
				
			||||||
                       .AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true)
 | 
					                       .AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
 | 
				
			||||||
                       .AddField(GetText(guildId, strs.viewers),
 | 
					
 | 
				
			||||||
 | 
					        if (showViewers)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            embed.AddField(GetText(guildId, strs.viewers),
 | 
				
			||||||
                status.Viewers == 0 && !status.IsLive
 | 
					                status.Viewers == 0 && !status.IsLive
 | 
				
			||||||
                    ? "-"
 | 
					                    ? "-"
 | 
				
			||||||
                    : status.Viewers,
 | 
					                    : status.Viewers,
 | 
				
			||||||
                true);
 | 
					                true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (status.IsLive)
 | 
					        if (status.IsLive)
 | 
				
			||||||
            embed = embed.WithOkColor();
 | 
					            embed = embed.WithOkColor();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					#nullable disable
 | 
				
			||||||
 | 
					using LinqToDB;
 | 
				
			||||||
 | 
					using LinqToDB.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using NadekoBot.Common.ModuleBehaviors;
 | 
				
			||||||
 | 
					using NadekoBot.Db.Models;
 | 
				
			||||||
 | 
					using NadekoBot.Modules.Searches.Common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace NadekoBot.Modules.Searches.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public sealed class StreamOnlineMessageDeleterService : INService, IReadyExecutor
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private readonly StreamNotificationService _notifService;
 | 
				
			||||||
 | 
					    private readonly DbService _db;
 | 
				
			||||||
 | 
					    private readonly DiscordSocketClient _client;
 | 
				
			||||||
 | 
					    private readonly IPubSub _pubSub;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public StreamOnlineMessageDeleterService(
 | 
				
			||||||
 | 
					        StreamNotificationService notifService,
 | 
				
			||||||
 | 
					        DbService db,
 | 
				
			||||||
 | 
					        IPubSub pubSub,
 | 
				
			||||||
 | 
					        DiscordSocketClient client)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _notifService = notifService;
 | 
				
			||||||
 | 
					        _db = db;
 | 
				
			||||||
 | 
					        _client = client;
 | 
				
			||||||
 | 
					        _pubSub = pubSub;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task OnReadyAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _notifService.OnlineMessagesSent += OnOnlineMessagesSent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_client.ShardId == 0)
 | 
				
			||||||
 | 
					            await _pubSub.Sub(_notifService.StreamsOfflineKey, OnStreamsOffline);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async Task OnOnlineMessagesSent(
 | 
				
			||||||
 | 
					        FollowedStream.FType type,
 | 
				
			||||||
 | 
					        string name,
 | 
				
			||||||
 | 
					        IReadOnlyCollection<(ulong, ulong)> pairs)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        await using var ctx = _db.GetDbContext();
 | 
				
			||||||
 | 
					        foreach (var (channelId, messageId) in pairs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            await ctx.GetTable<StreamOnlineMessage>()
 | 
				
			||||||
 | 
					                     .InsertAsync(() => new()
 | 
				
			||||||
 | 
					                     {
 | 
				
			||||||
 | 
					                         Name = name,
 | 
				
			||||||
 | 
					                         Type = type,
 | 
				
			||||||
 | 
					                         MessageId = messageId,
 | 
				
			||||||
 | 
					                         ChannelId = channelId,
 | 
				
			||||||
 | 
					                         DateAdded = DateTime.UtcNow,
 | 
				
			||||||
 | 
					                     });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async ValueTask OnStreamsOffline(List<StreamData> streamDatas)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (_client.ShardId != 0)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var pairs = await GetMessagesToDelete(streamDatas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var (channelId, messageId) in pairs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var textChannel = await _client.GetChannelAsync(channelId) as ITextChannel;
 | 
				
			||||||
 | 
					                if (textChannel is null)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await textChannel.DeleteMessageAsync(messageId);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async Task<IEnumerable<(ulong, ulong)>> GetMessagesToDelete(List<StreamData> streamDatas)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        await using var ctx = _db.GetDbContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var toReturn = new List<(ulong, ulong)>();
 | 
				
			||||||
 | 
					        foreach (var sd in streamDatas)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var key = sd.CreateKey();
 | 
				
			||||||
 | 
					            var toDelete = await ctx.GetTable<StreamOnlineMessage>()
 | 
				
			||||||
 | 
					                                    .Where(x => (x.Type == key.Type && x.Name == key.Name)
 | 
				
			||||||
 | 
					                                                || Sql.DateDiff(Sql.DateParts.Day, x.DateAdded, DateTime.UtcNow) > 1)
 | 
				
			||||||
 | 
					                                    .DeleteWithOutputAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            toReturn.AddRange(toDelete.Select(x => (x.ChannelId, x.MessageId)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return toReturn;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user