work on repeater
This commit is contained in:
		| @@ -8,7 +8,7 @@ using NadekoBot.Services.Database.Impl; | ||||
| namespace NadekoBot.Migrations | ||||
| { | ||||
|     [DbContext(typeof(NadekoSqliteContext))] | ||||
|     [Migration("20160828000228_first")] | ||||
|     [Migration("20160828153124_first")] | ||||
|     partial class first | ||||
|     { | ||||
|         protected override void BuildTargetModel(ModelBuilder modelBuilder) | ||||
| @@ -281,6 +281,27 @@ namespace NadekoBot.Migrations | ||||
|                     b.ToTable("Reminders"); | ||||
|                 }); | ||||
| 
 | ||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => | ||||
|                 { | ||||
|                     b.Property<int>("Id") | ||||
|                         .ValueGeneratedOnAdd(); | ||||
| 
 | ||||
|                     b.Property<ulong>("ChannelId"); | ||||
| 
 | ||||
|                     b.Property<ulong>("GuildId"); | ||||
| 
 | ||||
|                     b.Property<TimeSpan>("Interval"); | ||||
| 
 | ||||
|                     b.Property<string>("Message"); | ||||
| 
 | ||||
|                     b.HasKey("Id"); | ||||
| 
 | ||||
|                     b.HasIndex("ChannelId") | ||||
|                         .IsUnique(); | ||||
| 
 | ||||
|                     b.ToTable("Repeaters"); | ||||
|                 }); | ||||
| 
 | ||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => | ||||
|                 { | ||||
|                     b.Property<int>("Id") | ||||
| @@ -125,6 +125,22 @@ namespace NadekoBot.Migrations | ||||
|                     table.PrimaryKey("PK_Reminders", x => x.Id); | ||||
|                 }); | ||||
| 
 | ||||
|             migrationBuilder.CreateTable( | ||||
|                 name: "Repeaters", | ||||
|                 columns: table => new | ||||
|                 { | ||||
|                     Id = table.Column<int>(nullable: false) | ||||
|                         .Annotation("Autoincrement", true), | ||||
|                     ChannelId = table.Column<ulong>(nullable: false), | ||||
|                     GuildId = table.Column<ulong>(nullable: false), | ||||
|                     Interval = table.Column<TimeSpan>(nullable: false), | ||||
|                     Message = table.Column<string>(nullable: true) | ||||
|                 }, | ||||
|                 constraints: table => | ||||
|                 { | ||||
|                     table.PrimaryKey("PK_Repeaters", x => x.Id); | ||||
|                 }); | ||||
| 
 | ||||
|             migrationBuilder.CreateTable( | ||||
|                 name: "SelfAssignableRoles", | ||||
|                 columns: table => new | ||||
| @@ -306,6 +322,12 @@ namespace NadekoBot.Migrations | ||||
|                 table: "RaceAnimal", | ||||
|                 column: "BotConfigId"); | ||||
| 
 | ||||
|             migrationBuilder.CreateIndex( | ||||
|                 name: "IX_Repeaters_ChannelId", | ||||
|                 table: "Repeaters", | ||||
|                 column: "ChannelId", | ||||
|                 unique: true); | ||||
| 
 | ||||
