amki
5 years ago
7 changed files with 292 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@ -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" |
|||
} |
@ -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); |
|||
} |
|||
} |
|||
} |
@ -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…
Reference in new issue