mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
Added followedStreams.maxCount to searches configx
This commit is contained in:
@@ -28,6 +28,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
||||
|
||||
private readonly IPubSub _pubSub;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly SearchesConfigService _config;
|
||||
|
||||
public TypedKey<List<StreamData>> StreamsOnlineKey { get; }
|
||||
public TypedKey<List<StreamData>> StreamsOfflineKey { get; }
|
||||
@@ -49,13 +50,15 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
||||
IHttpClientFactory httpFactory,
|
||||
Bot bot,
|
||||
IPubSub pubSub,
|
||||
IEmbedBuilderService eb)
|
||||
IEmbedBuilderService eb,
|
||||
SearchesConfigService config)
|
||||
{
|
||||
_db = db;
|
||||
_client = client;
|
||||
_strings = strings;
|
||||
_pubSub = pubSub;
|
||||
_eb = eb;
|
||||
_config = config;
|
||||
|
||||
_streamTracker = new(httpFactory, creds);
|
||||
|
||||
@@ -69,34 +72,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)
|
||||
@@ -107,12 +110,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +155,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)
|
||||
@@ -165,9 +168,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();
|
||||
@@ -246,13 +249,13 @@ 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 => _client.GetGuild(fs.GuildId)
|
||||
?.GetTextChannel(fs.ChannelId)
|
||||
?.EmbedAsync(GetEmbed(fs.GuildId, stream)))
|
||||
.WhenAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,28 +269,28 @@ 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 rep = new ReplacementBuilder().WithOverride("%user%", () => fs.Username)
|
||||
.WithOverride("%platform%", () => fs.Type.ToString())
|
||||
.Build();
|
||||
var rep = new ReplacementBuilder().WithOverride("%user%", () => fs.Username)
|
||||
.WithOverride("%platform%", () => fs.Type.ToString())
|
||||
.Build();
|
||||
|
||||
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, false), message);
|
||||
var msg = await textChannel.EmbedAsync(GetEmbed(fs.GuildId, stream, false), message);
|
||||
|
||||
// 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
|
||||
@@ -297,16 +300,15 @@ 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);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,10 +386,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)
|
||||
@@ -450,7 +452,9 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
||||
GuildId = guildId
|
||||
};
|
||||
|
||||
if (gc.FollowedStreams.Count >= 10)
|
||||
var config = _config.Data;
|
||||
if (config.FollowedStreams.MaxCount is not -1
|
||||
&& gc.FollowedStreams.Count >= config.FollowedStreams.MaxCount)
|
||||
return null;
|
||||
|
||||
gc.FollowedStreams.Add(fs);
|
||||
@@ -475,10 +479,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
||||
public IEmbedBuilder GetEmbed(ulong guildId, StreamData status, bool showViewers = true)
|
||||
{
|
||||
var embed = _eb.Create()
|
||||
.WithTitle(status.Name)
|
||||
.WithUrl(status.StreamUrl)
|
||||
.WithDescription(status.StreamUrl)
|
||||
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
|
||||
.WithTitle(status.Name)
|
||||
.WithUrl(status.StreamUrl)
|
||||
.WithDescription(status.StreamUrl)
|
||||
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
|
||||
|
||||
if (showViewers)
|
||||
{
|
||||
|
@@ -55,6 +55,15 @@ Use a fully qualified url. Example: https://my-invidious-instance.mydomain.com
|
||||
Instances specified must have api available.
|
||||
You check that by opening an api endpoint in your browser. For example: https://my-invidious-instance.mydomain.com/api/v1/trending")]
|
||||
public List<string> InvidiousInstances { get; set; } = new List<string>();
|
||||
|
||||
[Comment("Maximum number of followed streams per server")]
|
||||
public FollowedStreamConfig FollowedStreams { get; set; } = new FollowedStreamConfig();
|
||||
}
|
||||
|
||||
public sealed class FollowedStreamConfig
|
||||
{
|
||||
[Comment("Maximum number of streams that each server can follow. -1 for infinite")]
|
||||
public int MaxCount { get; set; } = 10;
|
||||
}
|
||||
|
||||
public enum YoutubeSearcher
|
||||
|
@@ -28,6 +28,11 @@ public class SearchesConfigService : ConfigServiceBase<SearchesConfig>
|
||||
ConfigParsers.InsensitiveEnum,
|
||||
ConfigPrinters.ToString);
|
||||
|
||||
AddParsedProp("followedStreams.maxCount",
|
||||
sc => sc.FollowedStreams.MaxCount,
|
||||
ConfigParsers.InsensitiveEnum,
|
||||
ConfigPrinters.ToString);
|
||||
|
||||
Migrate();
|
||||
}
|
||||
|
||||
@@ -41,5 +46,13 @@ public class SearchesConfigService : ConfigServiceBase<SearchesConfig>
|
||||
c.WebSearchEngine = WebSearchEngine.Google_Scrape;
|
||||
});
|
||||
}
|
||||
|
||||
if (data.Version < 2)
|
||||
{
|
||||
ModifyConfig(c =>
|
||||
{
|
||||
c.Version = 2;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user