From e60dab78ea6b0bd6194c0b7b0091174e67f20acb Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Fri, 26 Jan 2024 00:16:45 +0100 Subject: [PATCH] working commit --- .gitignore | 15 +++++ include/BotToken.h | 3 + include/Format.h | 18 ++++++ include/Lazy.h | 112 ++++++++++++++++++++++++++++++++++++++ src/Lazy.cpp | 121 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 133 +++++++++++++++++++++++++++++++++++++++++++++ xmake.lua | 10 ++++ 7 files changed, 412 insertions(+) create mode 100644 .gitignore create mode 100644 include/BotToken.h create mode 100644 include/Format.h create mode 100644 include/Lazy.h create mode 100644 src/Lazy.cpp create mode 100644 src/main.cpp create mode 100644 xmake.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7bf3542 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store + +#VsCode +.vscode + +# Bot token +include/BotToken.h + +#Html +html \ No newline at end of file diff --git a/include/BotToken.h b/include/BotToken.h new file mode 100644 index 0000000..32cd007 --- /dev/null +++ b/include/BotToken.h @@ -0,0 +1,3 @@ +#pragma once + +const static char BOT_TOKEN[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; \ No newline at end of file diff --git a/include/Format.h b/include/Format.h new file mode 100644 index 0000000..0795820 --- /dev/null +++ b/include/Format.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include + +template +std::string Format(const std::string &format, Args... args) +{ + int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' + if (size <= 0) + { + throw std::runtime_error("Error during formatting."); + } + std::unique_ptr buf(new char[size]); + snprintf(buf.get(), static_cast(size), format.c_str(), args...); + return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside +} \ No newline at end of file diff --git a/include/Lazy.h b/include/Lazy.h new file mode 100644 index 0000000..7682586 --- /dev/null +++ b/include/Lazy.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include + +enum class LazyType +{ + Title, + Text, + Image, +}; + +class LazyElement +{ +public: + virtual LazyType GetType() const = 0; +}; + +class LazyTitle : public LazyElement +{ +private: + std::string m_Title; + std::uint8_t m_TitleLevel; + +public: + LazyTitle(const std::string &title, const std::uint8_t level) : m_Title(title), m_TitleLevel(level) {} + virtual LazyType GetType() const override + { + return LazyType::Title; + }; + + const std::string &GetTitle() const + { + return m_Title; + } + + int GetTitleLevel() const + { + return m_TitleLevel; + } +}; + +class LazyText : public LazyElement +{ +private: + std::string m_Text; + +public: + LazyText(const std::string &text) : m_Text(text) {} + virtual LazyType GetType() const override + { + return LazyType::Text; + }; + + const std::string &GetText() const + { + return m_Text; + } +}; + +class LazyImage : public LazyElement +{ +private: + std::string m_ImageLink; + std::string m_ImageAlt; + +public: + LazyImage(const std::string &link, const std::string &alt) : m_ImageLink(link), m_ImageAlt(alt) {} + virtual LazyType GetType() const override + { + return LazyType::Image; + }; + + const std::string &GetAlt() const + { + return m_ImageAlt; + } + + const std::string &GetLink() const + { + return m_ImageLink; + } +}; + +typedef std::vector> ElementList; + +class LazyFile +{ +private: + ElementList m_Elements; + +public: + void AddImage(const std::string &link, const std::string &alt) { + m_Elements.push_back(std::make_unique(link, alt)); + } + + void AddTitle(const std::string &title, const std::uint8_t level) { + m_Elements.push_back(std::make_unique(title, level)); + } + + void AddText(const std::string& text) { + m_Elements.push_back(std::make_unique(text)); + } + + const ElementList& GetElements() const { + return m_Elements; + } +}; + +std::string RenderHtml(const LazyFile& lazy); +LazyFile ReadLazyFile(const std::string& filePath); \ No newline at end of file diff --git a/src/Lazy.cpp b/src/Lazy.cpp new file mode 100644 index 0000000..285bdf7 --- /dev/null +++ b/src/Lazy.cpp @@ -0,0 +1,121 @@ +#include "Lazy.h" +#include "Format.h" +#include +#include +#include + +static const std::string HtmlTemplate = R"( + + + + + + + + + +
+%s +
+ +)"; + +static std::string RenderTitle(const LazyTitle *element) +{ + return Format(" %s ", element->GetTitleLevel(), element->GetTitle().c_str(), element->GetTitleLevel()); +} + +static std::string RenderText(const LazyText *element) +{ + return Format("

%s

", element->GetText().c_str()); +} + +static std::string RenderImage(const LazyImage *element) +{ + return Format("

\"%s\"

