diff --git a/DiscoBot/98293701175955456-calendar.db b/DiscoBot/98293701175955456-calendar.db index 0b98d38..c1c315c 100644 Binary files a/DiscoBot/98293701175955456-calendar.db and b/DiscoBot/98293701175955456-calendar.db differ diff --git a/DiscoBot/98293701175955456-rss.db b/DiscoBot/98293701175955456-rss.db index 5e70b8d..5854aef 100644 Binary files a/DiscoBot/98293701175955456-rss.db and b/DiscoBot/98293701175955456-rss.db differ diff --git a/DiscoBot/ClientApp/src/app/calendar/calendar.component.html b/DiscoBot/ClientApp/src/app/calendar/calendar.component.html index cb44fd3..e148b22 100644 --- a/DiscoBot/ClientApp/src/app/calendar/calendar.component.html +++ b/DiscoBot/ClientApp/src/app/calendar/calendar.component.html @@ -1,7 +1,10 @@

Calendar

-

This component demonstrates fetching data from the server.

-

Loading...

+
+
+ {{calendar.Id}} ||{{calendar.ChannelId}} +
+
diff --git a/DiscoBot/ClientApp/src/app/calendar/calendar.component.ts b/DiscoBot/ClientApp/src/app/calendar/calendar.component.ts index 2c78f82..856b742 100644 --- a/DiscoBot/ClientApp/src/app/calendar/calendar.component.ts +++ b/DiscoBot/ClientApp/src/app/calendar/calendar.component.ts @@ -7,25 +7,47 @@ import { HttpClient } from '@angular/common/http'; }) export class CalendarComponent { public forecasts: CalendarForecast[]; + public webSocket; + public calendars; - constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) { - console.log("ws connecting to ws" + baseUrl.substring(4, baseUrl.length) + "ws/calendar"); - var ws = new WebSocket("ws" + baseUrl.substring(4, baseUrl.length) + "ws/calendar"); - - ws.onopen = function () { + getCalendar(id) { + console.log("getCalendar: ", id); + this.webSocket.send('{Op: "calget", ChannelId: ' + id + '}'); + } - // Web Socket is connected, send data using send() - ws.send('{op:"connect", gid: 98293701175955456, module:"calendar"}'); - alert("Message is sent..."); + handleCalendarList(cList) { + console.log("Setting calendars: ", cList); + this.calendars = cList; + }; + constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) { + var self = this; + console.log("ws connecting to ws" + baseUrl.substring(4, baseUrl.length) + "ws/calendar"); + this.webSocket = new WebSocket("ws" + baseUrl.substring(4, baseUrl.length) + "ws/calendar"); + + + this.webSocket.onopen = function () { + // TODO: Stop hardcoding gid, get this from url? + self.webSocket.send('{Op:"connect", GId: 98293701175955456, Module:"calendar"}'); + setInterval(() => { + self.webSocket.send('{Op:"ping"}'); + },120000); }; - ws.onmessage = function (evt) { - var received_msg = evt.data; - alert(received_msg); + this.webSocket.onmessage = function (evt) { + console.log("evt: ", evt); + var msg = JSON.parse(evt.data); + console.log(msg); + switch (msg.Op) { + case "CalendarList": + self.handleCalendarList(msg.Calendars); + break; + default: + console.log("Unknown opcode: ", msg); + } }; - ws.onclose = function () { + this.webSocket.onclose = function () { // websocket is closed. alert("Connection is closed..."); diff --git a/DiscoBot/ClientApp/src/app/home/home.component.html b/DiscoBot/ClientApp/src/app/home/home.component.html index 771cae3..d9c9b49 100644 --- a/DiscoBot/ClientApp/src/app/home/home.component.html +++ b/DiscoBot/ClientApp/src/app/home/home.component.html @@ -11,5 +11,6 @@
  • Angular CLI integration. In development mode, there's no need to run ng serve. It runs in the background automatically, so your client-side resources are dynamically built on demand and the page refreshes when you modify any file.
  • Efficient production builds. In production mode, development-time features are disabled, and your dotnet publish configuration automatically invokes ng build to produce minified, ahead-of-time compiled JavaScript files.
  • +Dübbel Kalenderio -

    The ClientApp subdirectory is a standard Angular CLI application. If you open a command prompt in that directory, you can run any ng command (e.g., ng test), or use npm to install extra packages into it.

    + diff --git a/DiscoBot/DisBot.cs b/DiscoBot/DisBot.cs index 71060d1..1cce17d 100644 --- a/DiscoBot/DisBot.cs +++ b/DiscoBot/DisBot.cs @@ -30,25 +30,7 @@ namespace DiscoBot this.wsC = wsC; } - private async Task Echo(HttpContext context, WebSocket webSocket) - { - var buffer = new byte[1024 * 4]; - - WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); - // Clientpaket handlen - // WebSocket an richtiges module zustellen - while (!result.CloseStatus.HasValue) - { - var msgBytes = Encoding.UTF8.GetBytes("penis"); - Console.WriteLine(msgBytes); - await webSocket.SendAsync(new ArraySegment(msgBytes, 0, msgBytes.Length), result.MessageType, result.EndOfMessage, CancellationToken.None); - - result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); - } - //await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); - } - - public async Task HandleWebsocket(HttpContext context) + public async Task HandleWebsocket(HttpContext context, TaskCompletionSource tcs) { Console.WriteLine("Handling Websocket to "+ context.Request.Path); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); @@ -59,7 +41,9 @@ namespace DiscoBot { if (m.Name == login.Module) { - m.OnNewWebSocket(webSocket); +#pragma warning disable CS4014 // Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt. + m.OnNewWebSocketAsync(webSocket, tcs); +#pragma warning restore CS4014 // Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt. } } } @@ -74,6 +58,13 @@ namespace DiscoBot return line; } + public static async void SendStringViaWebSocket(WebSocket ws, string str) + { + var msgBytes = Encoding.UTF8.GetBytes(str); + Console.WriteLine("Sending: "+str); + await ws.SendAsync(new ArraySegment(msgBytes, 0, msgBytes.Length), WebSocketMessageType.Text, true, CancellationToken.None); + } + public async void Initialize() { Console.WriteLine("In init!"); diff --git a/DiscoBot/IModule.cs b/DiscoBot/IModule.cs index b36078d..745f818 100644 --- a/DiscoBot/IModule.cs +++ b/DiscoBot/IModule.cs @@ -12,6 +12,6 @@ namespace DiscoBot Dictionary> Commands { get; set; } string Name { get; set; } void Initialize(); - void OnNewWebSocket(WebSocket ws); + Task OnNewWebSocketAsync(WebSocket ws, TaskCompletionSource tcs); } } diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs index 81b2f8e..27e5527 100644 --- a/DiscoBot/Program.cs +++ b/DiscoBot/Program.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Console; namespace DiscoBot { diff --git a/DiscoBot/Startup.cs b/DiscoBot/Startup.cs index 9c9e0a7..e343b68 100644 --- a/DiscoBot/Startup.cs +++ b/DiscoBot/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.SpaServices.AngularCli; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Net.WebSockets; @@ -31,6 +32,7 @@ namespace DiscoBot services.AddMvc() .AddNewtonsoftJson(); + // In production, the Angular files will be served from this directory services.AddSpaStaticFiles(configuration => { @@ -75,7 +77,9 @@ namespace DiscoBot { if (context.WebSockets.IsWebSocketRequest) { - await diBot.HandleWebsocket(context); + var socketFinishedTcs = new TaskCompletionSource(); + await diBot.HandleWebsocket(context, socketFinishedTcs); + await socketFinishedTcs.Task; } else { @@ -107,7 +111,7 @@ namespace DiscoBot if (env.IsDevelopment()) { - spa.UseAngularCliServer(npmScript: "start"); + spa.UseProxyToSpaDevelopmentServer("http://localhost:4200"); } }); } diff --git a/DiscoBot/appsettings.json b/DiscoBot/appsettings.json index 8239cbe..c313e52 100644 --- a/DiscoBot/appsettings.json +++ b/DiscoBot/appsettings.json @@ -1,8 +1,12 @@ { "Logging": { - "LogLevel": { - "Default": "Warning" - } + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" }, + "Console": { + "IncludeScopes": true + } + }, "AllowedHosts": "*" } diff --git a/DiscoBot/calendar/CalController.cs b/DiscoBot/calendar/CalController.cs index 239ec6f..ff42bb9 100644 --- a/DiscoBot/calendar/CalController.cs +++ b/DiscoBot/calendar/CalController.cs @@ -15,10 +15,8 @@ namespace DiscoBot.calendar // GET: api/Cal [HttpGet("{guild}", Name = "Get")] public JsonResult Get(ulong guild) - { - CalendarContext calendarContext = new CalendarContext(guild); - List items = calendarContext.CalendarItems.Include(i => i.Attendance).ToList(); - return Json(items); + { + return Json(""); } // POST: api/Cal diff --git a/DiscoBot/calendar/Calendar.cs b/DiscoBot/calendar/Calendar.cs index 87785e0..3eedadd 100644 --- a/DiscoBot/calendar/Calendar.cs +++ b/DiscoBot/calendar/Calendar.cs @@ -5,6 +5,8 @@ using System.Net.WebSockets; using System.Threading.Tasks; using Discord; using Discord.WebSocket; +using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; namespace DiscoBot.calendar { @@ -32,10 +34,44 @@ namespace DiscoBot.calendar Console.WriteLine("Initializing calendar..."); } - public void OnNewWebSocket(WebSocket ws) + public async Task OnNewWebSocketAsync(WebSocket ws, TaskCompletionSource tcs) { Console.WriteLine("Calendar " + guild.Id + " has a new websocket."); webSockets.Add(ws); + // Send list of calendars(channels) + //var calendar = calendarContext.ChannelCalendar.Include(cal => cal.Items).ToList(); + var cList = new CalendarList(); + cList.Calendars = calendarContext.ChannelCalendar.ToList(); + string str = JsonConvert.SerializeObject(cList); + Console.WriteLine(str); + DisBot.SendStringViaWebSocket(ws, str); +#pragma warning disable CS4014 // Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt. + Task.Run(async () => + { + Console.WriteLine("Starting websocket handling..."); + while (ws.State != WebSocketState.Closed) + { + string msg = await DisBot.ReadOneStringFromWebSocket(ws); + var op = JsonConvert.DeserializeObject(msg); + switch (op.Op) + { + case "calget": + var calGet = JsonConvert.DeserializeObject(msg); + Console.WriteLine("ChannelID:" + calGet.ChannelId); + var calendarWS = new CalendarWS(); + var temp = calendarContext.ChannelCalendar.FirstOrDefault(); + calendarWS.Op = calGet.Op; + DisBot.SendStringViaWebSocket(ws, JsonConvert.SerializeObject(calendarWS)); + break; + default: + Console.WriteLine("Unknown opcode: " + op.Op); + break; + } + } + Console.WriteLine("Websocket handling stopped..."); + tcs.TrySetResult(new object()); + }); +#pragma warning restore CS4014 // Da auf diesen Aufruf nicht gewartet wird, wird die Ausführung der aktuellen Methode vor Abschluss des Aufrufs fortgesetzt. } private Task HandleTestCommand(SocketMessage msg, string[] parameters) @@ -56,6 +92,14 @@ namespace DiscoBot.calendar try { var gchan = msg.Channel as IGuildChannel; + var calendar = calendarContext.ChannelCalendar.FirstOrDefault(cal => cal.ChannelId == gchan.Id); + if(calendar == null) + { + calendar = new ChannelCalendar(); + calendar.ChannelId = gchan.Id; + calendar.Moderated = false; + calendarContext.Add(calendar); + } string name = parameters[1]; string date = parameters[2]; string comment = parameters[3]; @@ -70,8 +114,9 @@ namespace DiscoBot.calendar attendance.Attendee = msg.Author.Id; attendance.Attending = Attendance.Attending; calItem.Attendance.Add(attendance); - calendarContext.CalendarItems.Add(calItem); + calendar.Items.Add(calItem); calendarContext.SaveChanges(); + msg.Channel.SendMessageAsync("Event "+ calItem.Name + " has been added."); } catch(FormatException) { diff --git a/DiscoBot/calendar/CalendarContext.cs b/DiscoBot/calendar/CalendarContext.cs index aa845be..c2e0335 100644 --- a/DiscoBot/calendar/CalendarContext.cs +++ b/DiscoBot/calendar/CalendarContext.cs @@ -11,8 +11,7 @@ namespace DiscoBot.calendar public class CalendarContext : DbContext { private ulong guildId; - public DbSet CalendarItems { get; set; } - + public DbSet ChannelCalendar { get; set; } public CalendarContext(ulong guildId) { this.guildId = guildId; @@ -24,6 +23,15 @@ namespace DiscoBot.calendar } } + public class ChannelCalendar + { + [Key] + public ulong Id { get; set; } + public ulong ChannelId { get; set; } + public List Items { get; set; } = new List(); + public bool Moderated { get; set; } + } + public class CalendarItemAttendance { [Key] diff --git a/DiscoBot/calendar/JSONObjects.cs b/DiscoBot/calendar/JSONObjects.cs index d2e4619..73c5f2b 100644 --- a/DiscoBot/calendar/JSONObjects.cs +++ b/DiscoBot/calendar/JSONObjects.cs @@ -5,10 +5,37 @@ using System.Threading.Tasks; namespace DiscoBot.calendar { + public class Opcode + { + public string Op { get; set; } + } public class Login { - // {op:"connect", gid: 324984732895, module:"calendar"} + // {Op:"connect", GId: 324984732895, Module:"calendar"} public string Op { get; set; } public ulong Gid { get; set; } public string Module { get; set; } } + + public class CalendarList + { + // {Op: "CalendarList, Calendars: []} + public string Op { get; set; } + public List Calendars { get; set; } + public CalendarList() + { + this.Op = "CalendarList"; + } + } + public class CalendarWS + { + public string Op { get; set; } + public ChannelCalendar Calendar { get; set; } + } + + public class CalGet + { + // {Op:"calget", ChannelId: 239180890231} + public string Op { get; set; } + public ulong ChannelId { get; set; } + } } diff --git a/DiscoBot/rss/Rss.cs b/DiscoBot/rss/Rss.cs index 3aea0de..14811e3 100644 --- a/DiscoBot/rss/Rss.cs +++ b/DiscoBot/rss/Rss.cs @@ -43,7 +43,10 @@ namespace DiscoBot.rss Console.WriteLine("Found feed " + feed.Name); Timer timer = new Timer(feed.CheckInterval.TotalMilliseconds); timer.AutoReset = true; - timer.Elapsed += async (sender, e) => await HandleFeedCheck(feed); + timer.Elapsed += async (sender, e) => + { + await Task.Run(() => HandleFeedCheck(feed)); + }; timer.Start(); timers.Add(feed.Name, timer); return Task.CompletedTask; @@ -208,7 +211,7 @@ namespace DiscoBot.rss Console.WriteLine("Initializing rss..."); } - public void OnNewWebSocket(WebSocket ws) + public async Task OnNewWebSocketAsync(WebSocket ws, TaskCompletionSource tcs) { Console.WriteLine("Calendar " + guild.Id + " has a new websocket."); webSockets.Add(ws);