From 6b45ed12814e97ac99723f5ca65e0182f31f08bd Mon Sep 17 00:00:00 2001 From: amki Date: Mon, 30 Sep 2019 18:57:42 +0200 Subject: [PATCH] Start work on gsmeet plugin --- DiscoBot/98293701175955456-gsmeet.db | Bin 0 -> 12288 bytes DiscoBot/98293701175955456-rss.db | Bin 20480 -> 20480 bytes DiscoBot/DiscoBot.csproj | 2 + DiscoBot/calendar/Calendar.cs | 3 + DiscoBot/client_secret.json | 12 ++ DiscoBot/gsmeet/GSMeet.cs | 232 +++++++++++++++++++++++++++ DiscoBot/gsmeet/GSMeetContext.cs | 43 +++++ 7 files changed, 292 insertions(+) create mode 100644 DiscoBot/98293701175955456-gsmeet.db create mode 100644 DiscoBot/client_secret.json create mode 100644 DiscoBot/gsmeet/GSMeet.cs create mode 100644 DiscoBot/gsmeet/GSMeetContext.cs diff --git a/DiscoBot/98293701175955456-gsmeet.db b/DiscoBot/98293701175955456-gsmeet.db new file mode 100644 index 0000000000000000000000000000000000000000..3e259541b6281245bf655ee6c646c24fef63adec GIT binary patch literal 12288 zcmeI%!EVzq7zc1CgB2=uWrt}(6_S+`h;>R*I!I4sA)BIQZAk;8r^;OonP@X@@nF5e z3-B5|z#d|+!HqZI$d@Xqw$pAL(EpPy$FV;<{@s!c-i9Yi@{gzIGog5kJz~1fUUSYE z)2XgdEkmP=du4~(ynk2dYcQ^F8QQS57(^{2N7+o=w29Ny@G4J-M zz6(R{^}2&Na)WNnjsC%CnbVJgLpK`o1An+xq%ZagCglp0eQV_A>Nm!`M5L*l8l1N9 z_x)(Ob(!oX^7wO*DtZ1z(6n2RSI!AVrWW($a{J-{wd%8`zPjl)G&A4f%NW zNl(d4Sx2o|Jl;v(ygwGvZoJp`&K$=++7m(aRoWNxmrZAW`Dx-O}Z|GxhD zi?OO{cBr&W+q9gf=`>p=w_bJHR>yX>U)c6eyWM_n+BBz1=hEo^JQV~4AOHafKmY;| YfB*y_009U<00RG+KxJj)Vg8BXFEpo!Q2+n{ literal 0 HcmV?d00001 diff --git a/DiscoBot/98293701175955456-rss.db b/DiscoBot/98293701175955456-rss.db index 5854aef47b055ac8aa5e395aa20abb5b85427f7c..e13d6ecf54e24bb71ebbe5eca6226dd4519770ef 100644 GIT binary patch delta 295 zcmZozz}T>Wae_4CuZc3wjK4M}Y}4o9;o$D(R^vK2SwTQ~v!lT!E?!GrBU1$fBP$al zD^rWf3f2LlKoKJaLsKgwGb{gt&B|}GCa>11hUy= z{Zooc(-ZR&bF#VF)Pa2aNispg=DG&v3I=9YhCpNlQ9ilUCJtz&p``*)(A31r#9;CR zn*xX<3=OP|EUgSJCdb;w2}7(hu`)KYGO&c|JtrFmRcUSobf2N&WJ9|OxQHppp_8}S o1&BlRT37)MG%Wae_4Cmx(gYj9)e;Y}4o9{=wbNt;Th5vVwr}W=DfdT)bwwh87Bj##Y9r zR;Ff?6|4h9!6HV+R;H#vL2UyAD+2?b+{vxh2?9VFa|I(qD^p{j7*J;NSLq54o@Wdk z`E0WOlS^&lcujSU3=|AatxPPej4dWVuql9;Z)9L)Xl7+-Iyu%hP8edNsg + + diff --git a/DiscoBot/calendar/Calendar.cs b/DiscoBot/calendar/Calendar.cs index 3eedadd..611a8bb 100644 --- a/DiscoBot/calendar/Calendar.cs +++ b/DiscoBot/calendar/Calendar.cs @@ -41,6 +41,9 @@ namespace DiscoBot.calendar // Send list of calendars(channels) //var calendar = calendarContext.ChannelCalendar.Include(cal => cal.Items).ToList(); var cList = new CalendarList(); + // + // TODO: Make all ulong -> String because js can't handle ulong + // cList.Calendars = calendarContext.ChannelCalendar.ToList(); string str = JsonConvert.SerializeObject(cList); Console.WriteLine(str); diff --git a/DiscoBot/client_secret.json b/DiscoBot/client_secret.json new file mode 100644 index 0000000..619ceea --- /dev/null +++ b/DiscoBot/client_secret.json @@ -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" +} diff --git a/DiscoBot/gsmeet/GSMeet.cs b/DiscoBot/gsmeet/GSMeet.cs new file mode 100644 index 0000000..34f7e67 --- /dev/null +++ b/DiscoBot/gsmeet/GSMeet.cs @@ -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 timers = new Dictionary(); + private List webSockets = new List(); + + public Dictionary> Commands { get; set; } = new Dictionary>(); + + 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 feeds = rssContext.RssFeeds.Where(f => f.Channel == msg.Channel.Id).ToList(); + List m = new List(); + m.Add("Feeds for this channel are:"); + m.Add("Name | URL | CheckInterval | LastChecked"); + msg.Channel.SendMessageAsync(string.Join("\n", m)); + m = new List(); + 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> 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 tcs) + { + Console.WriteLine("Calendar " + guild.Id + " has a new websocket."); + webSockets.Add(ws); + } + } +} diff --git a/DiscoBot/gsmeet/GSMeetContext.cs b/DiscoBot/gsmeet/GSMeetContext.cs new file mode 100644 index 0000000..2e78e10 --- /dev/null +++ b/DiscoBot/gsmeet/GSMeetContext.cs @@ -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 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; } + } +}