|             migrationBuilder.CreateIndex( | ||||
|                 name: "IX_SelfAssignableRoles_GuildId_RoleId", | ||||
|                 table: "SelfAssignableRoles", | ||||
| @@ -345,6 +367,9 @@ namespace NadekoBot.Migrations | ||||
|             migrationBuilder.DropTable( | ||||
|                 name: "Reminders"); | ||||
| 
 | ||||
|             migrationBuilder.DropTable( | ||||
|                 name: "Repeaters"); | ||||
| 
 | ||||
|             migrationBuilder.DropTable( | ||||
|                 name: "SelfAssignableRoles"); | ||||
| 
 | ||||
| @@ -280,6 +280,27 @@ namespace NadekoBot.Migrations | ||||
|                     b.ToTable("Reminders"); | ||||
|                 }); | ||||
|  | ||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b => | ||||
|                 { | ||||
|                     b.Property<int>("Id") | ||||
|                         .ValueGeneratedOnAdd(); | ||||
|  | ||||
|                     b.Property<ulong>("ChannelId"); | ||||
|  | ||||
|                     b.Property<ulong>("GuildId"); | ||||
|  | ||||
|                     b.Property<TimeSpan>("Interval"); | ||||
|  | ||||
|                     b.Property<string>("Message"); | ||||
|  | ||||
|                     b.HasKey("Id"); | ||||
|  | ||||
|                     b.HasIndex("ChannelId") | ||||
|                         .IsUnique(); | ||||
|  | ||||
|                     b.ToTable("Repeaters"); | ||||
|                 }); | ||||
|  | ||||
|             modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => | ||||
|                 { | ||||
|                     b.Property<int>("Id") | ||||
|   | ||||
| @@ -1,130 +1,106 @@ | ||||
| using Discord; | ||||
| using Discord.Commands; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Modules.Permissions.Classes; | ||||
| using NadekoBot.Attributes; | ||||
| using NadekoBot.Services; | ||||
| using NadekoBot.Services.Database; | ||||
| using NadekoBot.Services.Database.Models; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using System.Timers; | ||||
|  | ||||
| //todo DB | ||||
| namespace NadekoBot.Modules.Administration | ||||
| { | ||||
|     class MessageRepeater : DiscordCommand | ||||
|     public partial class Administration | ||||
|     { | ||||
|         private readonly ConcurrentDictionary<Server, Repeater> repeaters = new ConcurrentDictionary<Server, Repeater>(); | ||||
|         private class Repeater | ||||
|  | ||||
|         [Group] | ||||
|         public class RepeatCommands | ||||
|         { | ||||
|             [Newtonsoft.Json.JsonIgnore] | ||||
|             public Timer MessageTimer { get; set; } | ||||
|             [Newtonsoft.Json.JsonIgnore] | ||||
|             public Channel RepeatingChannel { get; set; } | ||||
|             public ConcurrentDictionary<ulong, Repeater> repeaters; | ||||
|  | ||||
|             public ulong RepeatingServerId { get; set; } | ||||
|             public ulong RepeatingChannelId { get; set; } | ||||
|             public Message lastMessage { get; set; } = null; | ||||
|             public string RepeatingMessage { get; set; } | ||||
|             public int Interval { get; set; } | ||||
|  | ||||
|             public Repeater Start() | ||||
|             public RepeatCommands() | ||||
|             { | ||||
|                 MessageTimer = new Timer { Interval = Interval }; | ||||
|                 MessageTimer.Elapsed += async (s, e) => await Invoke(); | ||||
|                 return this; | ||||
|             } | ||||
|  | ||||
|             public async Task Invoke() | ||||
|             { | ||||
|                 var ch = RepeatingChannel; | ||||
|                 var msg = RepeatingMessage; | ||||
|                 if (ch != null && !string.IsNullOrWhiteSpace(msg)) | ||||
|                 using (var uow = DbHandler.UnitOfWork()) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         if (lastMessage != null) | ||||
|                             await lastMessage.Delete().ConfigureAwait(false); | ||||
|                     } | ||||
|                     catch { } | ||||
|                     try | ||||
|                     { | ||||
|                         lastMessage = await ch.SendMessageAsync(msg).ConfigureAwait(false); | ||||
|                     } | ||||
|                     catch { } | ||||
|                     repeaters = new ConcurrentDictionary<ulong, Repeater>(uow.Repeaters.GetAll().ToDictionary(r => r.ChannelId)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         internal override void Init(CommandGroupBuilder cgb) | ||||
|         { | ||||
|  | ||||
|             cgb.CreateCommand(Module.Prefix + "repeatinvoke") | ||||
|                 .Alias(Module.Prefix + "repinv") | ||||
|                 .Description($"Immediately shows the repeat message and restarts the timer. **Needs Manage Messages Permissions.**| `{Prefix}repinv`") | ||||
|                 .AddCheck(SimpleCheckers.ManageMessages()) | ||||
|                 .Do(async e => | ||||
|             [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|             [RequireContext(ContextType.Guild)] | ||||
|             [RequirePermission(GuildPermission.ManageMessages)] | ||||
|             public async Task RepeatInvoke(IMessage imsg) | ||||
|             { | ||||
|                 var channel = (ITextChannel)imsg.Channel; | ||||
|  | ||||
|                 Repeater rep; | ||||
|                 if (!repeaters.TryGetValue(channel.Id, out rep)) | ||||
|                 { | ||||
|                     Repeater rep; | ||||
|                     if (!repeaters.TryGetValue(e.Server, out rep)) | ||||
|                     { | ||||
|                         await channel.SendMessageAsync("`No repeating message found on this server.`"); | ||||
|                         return; | ||||
|                     } | ||||
|                     await channel.SendMessageAsync("`No repeating message found on this server.`").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                     await rep.Invoke(); | ||||
|                 }); | ||||
|                 await channel.SendMessageAsync("🔄 " + rep.Message); | ||||
|             } | ||||
|  | ||||
|             cgb.CreateCommand(Module.Prefix + "repeat") | ||||
|                 .Description("Repeat a message every X minutes. If no parameters are specified, " + | ||||
|                              $"repeat is disabled. **Needs Manage Messages Permissions.** |`{Prefix}repeat 5 Hello there`") | ||||
|                 .Parameter("minutes", ParameterType.Optional) | ||||
|                 .Parameter("msg", ParameterType.Unparsed) | ||||
|                 .AddCheck(SimpleCheckers.ManageMessages()) | ||||
|                 .Do(async e => | ||||
|             [LocalizedCommand, LocalizedDescription, LocalizedSummary] | ||||
|             [RequireContext(ContextType.Guild)] | ||||
|             public async Task Repeat(IMessage imsg, int minutes, [Remainder] string message = null) | ||||
|             { | ||||
|                 var channel = (ITextChannel)imsg.Channel; | ||||
|  | ||||
|                 if (minutes < 1 || minutes > 1500) | ||||
|                     return; | ||||
|  | ||||
|                 Repeater rep; | ||||
|  | ||||
|                 if (string.IsNullOrWhiteSpace(message)) //turn off | ||||
|                 { | ||||
|                     var minutesStr = minutes; | ||||
|                     var msg = msg; | ||||
|  | ||||
|                     // if both null, disable | ||||
|                     if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) | ||||
|                     if (repeaters.TryRemove(channel.Id, out rep)) | ||||
|                     { | ||||
|  | ||||
|                         Repeater rep; | ||||
|                         if (!repeaters.TryRemove(e.Server, out rep)) | ||||
|                             return; | ||||
|                         rep.MessageTimer.Stop(); | ||||
|                         await channel.SendMessageAsync("Repeating disabled").ConfigureAwait(false); | ||||
|                         return; | ||||
|                     } | ||||
|                     int minutes; | ||||
|                     if (!int.TryParse(minutesStr, out minutes) || minutes < 1 || minutes > 1440) | ||||
|                     { | ||||
|                         await channel.SendMessageAsync("Invalid value").ConfigureAwait(false); | ||||
|                         return; | ||||
|                     } | ||||
|  | ||||
|                     var repeater = repeaters.GetOrAdd( | ||||
|                         e.Server, | ||||
|                         s => new Repeater | ||||
|                         using (var uow = DbHandler.UnitOfWork()) | ||||
|                         { | ||||
|                             Interval = minutes * 60 * 1000, | ||||
|                             RepeatingChannel = e.Channel, | ||||
|                             RepeatingChannelId = e.Channel.Id, | ||||
|                             RepeatingServerId = e.Server.Id, | ||||
|                         }.Start() | ||||
|                     ); | ||||
|                             uow.Repeaters.Remove(rep); | ||||
|                             await uow.CompleteAsync(); | ||||
|                         } | ||||
|                         await channel.SendMessageAsync("`Stopped repeating a message.`").ConfigureAwait(false); | ||||
|                     } | ||||
|                     else | ||||
|                         await channel.SendMessageAsync("`No message is repeating.`").ConfigureAwait(false); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                     if (!string.IsNullOrWhiteSpace(msg)) | ||||
|                         repeater.RepeatingMessage = msg; | ||||
|  | ||||
|                     repeater.MessageTimer.Stop(); | ||||
|                     repeater.MessageTimer.Start(); | ||||
|  | ||||
|                     await channel.SendMessageAsync(String.Format("👌 Repeating `{0}` every " + | ||||
|                                                               "**{1}** minutes on {2} channel.", | ||||
|                                                               repeater.RepeatingMessage, minutes, repeater.RepeatingChannel)) | ||||
|                                                               .ConfigureAwait(false); | ||||
|                 rep = repeaters.AddOrUpdate(channel.Id, (cid) => | ||||
|                 { | ||||
|                     using (var uow = DbHandler.UnitOfWork()) | ||||
|                     { | ||||
|                         var localRep = new Repeater | ||||
|                         { | ||||
|                             ChannelId = channel.Id, | ||||
|                             GuildId = channel.Guild.Id, | ||||
|                             Interval = TimeSpan.FromMinutes(minutes), | ||||
|                             Message = message, | ||||
|                         }; | ||||
|                         uow.Repeaters.Add(localRep); | ||||
|                         uow.Complete(); | ||||
|                         return localRep; | ||||
|                     } | ||||
|                 }, (cid, old) => | ||||
|                 { | ||||
|                     using (var uow = DbHandler.UnitOfWork()) | ||||
|                     { | ||||
|                         old.Message = message; | ||||
|                         old.Interval = TimeSpan.FromMinutes(minutes); | ||||
|                         uow.Repeaters.Update(old); | ||||
|                         uow.Complete(); | ||||
|                         return old; | ||||
|                     } | ||||
|                 }); | ||||
|         } | ||||
|             } | ||||
|  | ||||
|         public MessageRepeater(DiscordModule module) : base(module) { } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -16,6 +16,7 @@ namespace NadekoBot.Services.Database | ||||
|         IReminderRepository Reminders { get; } | ||||
|         ISelfAssignedRolesRepository SelfAssignedRoles { get; } | ||||
|         IBotConfigRepository BotConfig { get; } | ||||
|         IRepeaterRepository Repeaters { get; } | ||||
|  | ||||
|         int Complete(); | ||||
|         Task<int> CompleteAsync(); | ||||
|   | ||||
							
								
								
									
										16
									
								
								src/NadekoBot/Services/Database/Models/Repeater.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/NadekoBot/Services/Database/Models/Repeater.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Services.Database.Models | ||||
| { | ||||
|     public class Repeater :DbEntity | ||||
|     { | ||||
|         public ulong GuildId { get; set; } | ||||
|         public ulong ChannelId { get; set; } | ||||
|         public string Message { get; set; } | ||||
|         public TimeSpan Interval { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -18,6 +18,7 @@ namespace NadekoBot.Services.Database | ||||
|         public DbSet<Reminder> Reminders { get; set; } | ||||
|         public DbSet<SelfAssignedRole> SelfAssignableRoles { get; set; } | ||||
|         public DbSet<BotConfig> BotConfig { get; set; } | ||||
|         public DbSet<Repeater> Repeaters { get; set; } | ||||
|  | ||||
|         protected override void OnModelCreating(ModelBuilder modelBuilder) | ||||
|         { | ||||
| @@ -63,6 +64,16 @@ namespace NadekoBot.Services.Database | ||||
|                 .IsUnique(); | ||||
|  | ||||
|             #endregion | ||||
|  | ||||
|             #region Repeater | ||||
|  | ||||
|             var repeaterEntity = modelBuilder.Entity<Repeater>(); | ||||
|  | ||||
|             repeaterEntity | ||||
|                 .HasIndex(r => r.ChannelId) | ||||
|                 .IsUnique(); | ||||
|  | ||||
|             #endregion | ||||
|         } | ||||
|         protected abstract override void OnConfiguring(DbContextOptionsBuilder optionsBuilder); | ||||
|     } | ||||
|   | ||||
| @@ -0,0 +1,14 @@ | ||||
| using NadekoBot.Services.Database.Models; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace NadekoBot.Services.Database.Repositories | ||||
| { | ||||
|     public interface IRepeaterRepository : IRepository<Repeater> | ||||
|     { | ||||
|          | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,17 @@ | ||||
| using NadekoBot.Services.Database.Models; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.EntityFrameworkCore; | ||||
|  | ||||
| namespace NadekoBot.Services.Database.Repositories.Impl | ||||
| { | ||||
|     public class RepeaterRepository : Repository<Repeater>, IRepeaterRepository | ||||
|     { | ||||
|         public RepeaterRepository(DbContext context) : base(context) | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -33,6 +33,9 @@ namespace NadekoBot.Services.Database | ||||
|         private IBotConfigRepository _botConfig; | ||||
|         public IBotConfigRepository BotConfig => _botConfig ?? (_botConfig = new BotConfigRepository(_context)); | ||||
|  | ||||
|         private IRepeaterRepository _repeaters; | ||||
|         public IRepeaterRepository Repeaters => _repeaters ?? (_repeaters = new RepeaterRepository(_context)); | ||||
|  | ||||
|         public UnitOfWork(NadekoContext context) | ||||
|         { | ||||
|             _context = context; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user