", element->GetLink().c_str(), element->GetAlt().c_str()); +} + +static std::string RenderElement(const LazyElement *element) +{ + switch (element->GetType()) + { + case LazyType::Image: + return RenderImage(dynamic_cast(element)); + + case LazyType::Text: + return RenderText(dynamic_cast(element)); + + case LazyType::Title: + return RenderTitle(dynamic_cast(element)); + + default: + break; + } +} + +std::string RenderHtml(const LazyFile &lazy) +{ + std::string result; + for (const auto &element : lazy.GetElements()) + { + result += RenderElement(element.get()); + result += "\n"; + } + return Format(HtmlTemplate, result.c_str()); +} + +static void ParseLine(LazyFile &file, const std::string &line) +{ + // Checks for empty line + if (line.empty()) + return; + + // Checks for title + static const std::string Title = "######"; + for (int i = 6; i > 0; i--) + { + if (line.substr(0, i) == Title.substr(0, i)) + { + file.AddTitle(line.substr(i), static_cast(i)); + return; + } + } + + // Checks for image + if (line[0] == '!') { + std::stringstream ss {line.substr(1)}; + std::string link, alt; + ss >> link >> alt; + file.AddImage(link, alt); + return; + } + + // Add Raw text + file.AddText(line); +} + +LazyFile ReadLazyFile(const std::string &filePath) +{ + std::ifstream input{filePath}; + if (!input) + { + std::cerr << "Can't read file !\n"; + } + + LazyFile file; + + std::string line; + while (getline(input, line)) + { + ParseLine(file, line); + } + + return file; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..674a58e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,133 @@ +#include +#include +#include "Lazy.h" +#include +#include +#include "BotToken.h" + +const static std::string WEBSITE_LINK = "http://thesims.freeboxos.fr:30000/Maths"; + +const static std::uint64_t GUILD_ID = 1183694732413652992UL; + +const static std::uint64_t MATHS_CM_ID = 1183694856292401182UL; +const static std::uint64_t MATHS_TD_ID = 1197472923636731935UL; + +void LoadCMThread(dpp::cluster &bot, dpp::thread &thread) +{ + std::cout << thread.name << std::endl; + std::cout << "Message count : " << (int)thread.message_count << std::endl; + LazyFile html; + dpp::message_map messages = bot.messages_get_sync(thread.id, 0, 0, 0, 100); + + for (auto &[id, message] : messages) + { + std::string content = message.content; + if (!content.empty()) + { + html.AddTitle(content, 2); + } + for (auto &attachment : message.attachments) + { + html.AddImage(attachment.url, attachment.url); + } + } + + std::string outputFileName = "html/CM/"; + if (thread.name[1] == 'L') + outputFileName += "Algebre/" + thread.name.substr(11); + else + outputFileName += "Analyse/" + thread.name.substr(10); + outputFileName += ".html"; + + std::ofstream outputFile{outputFileName}; + assert(outputFile); + std::cout << "Rendering file " << outputFileName << " ...\n"; + outputFile << RenderHtml(html); +} + +void LoadTDThread(dpp::cluster &bot, dpp::thread &thread) +{ + std::cout << thread.name << std::endl; + std::cout << "Message count : " << (int)thread.message_count << std::endl; + LazyFile html; + dpp::message_map messages = bot.messages_get_sync(thread.id, 0, 0, 0, 100); + + for (auto &[id, message] : messages) + { + std::string content = message.content; + if (!content.empty()) + { + html.AddTitle(content, 2); + } + for (auto &attachment : message.attachments) + { + html.AddImage(attachment.url, attachment.url); + } + } + + std::ofstream outputFile{"html/TD/" + thread.name + ".html"}; + outputFile << RenderHtml(html); +} + +void UpdateWebSite(dpp::cluster &bot) +{ + dpp::channel tdChannel = bot.channel_get_sync(MATHS_TD_ID); + dpp::channel cmChannel = bot.channel_get_sync(MATHS_CM_ID); + + dpp::active_threads threads = bot.threads_get_active_sync(GUILD_ID); + + for (auto &[id, info] : threads) + { + dpp::snowflake parentChannelID = info.active_thread.parent_id; + + switch (parentChannelID) + { + case MATHS_CM_ID: + LoadCMThread(bot, info.active_thread); + break; + + case MATHS_TD_ID: + LoadTDThread(bot, info.active_thread); + break; + + default: + break; + } + } +} + +void CreateDirectories() +{ + std::filesystem::create_directories("html/CM/Analyse"); + std::filesystem::create_directories("html/CM/Algebre"); + std::filesystem::create_directories("html/TD"); +} + +int main(int argc, char **argv) +{ + CreateDirectories(); + + dpp::cluster bot{BOT_TOKEN}; + + bot.on_slashcommand([&bot](const dpp::slashcommand_t &event) + { + if (event.command.get_command_name() == "updatewebsite") { + event.reply("Le site se met à jour ..."); + UpdateWebSite(bot); + /* Create a message with the content as our new embed. */ + dpp::message msg(event.command.channel_id, "Le site a été mis à jour au lien suivant 👉 " + WEBSITE_LINK); + + /* Reply to the user with the message, containing our embed. */ + event.edit_response(msg); + } }); + + bot.on_ready([&bot](const dpp::ready_t &event) + { + if (dpp::run_once()) + { + /* Create and register a command when the bot is ready */ + bot.global_bulk_command_create({dpp::slashcommand("updatewebsite", "Updates the website", bot.me.id)}); + } }); + bot.start(dpp::st_wait); + return 0; +} diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..5ffe560 --- /dev/null +++ b/xmake.lua @@ -0,0 +1,10 @@ +add_rules("mode.debug", "mode.release") + +add_requires("dpp") + +target("LazyBot") + set_kind("binary") + add_files("src/*.cpp") + add_packages("dpp") + add_includedirs("include") + set_rundir("$(projectdir)")