Start work on gsmeet plugin
This commit is contained in:
		
							parent
							
								
									baad11c9fa
								
							
						
					
					
						commit
						6b45ed1281
					
				
							
								
								
									
										
											BIN
										
									
								
								DiscoBot/98293701175955456-gsmeet.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								DiscoBot/98293701175955456-gsmeet.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -14,6 +14,8 @@ | |||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Discord.Net" Version="2.0.1" /> |     <PackageReference Include="Discord.Net" Version="2.0.1" /> | ||||||
|  |     <PackageReference Include="Google.Apis" Version="1.41.1" /> | ||||||
|  |     <PackageReference Include="Google.Apis.Sheets.v4" Version="1.41.1.1721" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" /> |     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0-preview3-19153-02" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0-preview3-19153-02" /> |     <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.0.0-preview3-19153-02" /> | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview4.19216.3" /> |     <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview4.19216.3" /> | ||||||
|  | |||||||
| @ -41,6 +41,9 @@ namespace DiscoBot.calendar | |||||||
|             // Send list of calendars(channels) |             // Send list of calendars(channels) | ||||||
|             //var calendar = calendarContext.ChannelCalendar.Include(cal => cal.Items).ToList(); |             //var calendar = calendarContext.ChannelCalendar.Include(cal => cal.Items).ToList(); | ||||||
|             var cList = new CalendarList(); |             var cList = new CalendarList(); | ||||||
|  |             // | ||||||
|  |             // TODO: Make all ulong -> String because js can't handle ulong | ||||||
|  |             // | ||||||
|             cList.Calendars = calendarContext.ChannelCalendar.ToList(); |             cList.Calendars = calendarContext.ChannelCalendar.ToList(); | ||||||
|             string str = JsonConvert.SerializeObject(cList); |             string str = JsonConvert.SerializeObject(cList); | ||||||
|             Console.WriteLine(str); |             Console.WriteLine(str); | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								DiscoBot/client_secret.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								DiscoBot/client_secret.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | { | ||||||
|  |   "type": "service_account", | ||||||
|  |   "project_id": "mupitracker", | ||||||
|  |   "private_key_id": "db6f15cff272a6a998563f3a161c54c6312090b2", | ||||||
|  |   "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2K2k6h8t1it/7\ncQ9sCBbHX7tx4xDAA/g6kOn4QkPSO+MG7N64iyPGfw9iliXEKSLNlrsTHqO3o52o\nmNhdQ/RyOkTetmfo2wuWzteMNEyCdyFg02d4SSzndsYYzvHB2fcxWZfPX6cC1K7y\nCOg7O8u0IhNXhdW162uaJ5TXjC6RBzyM6x9yHGPcLAOfQNIKdTS4QN3tOAaSczva\n0pYrIPbknTeKa12ck3cNLMLrppseFKaPAvkqU/I6Bvqe1ajB6HrToBNPwqKudn2q\nk4JuZMUmFux952ZMvwFoCr01bfJg3ATtcWD5dC/rg2aEJ22W5/CNxD0ENYbMYlwj\nqGsogwenAgMBAAECggEAB/nnnhnzBR8DBpnhMHw8LxeYd/iWs6mY1UuiCu4v1QUt\nQBDgAZmKA/dtP4ZOegPJE9JdN42YYoKF9StYEeFXUycM++llrFLm83/z/R4PGYlI\ny1oGRkSB9FKFgvGQsUmvYphHJtvLzrpsPIm6TVmlZio1yZfBDzmTGQlRoYxwP4ZM\nKj9B6ldyhMU+6aMmI8jxWT3GKB9fLg9bgfb5M+tHQ95UkRwYBh4hOObXw5HSOqXC\np4l6pKMlhECHfVKOrL9aBQh1Z2UFEhJjynwnpxx3o51tZmpvbFPMA7M9sz2cdSeY\njpDeuZIDGkTMPEarpmErCBZTM6C38Ine4whEJSJg/QKBgQDgQ0OP3hxsMUj8O6qK\nLRWoPm3oC+mcwrgtHnfydOEKqW7C/rykDUdNWQbUGQmwzGsJ8S1tgQUdkAfwNgRE\nvvYdVki51FiURW/+6+90bh71hItx4FVzq1o0e8Ey/P9D9AIjxaAVEgQT9YtuEh0H\nbt0q6neoVGTdD0jyr4e8TtPPhQKBgQDP8ysXtceYuWe39ElxT4PvqmPl4BlwEAGT\nR3w2s6oGzcvhH+XCD5LhIAwAXHDzYISEMJ/HKCUFKTYnSJAWDkZKuGclZOT/GhMK\nu5zFfacIOuXlazkxrnGpU6nmbMX1rv+kkI++JelKjNaxeBIq0xTzSvIAr0lz9tZ2\nnxIUpw2kOwKBgH3Gu9mwZJh5e8mbXSZp6r+VY+bE55y3yLvlXrhovN5R8IEEhaAs\nolTLHX1PHZQ+0bmdvjCwL8JIyWr7oKE9yKLjhZ5TbeqalxmOEZpnOI3SbLLNcp+Q\n9uKAlfaW1kOyUpDlgcbPd+IJ0M1G82j70KcFIV8TFg61R+B0edgvDbRRAoGAJROh\nOlAB73wXPxhCQ/6+cmv59dGYF3/zF/Rl9EbiaOYmlNQgHhKyyIrzONlCllI+LmeR\nBWxl9V6ctjJc5mHTLJ1mXqd3oPhgLsi2sguuTWxa8yXEA9SrlVpCb8AzJ5P1Jr1T\ns76EsvMbkHbtHk+Wa66QKYkXWqLHKE1CZwZGC2MCgYEAiBa5LaiPRhVL6xPT2pTk\nTUBxkqdI5vTxEXyNGhPoBmqHquFNi5OiHw+yOdJDaJUtGEaSnrkavx4TWqfIxh9n\nUnZ6UtpYp1humQK2ICdpyH+k+OacwCSFjm2ui4576eV75jnehVm17OkVAQa2KrBO\niS2F+8BEb+hiUTSlb3wqiFs=\n-----END PRIVATE KEY-----\n", | ||||||
|  |   "client_email": "discobot@mupitracker.iam.gserviceaccount.com", | ||||||
|  |   "client_id": "105431706557302750404", | ||||||
|  |   "auth_uri": "https://accounts.google.com/o/oauth2/auth", | ||||||
|  |   "token_uri": "https://oauth2.googleapis.com/token", | ||||||
|  |   "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | ||||||
|  |   "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/discobot%40mupitracker.iam.gserviceaccount.com" | ||||||
|  | } | ||||||
							
								
								
									
										232
									
								
								DiscoBot/gsmeet/GSMeet.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								DiscoBot/gsmeet/GSMeet.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,232 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.IO; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Net.WebSockets; | ||||||
