From 3314a53d0cf0a135fe6f82fcc7b6f4df84f70436 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sun, 23 Aug 2020 12:41:55 +0200 Subject: clean start, clean CMakeLists.txt --- CMakeLists.txt | 77 +++-- README.md | 13 +- src/N-Commands/KlingerHandler.cpp | 11 - src/N-Commands/KlingerHandler.hpp | 17 -- src/N-Commands/RelationshipHandler.cpp | 130 --------- src/N-Commands/RelationshipHandler.hpp | 10 - src/Utilities/GetEssen.cpp | 250 ---------------- src/Utilities/GetEssen.hpp | 38 --- src/Utilities/Logger.cpp | 48 ---- src/Utilities/Logger.hpp | 38 --- src/Utilities/Utilities.hpp | 142 --------- src/Utilities/sqdb.cpp | 506 --------------------------------- src/Utilities/sqdb.hpp | 207 -------------- src/main.cpp | 59 +--- 14 files changed, 42 insertions(+), 1504 deletions(-) delete mode 100644 src/N-Commands/KlingerHandler.cpp delete mode 100644 src/N-Commands/KlingerHandler.hpp delete mode 100644 src/N-Commands/RelationshipHandler.cpp delete mode 100644 src/N-Commands/RelationshipHandler.hpp delete mode 100644 src/Utilities/GetEssen.cpp delete mode 100644 src/Utilities/GetEssen.hpp delete mode 100644 src/Utilities/Logger.cpp delete mode 100644 src/Utilities/Logger.hpp delete mode 100644 src/Utilities/Utilities.hpp delete mode 100644 src/Utilities/sqdb.cpp delete mode 100644 src/Utilities/sqdb.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 239e2af..2c3ea9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,42 +1,41 @@ cmake_minimum_required(VERSION 3.17) -project(DORgodBotBackend) - -set(CMAKE_CXX_STANDARD 20) +project(N_Core + VERSION 0.2 + DESCRIPTION "Backend of the N bot - serving JSON requests" +) -find_package(Threads REQUIRED) -find_package(CURL) -find_package(JSONCPP) - -find_package(Boost COMPONENTS system REQUIRED) -find_package(Boost COMPONENTS filesystem REQUIRED) -find_package(Boost COMPONENTS date_time REQUIRED) - -include_directories(/usr/local/include ${OPENSSL_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ./src) - -add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY) -add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED) -add_definitions(-DHAS_JSONCPP=ON) - - -if (CURL_FOUND) - include_directories(${CURL_INCLUDE_DIRS}) - add_definitions(-DHAVE_CURL) -endif() - -link_libraries(pthread) -link_libraries(curl) -link_libraries(mongoose) -add_executable(DORgodBotBackend src/main.cpp - src/N-Commands/KlingerHandler.cpp - src/N-Commands/KlingerHandler.hpp - src/N-Commands/RelationshipHandler.cpp - src/N-Commands/RelationshipHandler.hpp - src/Utilities/Logger.cpp - src/Utilities/sqdb.cpp - src/Utilities/Logger.hpp - src/Utilities/sqdb.hpp - src/Utilities/Utilities.hpp - src/Utilities/GetEssen.cpp - src/Utilities/GetEssen.hpp) -target_link_libraries(DORgodBotBackend -lsqlite3 -ljsoncpp -lboost_date_time -lboost_system ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${CURL_LIBRARIES}) \ No newline at end of file +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +IF (CMAKE_VERSION VERSION_LESS "3.7.0") + set(CMAKE_INCLUDE_CURRENT_DIR ON) +ENDIF () + +add_executable(${PROJECT_NAME} + # Headers + + # Sources + src/main.cpp +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + $ + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +target_link_libraries(${PROJECT_NAME} PUBLIC + pthread +) + +#target_compile_definitions(${PROJECT_NAME} PRIVATE N_CORE) + +set_target_properties(${PROJECT_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) \ No newline at end of file diff --git a/README.md b/README.md index bdf9b99..c540718 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,4 @@ -# Dies ist das Backend von N - -Hier kommt noch Kram - -Benötigte Libraries: -Mongoose https://github.com/Gregwar/mongoose-cpp -jsoncpp - -Der Server läuft lokal auf Port 8080 - - -Niklas Halle +# N Core - the backend of N ## N protocol ### request Each message sent to the N core server must be valid JSON and have a `command` field. It contains the command for N to handle, sanitizied (i.e. no leading '/' or trailing username etc). diff --git a/src/N-Commands/KlingerHandler.cpp b/src/N-Commands/KlingerHandler.cpp deleted file mode 100644 index c596952..0000000 --- a/src/N-Commands/KlingerHandler.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// Created by max on 11.08.20. -// - -#include "KlingerHandler.hpp" - -void KlingerHandler::onCall(const Mongoose::Request& request, Mongoose::JsonResponse& response) { - - std::cout << "Klinger was called\n"; - response["text"] = "Bonjour!"; -} diff --git a/src/N-Commands/KlingerHandler.hpp b/src/N-Commands/KlingerHandler.hpp deleted file mode 100644 index c078303..0000000 --- a/src/N-Commands/KlingerHandler.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Created by max on 11.08.20. -// -#include -#include -#include -#ifndef DORGODBOTBACKEND_KLINGERHANDLER_H -#define DORGODBOTBACKEND_KLINGERHANDLER_H - - -class KlingerHandler { -public: - void onCall(const Mongoose::Request& request, Mongoose::JsonResponse& response) ; -}; - - -#endif //DORGODBOTBACKEND_KLINGERHANDLER_H diff --git a/src/N-Commands/RelationshipHandler.cpp b/src/N-Commands/RelationshipHandler.cpp deleted file mode 100644 index 46991a3..0000000 --- a/src/N-Commands/RelationshipHandler.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "RelationshipHandler.hpp" -#include -#include -#include -using namespace std; - -//Takk til https://www.geeksforgeeks.org/split-a-sentence-into-words-in-cpp/ -//fucking c++ does not has a split function like every other programming language in the world -vector removeDupWord(const string& str) { - vector v = {}; - string word; // = ""; - for(auto x : str) { - if(x == ' ') { - if(word != "/relation") { - v.push_back(word); - } - word = ""; - } else { - word += x; - } - } - v.push_back(word); - return v; -} -vector buildCalArr(vector nameV) { - string ges = nameV.at(0) + nameV.at(1); - - for(auto& c : ges) { - c = tolower(c); - } - - vector v = {}; - for(auto c1 : ges) { - //cout << c1 << '\n'; - int count = 0; - for(auto c2: ges) { - if(c1==c2) { - ++count; - } - } - v.push_back(count); - } - //cout << ges << endl; - - /*for(auto i: v) { - cout << i << ' '; - } - cout << v.size() << "\n";*/ - return v; -} - -int calculate(vector names) { - sort(names.begin(), names.end()); - vector nums = buildCalArr(names); - - while(nums.size() > 2) { - vector tempNums = {}; - for(std::size_t i=0;i names) { - //vector names = removeDupWord(str); - if(names.size() != 2) { - return "Gib zwei Namen ein Du Troll!"; - } - if(!isAlphaNum(names.at(0))) { - return "Seit wann enthælt ein Name Sonderzeichen oder Zahlen? Spüre den Zorn von N!"; - } - if(!isAlphaNum(names.at(1))) { - return "Seit wann enthælt ein Name Sonderzeichen oder Zahlen? Spüre den Zorn von N!"; - } - int result = calculate(names); - - return (names.at(0) + " und " + names.at(1) + " passen nach Angaben von N zu " + to_string(result) + "% zusammen. Gratuliere!\n"); -} - -void RelationshipHandler::onCall(Mongoose::Request& request, Mongoose::JsonResponse& response) { - - std::cout << "/relation was called\n"; - - response["text"] = rsStart(vector{request.get("name1", "Lukas"), request.get("name2", "cpp")}); - - response["success"] = "1"; - response["session"] = "NULL"; - /*if (messagePtr->date > telegram->getBootDate()) { - - log(messagePtr->from->username + ": "+messagePtr->text); - - telegram->sendMessage(messagePtr->chat->id, rsStart(messagePtr->text)); - - }*/ - -} diff --git a/src/N-Commands/RelationshipHandler.hpp b/src/N-Commands/RelationshipHandler.hpp deleted file mode 100644 index fe9c0ea..0000000 --- a/src/N-Commands/RelationshipHandler.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include -#include -#include - -class RelationshipHandler { -public: - void onCall(Mongoose::Request& request, Mongoose::JsonResponse& response); - -}; diff --git a/src/Utilities/GetEssen.cpp b/src/Utilities/GetEssen.cpp deleted file mode 100644 index 56742cc..0000000 --- a/src/Utilities/GetEssen.cpp +++ /dev/null @@ -1,250 +0,0 @@ -// -// Created by max on 18.12.18. -// - -#include "Utilities/GetEssen.hpp" - - -using namespace boost::posix_time; - -void returnEssen(Mongoose::Request &request, Mongoose::JsonResponse &response){ - std::cout << "mensa was called\n"; - mensa Mensa_ID; - std::string mensa_name = request.get("argument1", "adlershof"); - std::string offset_request = request.get("argument2", "0"); - - - if(mensa_name == "adlershof"){ - Mensa_ID = mensa::Adlershof; - } else if(mensa_name == "nord"){ - Mensa_ID = mensa::Nord; - }else if (mensa_name == "sued" || mensa_name == "süd"){ - Mensa_ID = mensa::Sued; - } - - int offset = std::stoi(offset_request); - - - response["success"] = "1"; - response["session"] = "NULL"; - response["text"] = getEssen(Mensa_ID, offset); - - -} - -bool db_update_mensa_message(const int& mensaID, const ptime& mensaDatum, const string& message){ - sqdb::Db db("../main.sqlite"); - string newTime = to_simple_string(ptime(second_clock::local_time())); - string mensaDatumString = to_string(mensaDatum.date().year()) + "-" + mensaDatum.date().month().as_short_string() + "-" + to_string(mensaDatum.date().day().as_number()); - sqdb::QueryStr str; - db.Query(str.Format(SQDB_MAKE_TEXT("update mensa set Message = '%s', LastModified = '%s' where ID = %i and Datum = '%s';"), message.c_str(), newTime.c_str(), mensaID, mensaDatumString.c_str())).Next(); - return true; -} - -bool db_insert_mensa_message(const int& mensaID, const ptime& mensaDatum, const string& message){ - sqdb::Db db("../main.sqlite"); - string newTime = to_simple_string(ptime(second_clock::local_time())); - string mensaDatumString = to_string(mensaDatum.date().year()) + "-" + mensaDatum.date().month().as_short_string() + "-" + to_string(mensaDatum.date().day().as_number()); - sqdb::QueryStr str; - db.Query(str.Format(SQDB_MAKE_TEXT("insert into mensa values(%i, '%s', '%s', '%s');"), mensaID, message.c_str(), mensaDatumString.c_str(), newTime.c_str())).Next(); - return true; -} - -Mensa_Essen db_get_mensa_message(const int& mensaID, const ptime& mensaDatum) { - Mensa_Essen out; - sqdb::Db db("../main.sqlite"); - - sqdb::QueryStr str; - string mensaDatumString = to_string(mensaDatum.date().year()) + "-" + mensaDatum.date().month().as_short_string() + "-" + to_string(mensaDatum.date().day().as_number()); - sqdb::Statement s = db.Query(str.Format(SQDB_MAKE_TEXT("SELECT * from mensa WHERE Datum = '%s' AND ID = %i;"), mensaDatumString.c_str(), mensaID )); - - try { - if(s.Next()) { - int ID = s.GetField(0); - string Message = s.GetField(1); - string Datum = s.GetField(2); - string LastModified = s.GetField(3); - - - ptime LMDate(time_from_string(LastModified)); - - out.ID = ID; - out.Message = Message; - out.Datum = mensaDatum; - out.LastModified = LMDate; - return out; - } - } catch (sqdb::Exception &exception){ - log("Error code: " + to_string(exception.GetErrorCode()) + " Error Message: " + exception.GetErrorMsg() + "\n"); - } - out.ID = -2; - return out; - -} - -string getEssen(const int mensa_ID, const int offset) { - Mensa_Essen Essen; - if (offset >= 0) { - - if (offset > 28) { - return "Ich fühle mich geschmeichelt, dass du denkst, dass ich so weit in die Zukunft gucken kann (0 bis 28 Tage)"; - } - - ptime datumNow = second_clock::local_time(); - ptime datumEssen = datumNow + (boost::gregorian::days(offset)); - - Essen = db_get_mensa_message(mensa_ID, datumEssen); - if (Essen.ID == -2) { // SQL got nothing back :/ - //log("sql got nothing back!"); - if (downloadMensaFile(mensa_ID, datumEssen) != CURLE_OK){ - log("Error downloading file"); - return "Error downloading file!"; - } - db_insert_mensa_message(mensa_ID, datumEssen, read_mensa_message_from_file(mensa_ID)); - Essen = db_get_mensa_message(mensa_ID, datumEssen); - - string out; - switch (Essen.ID) { - case mensa::Adlershof : - out = "Mensa Adlershof am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - case mensa ::Nord: - out = "Mensa Nord am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - case mensa::Sued : - out = "Mensa Sued am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - default: - out = "Mensa Unbekannt am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - - } - out += Essen.Message; - out += "\n (Stand: " + to_simple_string(Essen.LastModified) + ")\n"; - - return out; - } - - if (Essen.LastModified + hours(2) < datumNow) { //LastModified is more than 2 hours old - if (downloadMensaFile(mensa_ID, datumEssen) != CURLE_OK) { - return "Error downloading file!"; - } - - db_update_mensa_message(mensa_ID, datumEssen, read_mensa_message_from_file(mensa_ID)); - Essen = db_get_mensa_message(mensa_ID, datumEssen); - } - string out; - switch (Essen.ID) { - case mensa::Adlershof : - out = "Mensa Adlershof am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - case mensa::Nord : - out = "Mensa Nord am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - case mensa::Sued : - out = "Mensa Sued am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - default: - out = "Mensa Unbekannt am " + to_string(Essen.Datum.date().day().as_number()) + "." + to_string(Essen.Datum.date().month().as_number()) + "." + to_string(Essen.Datum.date().year()) + ":"; - break; - - } - out += Essen.Message; - out += "\n (Stand: " + to_simple_string(Essen.LastModified) + ")\n"; - return out; - } else return "Wer denkst du bin ich? Ein Zeitreisender?\nIch kann zwar in die Zukunft gucken, aber nur 28 Tage"; - -} - -string read_mensa_message_from_file(const int& mensa_id_file) { - string s; - string out; - bool serious = false; - - std::ifstream inFile(std::to_string(mensa_id_file)); - while (std::getline(inFile, s)) { - //out += mensa; - if (s.find("15.png") != string::npos && serious) { - string vegan; - - int vegan_byte[4] = {0xF0, 0x9F, 0x8C, 0xB1}; - for (int i : vegan_byte) { - vegan += (char) i; - } - - out += vegan; - } - - if (s.find("1.png") != string::npos && serious) { - string vegetarian; - - int vegetarian_byte[4] = {0xF0, 0x9F, 0x8C, 0xBD}; - for (int i : vegetarian_byte) { - vegetarian += (char) i; - } - - out += vegetarian; - } - if (s.find("splIcon") != string::npos && serious && s.find("1.png") == string::npos && - s.find("15.png") == string::npos) { - string emptyEmoji; - int emptyEmoji_byte[6] = {0xE2, 0x98, 0xA3, 0xEF, 0xB8, 0x8F}; - for (int i : emptyEmoji_byte) { - emptyEmoji += (char) i; - } - - out += emptyEmoji; - } - - if (s.find("splGroup\"") != string::npos) { //Getting the Category of the Meal - for (int i = 0, j = 0; (unsigned) i < s.length(); ++i) { - if (s.at(i) == '>') { - j = i + 1; - } - if (s.at(i) == '<' && j != 0) { - s = s.substr(j, i - j); - j = 0; - } - - } - serious = (s == "Aktionen" || s == "Essen" || s == "Beilagen"); - if (serious) { - out += "\n" + s + "\n"; - } - } - if (s.find("class=\"bold\"") != string::npos && serious) { //Getting the Meal - for (int i = 0, j = 0; (unsigned) i < s.length(); ++i) { - if (s.at(i) == '>') { - j = i + 1; - //logStatus("Zeichen > gefunden in Position" + std::to_string(i)); - } - if (s.at(i) == '<' && j != 0) { - s = s.substr(j, i - j); - j = 0; - } - - } - - out += "\t" + s; - } - - if (s.find("euro;") != string::npos && serious) { //geting the price of each Meal - for (int i = 0, j = 0; (unsigned) i < s.length(); ++i) { - if (s.at(i) == ';') { - j = i + 1; - } - if (s.at(i) == '/') { - s = s.substr(j, i - j); - j = 0; - } - } - out += "\t" + s + "€\n"; - } - } - - if (out.empty()) { - return "Heute kein Essen"; - } - return out; - -} diff --git a/src/Utilities/GetEssen.hpp b/src/Utilities/GetEssen.hpp deleted file mode 100644 index 813d115..0000000 --- a/src/Utilities/GetEssen.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "sqdb.hpp" -#include "Utilities/Utilities.hpp" -#include "Utilities/Logger.hpp" -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost::posix_time; - -void returnEssen(Mongoose::Request &request, Mongoose::JsonResponse &response); - -string getEssen(int mensa_ID, int offset); - -string read_mensa_message_from_file(const int& mensa_id_file); - -struct Mensa_Essen{ - int ID{191}; - string Message{"nothing got back! There was an error!!"}; - boost::posix_time::ptime Datum; - boost::posix_time::ptime LastModified; -}; -enum mensa { - Adlershof = 191, Nord = 147, Sued = 367 -}; - - - diff --git a/src/Utilities/Logger.cpp b/src/Utilities/Logger.cpp deleted file mode 100644 index 333ae16..0000000 --- a/src/Utilities/Logger.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "Logger.hpp" - -/*void Logger::Log(const TelegramMessage& message, LogLevel logLevel) { - Log("[" + message->from->username + "] " + message->text, logLevel); -}*/ - -void Logger::Log(const string& inMsg, LogLevel logLevel) { - string outMsg; - -#ifdef NDEBUG - if (logLevel == LogLevel::lDEBUG) { - // don't log debug messages in release mode - return; - } -#endif - - // prefix message with time - outMsg = "[" + NOW_STRING + "]"; - - // TODO: let at least some (ERROR, WARN) levels go to stderr, not stdout - // prefix log level - TODO: allow filtering based on globally set level? - switch (logLevel) { - case LogLevel::lSTATUS: - outMsg += " [STATUS] " + inMsg; - break; - case LogLevel::lDEBUG: - outMsg += " [DEBUG] " + inMsg; - break; - case LogLevel::lINFO: - outMsg += " [INFO] " + inMsg; - break; - case LogLevel::lWARN: - outMsg += " [WARN] " + inMsg; - break; - case LogLevel::lERROR: - outMsg += " [ERROR] " + inMsg; - break; - } - - Print(outMsg); -} - -void Logger::Print(const string& msg) { - // console output - cout << msg << endl; - - // file output | TODO: Logger needs state for that - or at least needs to pretend to have one -} \ No newline at end of file diff --git a/src/Utilities/Logger.hpp b/src/Utilities/Logger.hpp deleted file mode 100644 index f319d93..0000000 --- a/src/Utilities/Logger.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - - -#include "Utilities.hpp" - -using std::string; -using std::cout; -using std::endl; - -#define logWarn(x) Logger::Log(x, Logger::LogLevel::lWARN) -#define logDebug(x) Logger::Log(x, Logger::LogLevel::lDEBUG) -#define logError(x) Logger::Log(x, Logger::LogLevel::lERROR) - -#define logStatus(x) Logger::Log(x, Logger::LogLevel::lSTATUS) - -#define log(x) logI(x) -#define logI(x) Logger::Log(x, Logger::LogLevel::lINFO) - -class Logger { -public: - enum class LogLevel { - lSTATUS, // general bot status messages, everything it logs o it's own - lDEBUG, // messages logged for development purposes - lINFO, // messages logged on certain events (eg. command executed) - lWARN, - lERROR - }; - - static void Log(const string& msg, LogLevel logLevel); - //static void Log(const TelegramMessage& message, LogLevel logLevel); - -private: - static void Print(const string& msg); -}; - diff --git a/src/Utilities/Utilities.hpp b/src/Utilities/Utilities.hpp deleted file mode 100644 index 0c9f435..0000000 --- a/src/Utilities/Utilities.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#define NOW std::time(0) -#define LOG_TIME_FORMAT "%y-%m-%d %H:%M:%S" -#define HR_TIME_FORMAT "%d.%m.%y, %H:%M:%S UHR" -#define NOW_STRING TimeStampToHReadble(NOW, false) - -static std::string TimeStampToHReadble(const time_t rawTime, bool HR_READABLE) { - struct tm *dt; - char buffer[30]; - dt = localtime(&rawTime); - if(HR_READABLE) { - strftime(buffer, sizeof(buffer), HR_TIME_FORMAT, dt); - } else { - strftime(buffer, sizeof(buffer), LOG_TIME_FORMAT, dt); - } - return std::string(buffer); -} - -#include -static std::string getApiTokenFromFile(const std::string& filePath) { - std::string token = "NO-TOKEN"; - - std::ifstream inFile(filePath); - - if (inFile) { - // TODO: validate, at least a little - currently we just assume the file contains the correct data - std::getline(inFile, token); - } else { - return ""; - } - - return token; -} - -#ifdef NDEBUG - -static std::string getProductionApiToken() { - return getApiTokenFromFile("../release.api"); -} - -#else - -static std::string getDebugApiToken() { - return getApiTokenFromFile("../debug.api"); -} - -#endif - -static CURLcode downloadFile(const std::string& url, const std::string& fileName) { - - CURL *curl; - FILE *fp; - CURLcode res; - curl = curl_easy_init(); - - if (curl) { - fp = fopen(fileName.c_str(), "wb"); - - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - curl_easy_setopt(curl, CURLOPT_USERAGENT, - "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36"); //so apparently the Website stw.berlin blocks the IPwhen accessing it very often with the bot... - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - res = curl_easy_perform(curl); - if (res != CURLE_OK){ - //TODO: return int as status instead of boolean - maybe even this curl error? - return CURLE_COULDNT_CONNECT; - } - curl_easy_cleanup(curl); - fclose(fp); - return CURLE_OK; - } else { - return CURLE_COULDNT_CONNECT; - } -} - -static CURLcode downloadMensaFile(const int& ID, const boost::posix_time::ptime& datum) { - - std::string datumString = std::to_string(datum.date().year()) + "-" + std::to_string(datum.date().month().as_number()) + "-" + std::to_string(datum.date().day()); - - std::string postfield = "resources_id=" + std::to_string(ID) + "&date=" + datumString; - - CURL *curl; - FILE *fp; - CURLcode res; - curl = curl_easy_init(); - - if (curl) { - fp = fopen(std::to_string(ID).c_str(), "wb"); - - struct curl_slist *slist1; - - slist1 = nullptr; - slist1 = curl_slist_append(slist1, "Cookie: seitenbereich=mensen; _ga=GA1.2.1719763776.1545837849; filterkennz=[]; PHPSESSID=9fa00137a2ad065fe595196ddb34e0ba; _gid=GA1.2.226483670.1549982576; loadDataForResource=191; storedPathname=/mensen.html; _gat=1"); - slist1 = curl_slist_append(slist1, "Origin: https://www.stw.berlin"); - slist1 = curl_slist_append(slist1, "Accept-Encoding: gzip, deflate, br"); - slist1 = curl_slist_append(slist1, "Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"); - slist1 = curl_slist_append(slist1, "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36"); - slist1 = curl_slist_append(slist1, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8"); - slist1 = curl_slist_append(slist1, "Accept: */*"); - slist1 = curl_slist_append(slist1, "Referer: https://www.stw.berlin/mensen.html"); - slist1 = curl_slist_append(slist1, "X-Requested-With: XMLHttpRequest"); - slist1 = curl_slist_append(slist1, "Connection: keep-alive"); - slist1 = curl_slist_append(slist1, "DNT: 1"); - - curl = curl_easy_init(); - curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 102400L); - curl_easy_setopt(curl, CURLOPT_URL, "https://www.stw.berlin/xhr/speiseplan-wochentag.html"); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L); - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfield.c_str()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)32); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist1); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.63.0"); - curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); - curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS); - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); - curl_easy_setopt(curl, CURLOPT_SSH_KNOWNHOSTS, "/home/max/.ssh/known_hosts"); - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); - - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - res = curl_easy_perform(curl); - if (res != CURLE_OK){ - //TODO: return int as status instead of boolean - maybe even this curl error? - return res; - } - curl_easy_cleanup(curl); - curl = nullptr; - curl_slist_free_all(slist1); - slist1 = nullptr; - fclose(fp); - return CURLE_OK; - } else { - return CURLE_FAILED_INIT; - } -} diff --git a/src/Utilities/sqdb.cpp b/src/Utilities/sqdb.cpp deleted file mode 100644 index 0b88139..0000000 --- a/src/Utilities/sqdb.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "sqdb.hpp" - -#include - -using namespace sqdb; - -Exception::Exception(sqlite3* db) -{ - m_errorCode = sqlite3_errcode(db); - auto* c = (SQDB_CHAR*) -#ifdef SQDB_UTF8 - sqlite3_errmsg -#else - sqlite3_errmsg16 -#endif - (db); - m_errorMsg = SQDB_STRDUP(c); -} - -Exception::Exception(sqlite3* db, int errorCode) - : m_errorCode(errorCode) -{ - auto* c = (SQDB_CHAR*) -#ifdef SQDB_UTF8 - sqlite3_errmsg -#else - sqlite3_errmsg16 -#endif - (db); - m_errorMsg = SQDB_STRDUP(c); -} - -Exception::Exception(const SQDB_CHAR* errorMsg) - : m_errorCode(-1) -{ - m_errorMsg = SQDB_STRDUP(errorMsg); -} - -Exception::~Exception() -{ - free(m_errorMsg); -} - -int Exception::GetErrorCode() const -{ - return m_errorCode; -} - -const SQDB_CHAR* Exception::GetErrorMsg() const -{ - return m_errorMsg; -} - -RefCount::RefCount() - : m_refCount(nullptr) -{ -} - -RefCount::RefCount(const RefCount& x) - : m_refCount(x.m_refCount) -{ -} - -RefCount& RefCount::operator=(const RefCount& x) -{ - if ( this != &x ) - { - m_refCount = x.m_refCount; - } - return *this; -} - -void RefCount::IncRef() -{ - if ( !m_refCount ) - { - m_refCount = new unsigned; - *m_refCount = 0; - } - ++*m_refCount; -} - -unsigned RefCount::DecRef() -{ - assert(m_refCount); - unsigned value = --*m_refCount; - if ( value == 0 ) - { - delete m_refCount; - m_refCount = nullptr; - } - return value; -} - -Blob::Blob(const void* data, int size) - : m_size(size) -{ - m_data = new char[size]; - std::uninitialized_copy((char*)data, (char*)data + size, m_data); - IncRef(); -} - -Blob::Blob(const Blob& x) - : RefCount(x), m_data(x.m_data), m_size(x.m_size) -{ - IncRef(); -} - -Blob& Blob::operator=(const Blob& x) -{ - if ( this != &x ) - { - RefCount::operator=(x); - IncRef(); - m_data = x.m_data; - m_size = x.m_size; - } - return *this; -} - -int Blob::GetSize() const -{ - return m_size; -} - -const char* Blob::GetData() const -{ - return m_data; -} - -Blob::~Blob() -{ - if ( DecRef() == 0 ) - { - delete[] m_data; - } -} - -Convertor::Convertor(sqlite3* db, sqlite3_stmt* stmt, int field) - : m_db(db), m_stmt(stmt), m_field(field) -{ -} - -Convertor::operator int() const -{ - return GetInt(); -} - -Convertor::operator unsigned long() const -{ - return GetUnsignedLong(); -} - -Convertor::operator long long() const -{ - return GetLongLong(); -} - -Convertor::operator double() const -{ - return GetDouble(); -} - -Convertor::operator SQDB_STD_STRING() const -{ - return GetString(); -} - -Convertor::operator const SQDB_CHAR*() const -{ - return GetText(); -} - -Convertor::operator Blob() const -{ - return GetBlob(); -} - -int Convertor::GetInt() const -{ - assert(m_stmt); - return sqlite3_column_int(m_stmt, m_field); -} - -unsigned long Convertor::GetUnsignedLong() const -{ - assert(m_stmt); - const char* data = (char*) sqlite3_column_blob(m_stmt, m_field); - return strtoul(data, nullptr, 10); -} - -long long Convertor::GetLongLong() const -{ - assert(m_stmt); - return sqlite3_column_int64(m_stmt, m_field); -} - -double Convertor::GetDouble() const -{ - assert(m_stmt); - return sqlite3_column_double(m_stmt, m_field); -} - -SQDB_STD_STRING Convertor::GetString() const -{ - assert(m_stmt); - const auto* result = (const SQDB_CHAR*) -#ifdef SQDB_UTF8 - sqlite3_column_text -#else - sqlite3_column_text16 -#endif - (m_stmt, m_field); - return result; -} - -const SQDB_CHAR* Convertor::GetText() const -{ - assert(m_stmt); - const auto* result = (const SQDB_CHAR*) -#ifdef SQDB_UTF8 - sqlite3_column_text -#else - sqlite3_column_text16 -#endif - (m_stmt, m_field); - return result; -} - -Blob Convertor::GetBlob() const -{ - assert(m_stmt); - const void* data = sqlite3_column_blob(m_stmt, m_field); - int size = sqlite3_column_bytes(m_stmt, m_field); - return Blob(data, size); -} - -Statement::Statement(sqlite3* db, sqlite3_stmt* stmt) - : RefCount(), m_db(db), m_stmt(stmt), m_needReset(false) -{ - IncRef(); -} - -Statement::Statement(const Statement& x) - : RefCount(x), m_db(x.m_db), m_stmt(x.m_stmt), m_needReset(false) -{ - IncRef(); -} - -Statement& Statement::operator=(const Statement& x) -{ - if ( this != &x ) - { - RefCount::operator=(x); - IncRef(); - m_db = x.m_db; - m_stmt = x.m_stmt; - m_needReset = x.m_needReset; - } - return *this; -} - -bool Statement::Next() { - assert(m_stmt); - int ret = SQLITE_BUSY; - - while (ret == SQLITE_BUSY) { - ret = sqlite3_step(m_stmt); - m_needReset = true; - if ( ret == SQLITE_DONE ) { - return false; - } else if ( ret == SQLITE_ROW ) { - return true; - } else if ( ret == SQLITE_BUSY ) { - sleep(1); - continue; - } else { - throw Exception(m_db, ret); - } - } - return false; -} - -Convertor Statement::GetField(int field) const -{ - return {m_db, m_stmt, field}; -} - -Statement::~Statement() -{ - if ( DecRef() == 0 ) - { - sqlite3_finalize(m_stmt); - } -} - -void Statement::BindBlob(int i, const void* value, int n) -{ - if ( m_needReset ) - Reset(); - DoBind(i, value, n); -} - -void Statement::BindNull(int i) -{ - if ( m_needReset ) - Reset(); - DoBind(i); -} - -void Statement::DoBind(int i, int value) -{ - const int ret = sqlite3_bind_int(m_stmt, i, value); - CHECK(m_db, ret); -} - -void Statement::DoBind(int i, long long value) -{ - const int ret = sqlite3_bind_int64(m_stmt, i, value); - CHECK(m_db, ret); -} - -void Statement::DoBind(int i, double value) -{ - const int ret = sqlite3_bind_double(m_stmt, i, value); - CHECK(m_db, ret); -} - -void Statement::DoBind(int i, const SQDB_STD_STRING& value) -{ - const int ret = -#ifdef SQDB_UTF8 - sqlite3_bind_text -#else - sqlite3_bind_text16 -#endif - (m_stmt, i, value.c_str(), value.size() * sizeof(SQDB_STD_STRING::value_type), SQLITE_TRANSIENT); - CHECK(m_db, ret); -} - -void Statement::DoBind(int i, const SQDB_CHAR* value) -{ - const int len = SQDB_STRLEN(value); - - const int ret = -#ifdef SQDB_UTF8 - sqlite3_bind_text -#else - sqlite3_bind_text16 -#endif - (m_stmt, i, value, len * sizeof(SQDB_CHAR), SQLITE_TRANSIENT); - - CHECK(m_db, ret); -} - -void Statement::DoBind(int i, const void* value, int n) -{ - const int ret = sqlite3_bind_blob(m_stmt, i, value, n, SQLITE_TRANSIENT); - CHECK(m_db, ret); -} - -void Statement::DoBind(int i) -{ - const int ret = sqlite3_bind_null(m_stmt, i); - CHECK(m_db, ret); -} - -void Statement::Reset() -{ - assert(m_needReset); - assert(m_stmt); - - sqlite3_reset(m_stmt); - m_needReset = false; -} - -QueryStr::QueryStr() - : m_buf(nullptr) -{ -} - -const SQDB_CHAR* QueryStr::Format(const SQDB_CHAR* fmt, ...) -{ - va_list va; - va_start(va, fmt); -#ifdef SQDB_UTF8 - sqlite3_free(m_buf); - m_buf = sqlite3_vmprintf(fmt, va); -#else - free(m_buf); - int len = _vscwprintf(fmt, va) + 1; - m_buf = (SQDB_CHAR*)malloc(len * sizeof(SQDB_CHAR)); - vswprintf(m_buf, len, fmt, va); -#endif - - va_end(va); - - return m_buf; -} - -const SQDB_CHAR* QueryStr::Get() const -{ - return m_buf; -} - -QueryStr::~QueryStr() -{ -#ifdef SQDB_UTF8 - sqlite3_free(m_buf); -#else - free(m_buf); -#endif -} - -Db::Db(const SQDB_CHAR* fileName) - : RefCount() -{ -#ifdef SQDB_UTF8 - const int ret = sqlite3_open(fileName, &m_db); -#else - const int ret = sqlite3_open16(fileName, &m_db); -#endif - CHECK(m_db, ret); - - IncRef(); -} - -void Db::BeginTransaction() -{ - Query(SQDB_MAKE_TEXT("BEGIN;")).Next(); -} - -void Db::CommitTransaction() -{ - Query(SQDB_MAKE_TEXT("COMMIT;")).Next(); -} - -void Db::RollbackTransaction() -{ - Query(SQDB_MAKE_TEXT("ROLLBACK;")).Next(); -} - -bool Db::TableExists(const SQDB_CHAR* tableName) -{ - QueryStr str; - Statement s = - Query( - str.Format(SQDB_MAKE_TEXT("select count(*) from sqlite_master where type='table' and name='%s';"), tableName)); - s.Next(); - const int count = s.GetField(0); - return count > 0; -} - -Statement Db::Query(const SQDB_CHAR* queryStr) -{ - sqlite3_stmt* stmt = nullptr; -#ifdef SQDB_UTF8 - const int ret = sqlite3_prepare(m_db, queryStr, -1, &stmt, nullptr); -#else - const int ret = sqlite3_prepare16(m_db, queryStr, -1, &stmt, NULL); -#endif - CHECK(m_db, ret); - - return Statement(m_db, stmt); -} - -long long Db::LastId() -{ - long long ret = sqlite3_last_insert_rowid(m_db); - return ret; -} - -Db::Db(const Db& x) - : RefCount(x), - m_db(x.m_db) -{ - IncRef(); -} - -Db& Db::operator=(const Db& x) -{ - if ( this != &x ) - { - RefCount::operator=(x); - - IncRef(); - m_db = x.m_db; - } - return *this; -} - -Db::~Db() -{ - if ( DecRef() == 0 ) - { - sqlite3_close(m_db); - } -} - diff --git a/src/Utilities/sqdb.hpp b/src/Utilities/sqdb.hpp deleted file mode 100644 index ea38787..0000000 --- a/src/Utilities/sqdb.hpp +++ /dev/null @@ -1,207 +0,0 @@ -#pragma once - -#include - -#include "sqlite3.h" - -#ifdef _WIN32 -# include -# define SQDB_MAKE_TEXT(x) _TEXT(x) -# define SQDB_STRLEN _tcslen -# define SQDB_STRDUP _tcsdup -#else -# define SQDB_MAKE_TEXT(x) (x) -# define SQDB_STRLEN strlen -# define SQDB_STRDUP strdup -#endif - -#if !defined(SQDB_UTF16) && !defined(SQDB_UTF8) -# ifdef _WIN32 -# if defined(UNICODE) || defined(_UNICODE) -# define SQDB_UTF16 -# else -# define SQDB_UTF8 -# endif -# else -# define SQDB_UTF8 -# endif -#endif - -#ifdef SQDB_UTF8 -# define SQDB_CHAR char -# define SQDB_STD_STRING std::string -#endif - -#ifdef SQDB_UTF16 -# define SQDB_CHAR TCHAR -# define SQDB_STD_STRING std::wstring -#endif - -namespace sqdb -{ - - class Exception - { - public: - Exception(sqlite3* db); - - Exception(sqlite3* db, int errorCode); - - Exception(const SQDB_CHAR* errorMsg); - - ~Exception(); - - int GetErrorCode() const; - - const SQDB_CHAR* GetErrorMsg() const; - private: - int m_errorCode; - SQDB_CHAR* m_errorMsg; - }; - -#define CHECK(db, returnCode) \ - if ( (returnCode) != SQLITE_OK ) throw Exception(db, returnCode) - - class RefCount - { - protected: - RefCount(); - - RefCount(const RefCount& x); - RefCount& operator=(const RefCount& x); - - void IncRef(); - unsigned DecRef(); - - private: - unsigned* m_refCount; - }; - - class Blob : public RefCount - { - public: - Blob(const void* data, int size); - - Blob(const Blob& x); - Blob& operator=(const Blob& x); - - int GetSize() const; - const char* GetData() const; - - ~Blob(); - - private: - char* m_data; - int m_size; - }; - - class Convertor - { - public: - Convertor(sqlite3* db, sqlite3_stmt* stmt, int field); - - operator int() const; - operator unsigned long() const; - operator long long() const; - operator double() const; - operator SQDB_STD_STRING() const; - operator const SQDB_CHAR*() const; - operator Blob() const; - - int GetInt() const; - unsigned long GetUnsignedLong() const; - long long GetLongLong() const; - double GetDouble() const; - SQDB_STD_STRING GetString() const; - const SQDB_CHAR* GetText() const; - Blob GetBlob() const; - - private: - sqlite3* m_db; - sqlite3_stmt* m_stmt; - int m_field; - }; - - class Statement : public RefCount - { - public: - Statement(sqlite3* db, sqlite3_stmt* stmt); - - Statement(const Statement& x); - Statement& operator=(const Statement& x); - - bool Next(); - Convertor GetField(int field) const; - - template - void Bind(int i, const T& value) - { - if ( m_needReset ) - Reset(); - DoBind(i, value); - } - - void BindBlob(int i, const void* value, int n); - void BindNull(int i); - - ~Statement(); - - private: - void DoBind(int i, int value); - void DoBind(int i, long long value); - void DoBind(int i, double value); - void DoBind(int i, const SQDB_STD_STRING& value); - void DoBind(int i, const SQDB_CHAR* value); - - // Bind blob. - void DoBind(int i, const void* value, int n); - - // Bind null. - void DoBind(int i); - - // Reset binders so that new values can be bound. - void Reset(); - - sqlite3* m_db; - sqlite3_stmt* m_stmt; - bool m_needReset; - }; - - class QueryStr - { - public: - QueryStr(); - - const SQDB_CHAR* Format(const SQDB_CHAR* fmt, ...); - - const SQDB_CHAR* Get() const; - - ~QueryStr(); - - private: - SQDB_CHAR* m_buf; - }; - - class Db : public RefCount - { - public: - Db(const SQDB_CHAR* fileName); - - void BeginTransaction(); - void CommitTransaction(); - void RollbackTransaction(); - - bool TableExists(const SQDB_CHAR* tableName); - Statement Query(const SQDB_CHAR* queryStr); - long long LastId(); - - Db(const Db& x); - Db& operator=(const Db& x); - - ~Db(); - - private: - sqlite3* m_db; - }; - -} diff --git a/src/main.cpp b/src/main.cpp index 8a08b4a..d90e58d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,58 +1,5 @@ -#include "N-Commands/KlingerHandler.hpp" -#include "N-Commands/RelationshipHandler.hpp" -#include "Utilities/GetEssen.hpp" -#include "Utilities/Logger.hpp" -#include "Utilities/Utilities.hpp" -#include "Utilities/sqdb.hpp" -#include -#include -#include +#include - -using namespace std; -using namespace Mongoose; - -class MyController : public JsonController -{ -public: - void hello(Request &request, JsonResponse &response) - { - response["text"] = "Hello " + htmlEntities(request.get("name", "... what's your name ?")) + "\n"; - response["success"] = "1"; - response["session"] = "NULL"; - } - void klinger(Request &request, JsonResponse &response){ - KlingerHandler klinger; - klinger.onCall(request, response); - } - void relation(Request &request, JsonResponse &response){ - RelationshipHandler relation; - relation.onCall(request, response); - } - void mensa(Request &request, JsonResponse &response){ - returnEssen(request, response); - } - - void setup() - { - setPrefix("/api/v1"); - addRouteResponse("GET", "/hello", MyController, hello, JsonResponse); - addRouteResponse("GET", "/klinger", MyController, klinger, JsonResponse); - addRouteResponse("GET", "/relation", MyController, relation, JsonResponse); - addRouteResponse("GET", "/mensa", MyController, mensa, JsonResponse); - } -}; - - -int main() -{ - MyController myController; - Server server(8080); - server.registerController(&myController); - - server.start(); - - while (1) { - MyController::sleep(10); - } +int main() { + std::cout << "Hello, World\n" << std::endl; } \ No newline at end of file -- cgit v1.2.3-54-g00ecf