From e4998d433dd49cc164632875670da08945d7f6f3 Mon Sep 17 00:00:00 2001 From: Marco Realacci Date: Wed, 31 Jan 2024 04:56:23 +0100 Subject: [PATCH] Add local images support ...finally! --- Bot/Modules/OttoLinux/BotGame.cs | 23 ++++++++-- Bot/Modules/OttoLinux/PhotoServer.cs | 66 ++++++++++++++++++++++++++++ Bot/Modules/OttoLinux/Question.cs | 2 + Bot/Program.cs | 11 +++-- Bot/Telegram/TelegramBot.cs | 2 +- 5 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 Bot/Modules/OttoLinux/PhotoServer.cs diff --git a/Bot/Modules/OttoLinux/BotGame.cs b/Bot/Modules/OttoLinux/BotGame.cs index 69ca0b5..92c0939 100644 --- a/Bot/Modules/OttoLinux/BotGame.cs +++ b/Bot/Modules/OttoLinux/BotGame.cs @@ -16,6 +16,7 @@ namespace SoUnBot.Modules.OttoLinux private string _questionsPath; private string _name; private bool _lock; + private string _webBaseURL; private Dictionary _scores; private Dictionary _playingQuestions; @@ -24,12 +25,13 @@ namespace SoUnBot.Modules.OttoLinux private static Random _rng = new Random(); - public BotGame(AccessManager accessManager, string name, string path, bool locke, int version = 1) + public BotGame(AccessManager accessManager, string name, string path, bool locke, string webBaseUrl, int version = 1) { _accessManager = accessManager; _questionsPath = path; _name = name; _lock = locke; + _webBaseURL = webBaseUrl; _questions = new List(); _scores = new Dictionary(); @@ -416,13 +418,26 @@ namespace SoUnBot.Modules.OttoLinux }; string quest = qst.Quest; + if (qst.Image != "") + { + try + { + await botClient.SendPhotoAsync( + chatId: uid, + photo: qst.Image.Contains("http") ? qst.Image : _webBaseURL + "/" + qst.Image); + } + catch(Exception e) + { + CatchParsingError(botClient, quest, uid, e); + } + } if (qst.Quest.StartsWith("img=")) { try { await botClient.SendPhotoAsync( - chatId: uid, - photo: quest.Substring(4).Split('\n')[0]); + chatId: uid, + photo: quest.Substring(4).Split('\n')[0].Contains("http") ? quest.Substring(4).Split('\n')[0] : _webBaseURL + "/" + quest.Substring(4).Split('\n')[0]); } catch(Exception e) { @@ -453,7 +468,7 @@ namespace SoUnBot.Modules.OttoLinux { await botClient.SendPhotoAsync( chatId: uid, - photo: qst.Answers[i].Split('\n')[0].Substring(4), + photo: qst.Answers[i].Split('\n')[0].Substring(4).Contains("http") ? qst.Answers[i].Split('\n')[0].Substring(4) : _webBaseURL + "/" + qst.Answers[i].Split('\n')[0].Substring(4), caption: "✏️ Risposta " + (i + 1) + ": " + qst.Answers[i].Substring(qst.Answers[i].Split('\n')[0].Length) ); } diff --git a/Bot/Modules/OttoLinux/PhotoServer.cs b/Bot/Modules/OttoLinux/PhotoServer.cs new file mode 100644 index 0000000..3560439 --- /dev/null +++ b/Bot/Modules/OttoLinux/PhotoServer.cs @@ -0,0 +1,66 @@ +// This feature is not maintained anymore +// it was exposing a webserver returning a json with all the questions and answers. +// It was originally intended for a web version of the bot, but was never completed. + +using System.Net; + +namespace SoUnBot.Modules.OttoLinux +{ + public class PhotoServer + { + public PhotoServer(string baseDir) + { + using var listener = new HttpListener(); + listener.Prefixes.Add("http://+:8001/"); + listener.Start(); + Console.WriteLine("PhotoServer is listening on port 8001..."); + + while (true) + { + HttpListenerContext ctx = listener.GetContext(); + using HttpListenerResponse resp = ctx.Response; + + resp.StatusCode = (int)HttpStatusCode.OK; + resp.StatusDescription = "Status OK"; + resp.AddHeader("Access-Control-Allow-Origin", "*"); + resp.AddHeader("Access-Control-Allow-Headers", "*"); + resp.AddHeader("Access-Control-Allow-Methods", "GET"); + + if (ctx.Request.Url == null) + { + resp.StatusCode = (int)HttpStatusCode.BadRequest; + continue; + } + + if (!File.Exists(baseDir + "/" + ctx.Request.Url.AbsolutePath)) + { + resp.StatusCode = (int)HttpStatusCode.NotFound; + continue; + } + + if (ctx.Request.Url.AbsolutePath.EndsWith("png")) + { + resp.AddHeader("Content-Type", "image/png"); + } + else if (ctx.Request.Url.AbsolutePath.EndsWith("jpg")) + { + resp.AddHeader("Content-Type", "image/jpeg"); + } + else + { + resp.StatusCode = (int)HttpStatusCode.BadRequest; + continue; + } + + byte[] buffer = File.ReadAllBytes(baseDir + "/" + ctx.Request.Url.AbsolutePath); + resp.ContentLength64 = buffer.Length; + + using Stream ros = resp.OutputStream; + try + { + ros.Write(buffer, 0, buffer.Length); + } catch { } + } + } + } +} diff --git a/Bot/Modules/OttoLinux/Question.cs b/Bot/Modules/OttoLinux/Question.cs index c024267..c168f53 100644 --- a/Bot/Modules/OttoLinux/Question.cs +++ b/Bot/Modules/OttoLinux/Question.cs @@ -15,6 +15,8 @@ namespace SoUnBot.Modules.OttoLinux public List Answers { get; } [JsonProperty("correct")] public int Correct { get; private set; } + [JsonProperty("image")] + public string Image { get; private set; } public Question(String quest) { diff --git a/Bot/Program.cs b/Bot/Program.cs index 684740f..49810bc 100644 --- a/Bot/Program.cs +++ b/Bot/Program.cs @@ -5,9 +5,10 @@ using SoUnBot.Telegram; using Telegram.Bot.Types; string dataPath = Environment.GetEnvironmentVariable("DATA_PATH") ?? "BotData"; -string aclPath = Environment.GetEnvironmentVariable("ACL_PATH") ?? "BotData"; +string aclPath = Environment.GetEnvironmentVariable("ACL_PATH") ?? "BotData/ACL"; string tgToken = Environment.GetEnvironmentVariable("TELEGRAM_TOKEN") ?? "this-string-is-not-a-token"; string tgAdminId = Environment.GetEnvironmentVariable("TELEGRAM_ADMIN_ID") ?? "000000"; +string webBaseURL = Environment.GetEnvironmentVariable("WEB_BASE_URL") ?? "http://localhost:8001"; Console.WriteLine("Welcome to SO un bot!"); @@ -28,12 +29,12 @@ try if (f.EndsWith("txt")) { Console.WriteLine("Loading module " + Path.GetFileNameWithoutExtension(f)); - moduleLoader.LoadModule(new BotGame(acl, Path.GetFileNameWithoutExtension(f), f, false)); + moduleLoader.LoadModule(new BotGame(acl, Path.GetFileNameWithoutExtension(f), f, false, webBaseURL)); } else if (f.EndsWith("json")) { Console.WriteLine("Loading module " + Path.GetFileNameWithoutExtension(f)); - moduleLoader.LoadModule(new BotGame(acl, Path.GetFileNameWithoutExtension(f), f, false, 3)); + moduleLoader.LoadModule(new BotGame(acl, Path.GetFileNameWithoutExtension(f), f, false, webBaseURL, 3)); } else { @@ -43,7 +44,7 @@ try foreach (string d in Directory.GetDirectories(dataPath + "/Questions")) { Console.WriteLine("Loading module " + Path.GetFileName(d)); - moduleLoader.LoadModule(new BotGame(acl, Path.GetFileName(d), d, false, 2)); + moduleLoader.LoadModule(new BotGame(acl, Path.GetFileName(d), d, false, webBaseURL, 2)); } } catch (System.Exception ex) @@ -55,6 +56,8 @@ catch (System.Exception ex) Console.WriteLine("Starting Telegram bot listener..."); new TelegramBot(tgToken, acl, dataPath + "/motd.txt", moduleLoader.Modules); +new PhotoServer(dataPath + "/Images"); + // worst way ever to keep the main thread running, I know while (true) Thread.Sleep(10000); \ No newline at end of file diff --git a/Bot/Telegram/TelegramBot.cs b/Bot/Telegram/TelegramBot.cs index dade58b..7aa3099 100644 --- a/Bot/Telegram/TelegramBot.cs +++ b/Bot/Telegram/TelegramBot.cs @@ -13,7 +13,7 @@ namespace SoUnBot.Telegram { private AccessManager _accessManager; private string _moth_path; - + private Dictionary _modules; public TelegramBotClient BotClient { get; private set; } private Dictionary _usersContext;