|  | using System.ServiceModel.Syndication; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | using System.Timers; | ||||||
|  | using System.Xml; | ||||||
|  | using Discord; | ||||||
|  | using Discord.WebSocket; | ||||||
|  | using Google.Apis.Auth.OAuth2; | ||||||
|  | using Google.Apis.Sheets.v4; | ||||||
|  | 
 | ||||||
|  | namespace DiscoBot.gsmeet | ||||||
|  | { | ||||||
|  |     public class GSMeet : IModule | ||||||
|  |     { | ||||||
|  |         string IModule.Name { get => "GSMeet"; set => throw new NotImplementedException(); } | ||||||
|  |         private SocketGuild guild; | ||||||
|  |         private GSMeetContext gsmeetContext; | ||||||
|  |         private Dictionary<string, Timer> timers = new Dictionary<string, Timer>(); | ||||||
|  |         private List<WebSocket> webSockets = new List<WebSocket>(); | ||||||
|  | 
 | ||||||
|  |         public Dictionary<string, Func<SocketMessage, string[], Task>> Commands { get; set; } = new Dictionary<string, Func<SocketMessage, string[], Task>>(); | ||||||
|  | 
 | ||||||
|  |         private static readonly string[] Scopes = { SheetsService.Scope.Spreadsheets }; | ||||||
|  |         private static readonly string ApplicationName = "DiscoBot"; | ||||||
|  |         private SheetsService service; | ||||||
|  | 
 | ||||||
|  |         public GSMeet(SocketGuild guild) | ||||||
|  |         { | ||||||
|  |             this.guild = guild; | ||||||
|  |             gsmeetContext = new GSMeetContext(guild.Id); | ||||||
|  |             gsmeetContext.Database.EnsureCreated(); | ||||||
|  | 
 | ||||||
|  |             GoogleCredential credential; | ||||||
|  |             using(var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read)) | ||||||
|  |             { | ||||||
|  |                 credential = GoogleCredential.FromStream(stream).CreateScoped(Scopes); | ||||||
|  |             } | ||||||
|  |             service = new SheetsService(new Google.Apis.Services.BaseClientService.Initializer() | ||||||
|  |             { | ||||||
|  |                 HttpClientInitializer = credential, | ||||||
|  |                 ApplicationName = ApplicationName | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             foreach(var f in gsmeetContext.GSheets) | ||||||
|  |             { | ||||||
|  |                 InitializeSheet(f); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             Commands.Add("gsmeetadd", HandleGSMeetAddCommand); | ||||||
|  |             Commands.Add("gsmeetdel", HandleGSMeetDelCommand); | ||||||
|  |             Commands.Add("gsmeetlist", HandleGSMeetListCommand); | ||||||
|  |             Commands.Add("gsmeetdebug", HandleGSMeetDebugCommand); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task InitializeSheet(GSheet sheet) | ||||||
|  |         { | ||||||
|  |             Console.WriteLine("Found sheet " + sheet.Name); | ||||||
|  |             Timer timer = new Timer(sheet.CheckInterval.TotalMilliseconds); | ||||||
|  |             timer.AutoReset = true; | ||||||
|  |             timer.Elapsed += async (sender, e) => | ||||||
|  |             { | ||||||
|  |                 await Task.Run(() => HandleSheetCheck(sheet)); | ||||||
|  |             }; | ||||||
|  |             timer.Start(); | ||||||
|  |             timers.Add(sheet.Name, timer); | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task DeinitializeSheets(GSheet sheet) | ||||||
|  |         { | ||||||
|  |             /* | ||||||
|  |             Timer t = timers[feed.Name]; | ||||||
|  |             t.Stop(); | ||||||
|  |             timers.Remove(feed.Name); | ||||||
|  |             */ | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task HandleSheetCheck(GSheet sheet) | ||||||
|  |         { | ||||||
|  |             SocketTextChannel c = guild.Channels.Where(g => g.Id == sheet.Channel).Single() as SocketTextChannel; | ||||||
|  |             c.SendMessageAsync("Checking sheet " + sheet.SheetId + " :3"); | ||||||
|  |             var values = FetchRangeFromSheet(sheet.SheetId, $"{sheet.SheetName}!A1:I10"); | ||||||
|  |             if (values == null || values.Count < 1) | ||||||
|  |             { | ||||||
|  |                 c.SendMessageAsync("No values found."); | ||||||
|  |                 return Task.CompletedTask; | ||||||
|  |             } | ||||||
|  |             var str = ""; | ||||||
|  |             foreach (var row in values) | ||||||
|  |             { | ||||||
|  |                 foreach (var col in row) | ||||||
|  |                 { | ||||||
|  |                     str += col + "| "; | ||||||
|  |                 } | ||||||
|  |                 str += "\n"; | ||||||
|  |             } | ||||||
|  |             c.SendMessageAsync("Result: " + str); | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task HandleGSMeetAddCommand(SocketMessage msg, string[] parameters) | ||||||
|  |         { | ||||||
|  |             var gchan = msg.Channel as IGuildChannel; | ||||||
|  |             string name = parameters[1]; | ||||||
|  |             string sheetId = parameters[2]; | ||||||
|  |             string sheetName = parameters[3]; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 int timeSec = Int32.Parse(parameters[4]); | ||||||
|  |                 GSheet sheet = new GSheet(); | ||||||
|  |                 sheet.Channel = gchan.Id; | ||||||
|  |                 sheet.Name = name; | ||||||
|  |                 sheet.SheetId = sheetId; | ||||||
|  |                 sheet.SheetName = sheetName; | ||||||
|  |                 sheet.LastChecked = DateTimeOffset.Now; | ||||||
|  |                 sheet.CheckInterval = new TimeSpan(0, 0, timeSec); | ||||||
|  |                 gsmeetContext.GSheets.Add(sheet); | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     gsmeetContext.SaveChanges(); | ||||||
|  |                     InitializeSheet(sheet); | ||||||
|  |                     msg.Channel.SendMessageAsync("Sheet " + sheet.Name + " with id " + sheet.SheetId + " saved."); | ||||||
|  |                 } | ||||||
|  |                 catch (InvalidOperationException) | ||||||
|  |                 { | ||||||
|  |                     msg.Channel.SendMessageAsync("Unable to save sheet feed."); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             catch (FormatException) | ||||||
|  |             { | ||||||
|  |                 msg.Channel.SendMessageAsync("Unable to save sheet. Invalid check time."); | ||||||
|  |             } | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task HandleGSMeetListCommand(SocketMessage msg, string[] parameters) | ||||||
|  |         { | ||||||
|  |             /* | ||||||
|  |             List<RssFeed> feeds = rssContext.RssFeeds.Where(f => f.Channel == msg.Channel.Id).ToList(); | ||||||
|  |             List<string> m = new List<string>(); | ||||||
|  |             m.Add("Feeds for this channel are:"); | ||||||
|  |             m.Add("Name | URL | CheckInterval | LastChecked"); | ||||||
|  |             msg.Channel.SendMessageAsync(string.Join("\n", m)); | ||||||
|  |             m = new List<string>(); | ||||||
|  |             int cnt = 0; | ||||||
|  |             foreach (var f in feeds) | ||||||
|  |             { | ||||||
|  |                 m.Add("- " + f.Name + " | " + f.Url + " | " + f.CheckInterval + " | " + f.LastChecked); | ||||||
|  |                 cnt++; | ||||||
|  |                 if(cnt > 4) | ||||||
|  |                 { | ||||||
|  |                     cnt = 0; | ||||||
|  |                     msg.Channel.SendMessageAsync(string.Join("\n", m)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if(cnt > 0) | ||||||
|  |                 msg.Channel.SendMessageAsync(string.Join("\n", m)); | ||||||
|  |                 */ | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task HandleGSMeetDelCommand(SocketMessage msg, string[] parameters) | ||||||
|  |         { | ||||||
|  |             /* | ||||||
|  |             var gchan = msg.Channel as IGuildChannel; | ||||||
|  |             string name = parameters[1]; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 RssFeed f = rssContext.RssFeeds.Where(f => f.Name == name).Single(); | ||||||
|  |                 rssContext.Remove(f); | ||||||
|  |                 rssContext.SaveChanges(); | ||||||
|  |                 DeinitializeFeed(f); | ||||||
|  |                 msg.Channel.SendMessageAsync("Removed feed " + f.Name); | ||||||
|  |             } catch(InvalidOperationException) | ||||||
|  |             { | ||||||
|  |                 msg.Channel.SendMessageAsync("Could not find feed " + name); | ||||||
|  |             } | ||||||
|  |             */ | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Task HandleGSMeetDebugCommand(SocketMessage msg, string[] parameters) | ||||||
|  |         { | ||||||
|  |             var gchan = msg.Channel as IGuildChannel; | ||||||
|  |             string name = parameters[1]; | ||||||
|  |             string sheetId = parameters[2]; | ||||||
|  |             string sheetName = parameters[3]; | ||||||
|  | 
 | ||||||
|  |             var values = FetchRangeFromSheet(sheetId, $"{sheetName}!A1:I10"); | ||||||
|  |             if(values == null || values.Count < 1) | ||||||
|  |             { | ||||||
|  |                 msg.Channel.SendMessageAsync("No values found."); | ||||||
|  |                 return Task.CompletedTask; | ||||||
|  |             } | ||||||
|  |             var str = ""; | ||||||
|  |             foreach(var row in values) | ||||||
|  |             { | ||||||
|  |                 foreach(var col in row) | ||||||
|  |                 { | ||||||
|  |                     str += col + "| "; | ||||||
|  |                 } | ||||||
|  |                 str += "\n"; | ||||||
|  |             } | ||||||
|  |             msg.Channel.SendMessageAsync("Result: "+str); | ||||||
|  | 
 | ||||||
|  |             return Task.CompletedTask; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private IList<IList<object>> FetchRangeFromSheet(string sheetId, string range) | ||||||
|  |         { | ||||||
|  |             var request = service.Spreadsheets.Values.Get(sheetId, range); | ||||||
|  |             var response = request.Execute(); | ||||||
|  |             return response.Values; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public void Initialize() | ||||||
|  |         { | ||||||
|  |             Console.WriteLine("Initializing gsmeet..."); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public async Task OnNewWebSocketAsync(WebSocket ws, TaskCompletionSource<object> tcs) | ||||||
|  |         { | ||||||
|  |             Console.WriteLine("Calendar " + guild.Id + " has a new websocket."); | ||||||
|  |             webSockets.Add(ws); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								DiscoBot/gsmeet/GSMeetContext.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								DiscoBot/gsmeet/GSMeetContext.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | using Microsoft.EntityFrameworkCore; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.ComponentModel.DataAnnotations; | ||||||
|  | using System.Linq; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  | 
 | ||||||
|  | namespace DiscoBot.gsmeet | ||||||
|  | { | ||||||
|  |     public class GSMeetContext : DbContext | ||||||
|  |     { | ||||||
|  |         private ulong guildId; | ||||||
|  |         public DbSet<GSheet> GSheets { get; set; } | ||||||
|  | 
 | ||||||
|  |         public GSMeetContext(ulong guildId) | ||||||
|  |         { | ||||||
|  |             this.guildId = guildId; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | ||||||
|  |         { | ||||||
|  |             optionsBuilder.UseSqlite("Data Source=" + guildId + "-gsmeet.db"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public class GSheet | ||||||
|  |     { | ||||||
|  |         [Key] | ||||||
|  |         public string Name { get; set; } | ||||||
|  |         public string SheetId { get; set; } | ||||||
|  |         public string SheetName { get; set; } | ||||||
|  |         public ulong Channel { get; set; } | ||||||
|  |         public TimeSpan CheckInterval { get; set; } | ||||||
|  |         public DateTimeOffset LastChecked { get; set; } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public class GSSignup | ||||||
|  |     { | ||||||
|  |         public string DiscordTag { get; set; } | ||||||
|  |         public string Name { get; set; } | ||||||
|  |         public string[] Signups { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user