diff --git a/DiscordBot/Modules/TipModule.cs b/DiscordBot/Modules/TipModule.cs index 0423737e..85d94075 100644 --- a/DiscordBot/Modules/TipModule.cs +++ b/DiscordBot/Modules/TipModule.cs @@ -31,6 +31,9 @@ public async Task Tip(string keywords) return; } + foreach (var tip in tips) + tip.Requests++; + var isAnyTextTips = tips.Any(tip => !string.IsNullOrEmpty(tip.Content)); var builder = new EmbedBuilder(); if (isAnyTextTips) @@ -70,6 +73,7 @@ public async Task Tip(string keywords) var ids = string.Join(" ", tips.Select(t => t.Id.ToString()).ToArray()); await ReplyAsync($"-# Tip ID {ids}"); await Context.Message.DeleteAsync(); + await TipService.CommitTipDatabase(); } [Command("AddTip")] @@ -109,7 +113,8 @@ public async Task ReplaceTip(ulong tipId, string content = "") await TipService.ReplaceTip(Context.Message, tip, content); } - + +#if false [Command("DumpTips")] [Summary("For debugging, view the tip index.")] [RequireModerator] @@ -138,6 +143,18 @@ await Context.Channel.SendMessageAsync( await Task.Delay(chunkTime); } } +#endif + + [Command("ReloadTips")] + [Summary("Reload the database of tips.")] + [RequireModerator] + public async Task ReloadTipDatabase() + { + // rare usage, but in case someone with a shell decides + // to edit the json for debugging/expansion reasons... + await TipService.ReloadTipDatabase(); + await ReplyAsync("Tip index reloaded."); + } [Command("ListTips")] [Summary("List available tips by their keywords.")] diff --git a/DiscordBot/Services/Tips/Components/Tip.cs b/DiscordBot/Services/Tips/Components/Tip.cs index f7962ad4..bfaab3f4 100644 --- a/DiscordBot/Services/Tips/Components/Tip.cs +++ b/DiscordBot/Services/Tips/Components/Tip.cs @@ -8,4 +8,5 @@ public class Tip: IEntity public string Content { get; set; } public List Keywords { get; set; } public List ImagePaths { get; set; } + public int Requests { get; set; } } diff --git a/DiscordBot/Services/Tips/TipService.cs b/DiscordBot/Services/Tips/TipService.cs index b94490c0..24cd0404 100644 --- a/DiscordBot/Services/Tips/TipService.cs +++ b/DiscordBot/Services/Tips/TipService.cs @@ -76,16 +76,8 @@ private void Initialize() _loggingService.LogAction($"[{ServiceName}] Tip directory contains {new DirectoryInfo(_imageDirectory).EnumerateFiles("*.*", SearchOption.AllDirectories).Count()} files.", ExtendedLogSeverity.Info); } - - if (File.Exists(jsonPath)) - { - var json = File.ReadAllText(jsonPath); - _tips = JsonConvert.DeserializeObject>>(json); - _loggingService.LogAction( - $"[{ServiceName}] Tip index has {_tips.Count} keywords.", - ExtendedLogSeverity.Info); - //NOTE: elements of type Tip are not de-duplicated after loading - } + + var blocking = ReloadTipDatabase(); } _isRunning = true; @@ -271,11 +263,64 @@ public async Task ReplaceTip(IUserMessage message, Tip tip, string content) // REVIEW: causes two CommitTipDatabase calls } - private async Task CommitTipDatabase() + public async Task ReloadTipDatabase() + { + var jsonPath = GetTipPath(DatabaseName);; + if (File.Exists(jsonPath)) + { + var json = File.ReadAllText(jsonPath); + _tips = JsonConvert.DeserializeObject>>(json); + _loggingService.LogAction( + $"[{ServiceName}] Tip index has {_tips.Count} keywords.", + ExtendedLogSeverity.Info); + } + + //NOTE: elements of type Tip are not de-duplicated after loading in earlier versions + // probably some Linq clever way of de-duplicating + bool touched = false; + var tips = new Dictionary(); + foreach (string keyword in _tips.Keys) + { + var list = _tips[keyword]; + for (int i = 0; i < list.Count; i++) + { + ulong id = list[i].Id; + if (tips.TryGetValue(id, out var tip)) + { + if (!Object.ReferenceEquals(list[i], tip)) + { + list[i] = tip; + touched = true; + } + } + else + { + tips[id] = list[i]; + } + } + } + + if (touched) + { + _loggingService.LogAction( + $"[{ServiceName}] Tip index was de-duplicated.", + ExtendedLogSeverity.Info); + await CommitTipDatabase(); + } + } + + public async Task CommitTipDatabase() { // In same folder, we save json files var jsonPath = GetTipPath(DatabaseName); - await File.WriteAllTextAsync(jsonPath, JsonConvert.SerializeObject(_tips)); + var settings = new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }; + await File.WriteAllTextAsync(jsonPath, + JsonConvert.SerializeObject(_tips, + Formatting.Indented, + settings)); } public string DumpTipDatabase()