diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/Enum2String.hpp | 10 | ||||
-rw-r--r-- | include/GetEssen.hpp | 47 | ||||
-rw-r--r-- | include/Handler.hpp | 21 | ||||
-rw-r--r-- | include/RelationshipHandler.hpp | 17 | ||||
-rw-r--r-- | include/Response.hpp | 20 | ||||
-rw-r--r-- | include/SimpleHandlers.hpp | 13 | ||||
-rw-r--r-- | include/Utilities.hpp | 147 | ||||
-rw-r--r-- | include/sqdb.hpp | 227 |
8 files changed, 497 insertions, 5 deletions
diff --git a/include/Enum2String.hpp b/include/Enum2String.hpp index 4992e0d..da3ab94 100644 --- a/include/Enum2String.hpp +++ b/include/Enum2String.hpp @@ -3,13 +3,13 @@ #undef END_ENUM #ifndef GENERATE_ENUM_STRINGS -#define DECL_ENUM_ELEMENT( element ) element -#define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME -#define END_ENUM( ENUM_NAME ) ENUM_NAME; \ +#define DECL_ENUM_ELEMENT(element) element +#define BEGIN_ENUM(ENUM_NAME) typedef enum tag##ENUM_NAME +#define END_ENUM(ENUM_NAME) ENUM_NAME; \ std::string GetString##ENUM_NAME(enum tag##ENUM_NAME index); #else #define DECL_ENUM_ELEMENT( element ) #element - #define BEGIN_ENUM( ENUM_NAME ) std::string gs_##ENUM_NAME [] = - #define END_ENUM( ENUM_NAME ) ; std::string GetString##ENUM_NAME(\ +#define BEGIN_ENUM( ENUM_NAME ) std::string gs_##ENUM_NAME [] = +#define END_ENUM( ENUM_NAME ) ; std::string GetString##ENUM_NAME(\ tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; } #endif
\ No newline at end of file diff --git a/include/GetEssen.hpp b/include/GetEssen.hpp new file mode 100644 index 0000000..ff75029 --- /dev/null +++ b/include/GetEssen.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include <iostream> +#include <sys/stat.h> + +#include <curl/curl.h> + +#include <boost/date_time/date_formatting.hpp> +#include <boost/date_time/gregorian/gregorian.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + +#include "Handler.hpp" +#include "Response.hpp" + +namespace Handler { + namespace MensaHandler { + using std::string; + using boost::posix_time::ptime; + + struct MensaEssen { + int ID{191}; + string Message{"nothing got back! There was an error!!"}; + ptime Datum; + ptime LastModified; + }; + + enum mensa { + Adlershof = 191, Nord = 147, Sued = 367 + }; + + + bool db_update_mensa_message(const int &mensaID, const ptime &mensaDatum, const string &message); + + bool db_insert_mensa_message(const int &mensaID, const ptime &mensaDatum, const string &message); + + MensaEssen db_get_mensa_message(const int &mensaID, const ptime &mensaDatum); + + string getEssen(const int mensa_ID, const int offset); + + string read_mensa_message_from_file(const int &mensa_id_file); + } + + json mensaHandler(std::string const &arguments, std::string const &session, void *payload); +} + + + diff --git a/include/Handler.hpp b/include/Handler.hpp new file mode 100644 index 0000000..3d4b830 --- /dev/null +++ b/include/Handler.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "crow.h" + +namespace Handler { + typedef crow::json::wvalue json; + typedef std::function<json(std::string const &arguments, std::string const &session, + void *payload)> handler_function; + + struct CommandHandler { + [[nodiscard]] json exec(std::string const &arguments, std::string const &session) const { + return func(arguments, session, payload); + } + + handler_function func{nullptr}; + std::string description; + void *payload{nullptr}; + }; + + std::vector<std::string> tokenizeArguments(std::string const &arguments, std::string const &delimiter = " "); +}
\ No newline at end of file diff --git a/include/RelationshipHandler.hpp b/include/RelationshipHandler.hpp new file mode 100644 index 0000000..5b609f4 --- /dev/null +++ b/include/RelationshipHandler.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "Handler.hpp" + +namespace Handler { + namespace RelationShipHandler { + std::vector<int> buildCalArr(std::vector<std::string> nameV); + + int calculate(std::vector<std::string> names); + + bool isAlphaNum(const std::string &str); + + std::string rsStart(std::vector<std::string> const &names); + } + + json relationShipHandler(std::string const &arguments, std::string const &session, void *payload); +} diff --git a/include/Response.hpp b/include/Response.hpp new file mode 100644 index 0000000..53043c8 --- /dev/null +++ b/include/Response.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "crow.h" + +#include "AnnotationTypes.hpp" + +namespace Response { + using Reply::AnnotationType; + typedef crow::json::wvalue json; + + json simple_response(std::string const &text, std::string const &session = "null", bool success = true); + + json create_annotation(AnnotationType annotation = AnnotationType::none, std::string const &extra = ""); + + json create_text(std::string const &text); + + json create_text(std::string const &text, std::vector<json> &&annotations); + + json create_response(std::vector<json> &&reply, std::string const &session = "null", bool success = true); +}
\ No newline at end of file diff --git a/include/SimpleHandlers.hpp b/include/SimpleHandlers.hpp new file mode 100644 index 0000000..06dfcd1 --- /dev/null +++ b/include/SimpleHandlers.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "Handler.hpp" + +namespace Handler { + json helpHandler(std::string const &arguments, std::string const &session, void *payload); + + json stopHandler(std::string const &arguments, std::string const &session, void *payload); + + json wikiHandler(std::string const &arguments, std::string const &session, void *payload); + + json klingerHandler(std::string const &arguments, std::string const &session, void *payload); +}
\ No newline at end of file diff --git a/include/Utilities.hpp b/include/Utilities.hpp new file mode 100644 index 0000000..781b9fb --- /dev/null +++ b/include/Utilities.hpp @@ -0,0 +1,147 @@ +#pragma once + +#include <ctime> +#include <string> +#include <curl/curl.h> +#include <boost/date_time.hpp> + +#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 <fstream> + +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/include/sqdb.hpp b/include/sqdb.hpp new file mode 100644 index 0000000..b92cac6 --- /dev/null +++ b/include/sqdb.hpp @@ -0,0 +1,227 @@ +#pragma once + +#include <string> + +#include "sqlite3.h" + +#ifdef _WIN32 +# include <tchar.h> +# 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<class T> + 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; + }; + +} |