Browse Source

Start work on gsmeet plugin

master
amki 5 years ago
parent
commit
6b45ed1281
  1. BIN
      DiscoBot/98293701175955456-gsmeet.db
  2. BIN
      DiscoBot/98293701175955456-rss.db
  3. 2
      DiscoBot/DiscoBot.csproj
  4. 3
      DiscoBot/calendar/Calendar.cs
  5. 12
      DiscoBot/client_secret.json
  6. 232
      DiscoBot/gsmeet/GSMeet.cs
  7. 43
      DiscoBot/gsmeet/GSMeetContext.cs

BIN
DiscoBot/98293701175955456-gsmeet.db

Binary file not shown.

BIN
DiscoBot/98293701175955456-rss.db

Binary file not shown.

2
DiscoBot/DiscoBot.csproj

@ -14,6 +14,8 @@
<ItemGroup>
<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.SpaServices.Extensions" Version="3.0.0-preview3-19153-02" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview4.19216.3" />

3
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);

12
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"
}

232
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<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

@ -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…
Cancel
Save