diff --git a/Geekbot.net/Commands/Admin/Owner/MigrationMethods.cs b/Geekbot.net/Commands/Admin/Owner/MigrationMethods.cs new file mode 100644 index 0000000..6f50257 --- /dev/null +++ b/Geekbot.net/Commands/Admin/Owner/MigrationMethods.cs @@ -0,0 +1,8 @@ +namespace Geekbot.net.Commands.Admin.Owner +{ + public enum MigrationMethods + { + redis, + messages + } +} \ No newline at end of file diff --git a/Geekbot.net/Commands/Admin/Owner.cs b/Geekbot.net/Commands/Admin/Owner/Owner.cs similarity index 68% rename from Geekbot.net/Commands/Admin/Owner.cs rename to Geekbot.net/Commands/Admin/Owner/Owner.cs index 7cc194b..b02ee47 100644 --- a/Geekbot.net/Commands/Admin/Owner.cs +++ b/Geekbot.net/Commands/Admin/Owner/Owner.cs @@ -9,7 +9,7 @@ using Geekbot.net.Lib.GlobalSettings; using Geekbot.net.Lib.Logger; using Geekbot.net.Lib.UserRepository; -namespace Geekbot.net.Commands.Admin +namespace Geekbot.net.Commands.Admin.Owner { [Group("owner")] [RequireOwner] @@ -35,27 +35,42 @@ namespace Geekbot.net.Commands.Admin } [Command("migrate", RunMode = RunMode.Async)] - public async Task Migrate(string force = "") + public async Task Migrate(MigrationMethods method, string force = "") { try { - var status = _globalSettings.GetKey("MigrationStatus"); - if (status.Equals("Running")) + switch (method) { - await ReplyAsync("Migration already running"); - return; - } - if (status.Equals("Done") && !force.Equals("force")) - { - await ReplyAsync("Migration already ran, write `!owner migrate force` to run again"); - return; - } + case MigrationMethods.redis: + var status = _globalSettings.GetKey("MigrationStatus"); + if (status.Equals("Running")) + { + await ReplyAsync("Migration already running"); + return; + } + if (status.Equals("Done") && !force.Equals("force")) + { + await ReplyAsync("Migration already ran, write `!owner migrate redis force` to run again"); + return; + } - await ReplyAsync("starting migration"); - await _globalSettings.SetKey("MigrationStatus", "Running"); - var redisMigration = new RedisMigration(_database, _redis, _logger, _client); - await redisMigration.Migrate(); - await _globalSettings.SetKey("MigrationStatus", "Done"); + await ReplyAsync("starting migration"); + await _globalSettings.SetKey("MigrationStatus", "Running"); + var redisMigration = new RedisMigration(_database, _redis, _logger, _client); + await redisMigration.Migrate(); + await _globalSettings.SetKey("MigrationStatus", "Done"); + break; + + case MigrationMethods.messages: + await ReplyAsync("Migrating Messages to postgres..."); + var messageMigration = new MessageMigration(_database, _redis, _logger); + await messageMigration.Migrate(); + break; + + default: + await ReplyAsync("No Migration Method specified..."); + break; + } } catch (Exception e) { diff --git a/Geekbot.net/Commands/User/Ranking/Rank.cs b/Geekbot.net/Commands/User/Ranking/Rank.cs index 1bb9f95..08fd384 100644 --- a/Geekbot.net/Commands/User/Ranking/Rank.cs +++ b/Geekbot.net/Commands/User/Ranking/Rank.cs @@ -151,17 +151,17 @@ namespace Geekbot.net.Commands.User.Ranking private Dictionary GetMessageList(int amount) { -// return _database.Messages -// .Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong())) -// .OrderByDescending(o => o.MessageCount) -// .Take(amount) -// .ToDictionary(key => key.UserId.AsUlong(), key => key.MessageCount); - return _redis.Db - .HashGetAll($"{Context.Guild.Id}:Messages") - .Where(user => !user.Name.Equals(0)) - .OrderByDescending(s => s.Value) + return _database.Messages + .Where(k => k.GuildId.Equals(Context.Guild.Id.AsLong())) + .OrderByDescending(o => o.MessageCount) .Take(amount) - .ToDictionary(user => ulong.Parse(user.Name), user => int.Parse(user.Value)); + .ToDictionary(key => key.UserId.AsUlong(), key => key.MessageCount); +// return _redis.Db +// .HashGetAll($"{Context.Guild.Id}:Messages") +// .Where(user => !user.Name.Equals(0)) +// .OrderByDescending(s => s.Value) +// .Take(amount) +// .ToDictionary(user => ulong.Parse(user.Name), user => int.Parse(user.Value)); } private Dictionary GetKarmaList(int amount) diff --git a/Geekbot.net/Commands/User/Stats.cs b/Geekbot.net/Commands/User/Stats.cs index 4ec2148..4468b21 100644 --- a/Geekbot.net/Commands/User/Stats.cs +++ b/Geekbot.net/Commands/User/Stats.cs @@ -39,15 +39,15 @@ namespace Geekbot.net.Commands.User var age = Math.Floor((DateTime.Now - createdAt).TotalDays); var joinedDayAgo = Math.Floor((DateTime.Now - joinedAt).TotalDays); -// var messages = _database.Messages -// .First(e => e.GuildId.Equals(Context.Guild.Id.AsLong()) && e.UserId.Equals(Context.User.Id.AsLong())) -// .MessageCount; -// var guildMessages = _database.Messages -// .Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())) -// .Select(e => e.MessageCount) -// .Sum(); - var messages = (int) _redis.Db.HashGet($"{Context.Guild.Id}:Messages", userInfo.Id.ToString()); - var guildMessages = (int) _redis.Db.HashGet($"{Context.Guild.Id}:Messages", 0.ToString()); + var messages = _database.Messages + .First(e => e.GuildId.Equals(Context.Guild.Id.AsLong()) && e.UserId.Equals(Context.User.Id.AsLong())) + .MessageCount; + var guildMessages = _database.Messages + .Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())) + .Select(e => e.MessageCount) + .Sum(); +// var messages = (int) _redis.Db.HashGet($"{Context.Guild.Id}:Messages", userInfo.Id.ToString()); +// var guildMessages = (int) _redis.Db.HashGet($"{Context.Guild.Id}:Messages", 0.ToString()); var level = _levelCalc.GetLevel(messages); var percent = Math.Round((double) (100 * messages) / guildMessages, 2); diff --git a/Geekbot.net/Database/MessageMigration.cs b/Geekbot.net/Database/MessageMigration.cs new file mode 100644 index 0000000..ed07072 --- /dev/null +++ b/Geekbot.net/Database/MessageMigration.cs @@ -0,0 +1,73 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Geekbot.net.Database.Models; +using Geekbot.net.Lib.AlmostRedis; +using Geekbot.net.Lib.Extensions; +using Geekbot.net.Lib.Logger; + +namespace Geekbot.net.Database +{ + public class MessageMigration + { + private readonly DatabaseContext _database; + private readonly IAlmostRedis _redis; + private readonly IGeekbotLogger _logger; + + public MessageMigration(DatabaseContext database, IAlmostRedis redis, IGeekbotLogger logger) + { + _database = database; + _redis = redis; + _logger = logger; + } + + public async Task Migrate() + { + _logger.Warning(LogSource.Migration, "Starting message migration"); + try + { + var messageKeys = _redis.GetAllKeys().Where(e => e.ToString().EndsWith("Messages")); + foreach (var keyName in messageKeys) + { + try + { + var guildId = ulong.Parse(keyName.ToString().Split(':').FirstOrDefault()); + var guildUsers = _redis.Db.HashGetAll(keyName); + foreach (var user in guildUsers) + { + try + { + var userId = ulong.Parse(user.Name); + if (userId != 0) + { + var userMessages = int.Parse(user.Value); + _database.Messages.Add(new MessagesModel + { + UserId = userId.AsLong(), + GuildId = guildId.AsLong(), + MessageCount = userMessages + }); + } + } + catch (Exception e) + { + _logger.Error(LogSource.Migration, $"Failed to add record for a user in {guildId}", e); + } + } + + await _database.SaveChangesAsync(); + } + catch (Exception e) + { + _logger.Error(LogSource.Migration, "Failed to determinate guild", e); + } + } + _logger.Warning(LogSource.Migration, "Successfully finished message migration"); + } + catch (Exception e) + { + _logger.Error(LogSource.Migration, "Message migration failed", e); + } + } + } +} \ No newline at end of file