From 48d6a7408f2371c5b66482cc68ec2b801d444700 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 15:40:36 +0200 Subject: started work on latex render command --- include/SimpleHandlers.hpp | 2 ++ src/SimpleHandlers.cpp | 30 ++++++++++++++++++++++++++++++ src/main.cpp | 4 ++++ 3 files changed, 36 insertions(+) diff --git a/include/SimpleHandlers.hpp b/include/SimpleHandlers.hpp index aef2372..1121685 100644 --- a/include/SimpleHandlers.hpp +++ b/include/SimpleHandlers.hpp @@ -11,5 +11,7 @@ namespace Handler { json wikiHandler(std::string const &arguments, std::string const &session, void *payload); + json latexRenderHandler(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/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index ee801d4..0a4bdb1 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -2,7 +2,11 @@ #include "Response.hpp" +#include +#include #include +#include +#include using namespace Response; @@ -87,3 +91,29 @@ json Handler::sayHandler(const std::string &arguments, const std::string &sessio (void) payload; return simple_response(arguments, session, true); } + +std::string url_encode(std::string const &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (char c : value) { + // Keep alphanumeric and other accepted characters intact + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + escaped << c; + continue; + } + + // Any other characters are percent-encoded + escaped << std::uppercase; + escaped << '%' << std::setw(2) << int((unsigned char) c); + escaped << std::nouppercase; + } + + return escaped.str(); +} + +json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) { + (void) payload; + return simple_response("https://latex.codecogs.com/png.latex?" + url_encode(arguments), session, true); +} diff --git a/src/main.cpp b/src/main.cpp index 948bc1d..2e215cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,6 +39,10 @@ int main() { return createPlainDescriptionFromText( "{adlershof, nord, sued} Shows the daily menu of the mensa at various places."); }}); + Handler::CommandHandler{"latex", Handler::latexRenderHandler [createPlainDescriptionFromText]() { + return createPlainDescriptionFromText( + "Renders the given string to a png"); + }}); regular_commands.emplace_back( Handler::CommandHandler{"klinger", Handler::klingerHandler, [createPlainDescriptionFromText]() { return createPlainDescriptionFromText("Greats in french. Bonjour!"); -- cgit v1.2.3-54-g00ecf From fc2f037e216e517ec4b87b0663277a3fc40c1d74 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:23:04 +0200 Subject: fix stuff, start encoding, add doku for attachment sending --- README.md | 15 ++++++- include/Response.hpp | 5 +++ src/Response.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++++++++- src/SimpleHandlers.cpp | 30 +++++++++++++- src/main.cpp | 3 +- 5 files changed, 155 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 22f8a05..ea08283 100644 --- a/README.md +++ b/README.md @@ -64,10 +64,23 @@ No extra content. The text should be printed underlined. No extra content. +##### `attachment` +The text is the caption of an attached file. +Extra content: an `attachment`-object. (TODO: extend to array of attachments) + ##### `command` -The text should be formated in a way to underlying platform of the bridge would recognize it (e.g. prefix with '/'). +The text should be formatted in a way to underlying platform of the bridge would recognize it (e.g. prefix with '/'). Extra content: the description of the command. ##### `link` The text should be formatted as a link. Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. + +#### `attachment` +The `attachment` object: + +| Field | Type | Description | +|-------|------|-------------| +| `type` | string | MIME type of the attachment (e.g. "png", "gif", etc) | +| `name` | string | The name of the file (including the file ending) | +| `content` | string | Base64 encoded file contents | \ No newline at end of file diff --git a/include/Response.hpp b/include/Response.hpp index 82edb53..3e42d0d 100644 --- a/include/Response.hpp +++ b/include/Response.hpp @@ -11,6 +11,11 @@ namespace Response { // create a full response of just plain text json simple_response(std::string const &text, std::string const &session = "null", bool success = true); + // create file attachment (is an annotation) + json create_attachment(std::string const &file_path); + json create_attachment(std::string const &file_path, std::string const &file_name); + json create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type); + // "nested" annotations: the extra field is again an array of text-annotation pairs json create_annotation(AnnotationType annotation, std::vector &&extra); // construct an extra field with no special annotations in the extra diff --git a/src/Response.cpp b/src/Response.cpp index 286de52..d97ab40 100644 --- a/src/Response.cpp +++ b/src/Response.cpp @@ -44,4 +44,109 @@ Response::json Response::create_response(std::vector &&reply, std::string response["session"] = session; response["reply"] = std::move(reply); return response; -} \ No newline at end of file +} + +static std::string const base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +std::string base64_encode(unsigned char const *input, unsigned int const len) { + std::string ret; + size_t i = 0; + unsigned char bytes[3]; + unsigned char sextets[4]; + + while (i <= (len - 3)) { + bytes[0] = *(input++); + bytes[1] = *(input++); + bytes[2] = *(input++); + + sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte + sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) + >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte + sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) + >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte + sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte + + for (size_t j = 0; j < 4; ++j) { + ret += base64_chars[sextets[j]]; + } + + i += 3; // increases to go to third byte + } + + if (i != len) { + size_t k = 0; + size_t j = len - i; // Find index of last byte + while (k < j) { // Sets first bytes + bytes[k] = *(input++); + ++k; + } + + while (j < 3) { // Set last bytes to 0x00 + bytes[j] = '\0'; + ++j; + } + + sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte + sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) + >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte + sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) + >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte + // No last one is needed, because if there were 4, then (i == len) == true + + for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data + ret += base64_chars[sextets[j]]; // Appends them to string + } + + while ((j++) < 4) // Appends remaining ='s + ret += '='; + + } + + return ret; +} + +std::string base64_encode_file(std::string const &path) { + std::vector temp; + + std::ifstream infile; + infile.open(path, std::ios::binary); // Open file in binary mode + if (infile.is_open()) { + while (!infile.eof()) { + char c = (char) infile.get(); + temp.push_back(c); + } + infile.close(); + } else return "File could not be opened"; + std::string ret(temp.begin(), temp.end() - 1); + ret = base64_encode((unsigned const char *) ret.c_str(), ret.size()); + + return ret; +} + +Response::json Response::create_attachment(std::string const &file_path) { + std::string name = file_path; + if (auto pos = file_path.find_last_of('/'); pos != std::string::npos) { + name = file_path.substr(pos + 1); + } + return create_attachment(file_path, name); +} + +Response::json Response::create_attachment(std::string const &file_path, std::string const &file_name) { + std::string type = "unknown"; + if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) { + type = file_name.substr(pos + 1); + } + return create_attachment(file_path, file_name, type); +} + +Response::json +Response::create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type) { + json attachment(crow::json::type::Object); + attachment["type"] = file_type; + attachment["name"] = file_name; + attachment["content"] = base64_encode_file(file_path); + return attachment; +} diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 0a4bdb1..d9c6448 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -2,11 +2,14 @@ #include "Response.hpp" +#include #include +#include #include -#include #include #include +#include +#include using namespace Response; @@ -113,7 +116,30 @@ std::string url_encode(std::string const &value) { return escaped.str(); } + +std::string exec(const char* cmd) { + std::array buffer{}; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} + json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) { (void) payload; - return simple_response("https://latex.codecogs.com/png.latex?" + url_encode(arguments), session, true); + + std::string file = exec("mktemp"); + + std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' " + "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' " + "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' " + "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " + "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); + + return simple_response(result, session, true); } diff --git a/src/main.cpp b/src/main.cpp index 2e215cd..8c6571f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,8 @@ int main() { return createPlainDescriptionFromText( "{adlershof, nord, sued} Shows the daily menu of the mensa at various places."); }}); - Handler::CommandHandler{"latex", Handler::latexRenderHandler [createPlainDescriptionFromText]() { + regular_commands.emplace_back( + Handler::CommandHandler{"latex", Handler::latexRenderHandler, [createPlainDescriptionFromText]() { return createPlainDescriptionFromText( "Renders the given string to a png"); }}); -- cgit v1.2.3-54-g00ecf From ddc44ca19ba82b7638a909714122e73b92a5183b Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:43:35 +0200 Subject: simplified attachments (server side), moved into handlers again --- README.md | 14 ++---- include/AnnotationTypes.hpp | 1 + include/Response.hpp | 5 --- src/Response.cpp | 105 -------------------------------------------- src/SimpleHandlers.cpp | 95 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 97 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index ea08283..fd3aa1c 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,8 @@ No extra content. ##### `attachment` The text is the caption of an attached file. -Extra content: an `attachment`-object. (TODO: extend to array of attachments) +Extra content: String of content: "`file_name`;`file_type`;`file_content`", where `file_content` is base64 encoded. +E.g.: "image.png;png;iVBORw0KGgoAAAANSUhEUgAAABwAAAAMBAMAAACD9cA8AAAALVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAELt2Mu9Eic1mIqtU3XZzvlQAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACJSURBVAgdY2BgFGCAARCTyQDGAzP5HOBcENMVzgMx0zsqGXjmGDBwzpwFYjJoMjBsZkhjOMlQCWIyvGLgvMBQxVDhIABkMrAFMPDqTE5gWPv0AJDJwL6BQW4ByLTlD4BMBo4JMnJADscBhgAgk4HXwYDXgeEINwMbkDZg4LFZwFVzUoAt5ySICQDlYB5evEnwqgAAAABJRU5ErkJggg==" ##### `command` The text should be formatted in a way to underlying platform of the bridge would recognize it (e.g. prefix with '/'). @@ -74,13 +75,4 @@ Extra content: the description of the command. ##### `link` The text should be formatted as a link. -Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. - -#### `attachment` -The `attachment` object: - -| Field | Type | Description | -|-------|------|-------------| -| `type` | string | MIME type of the attachment (e.g. "png", "gif", etc) | -| `name` | string | The name of the file (including the file ending) | -| `content` | string | Base64 encoded file contents | \ No newline at end of file +Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. \ No newline at end of file diff --git a/include/AnnotationTypes.hpp b/include/AnnotationTypes.hpp index 66d0b9d..8fba983 100644 --- a/include/AnnotationTypes.hpp +++ b/include/AnnotationTypes.hpp @@ -14,6 +14,7 @@ namespace Reply { DECL_ENUM_ELEMENT(none), DECL_ENUM_ELEMENT(bold), DECL_ENUM_ELEMENT(italics), + DECL_ENUM_ELEMENT(attachment), DECL_ENUM_ELEMENT(strikethrough), DECL_ENUM_ELEMENT(underline), DECL_ENUM_ELEMENT(command), diff --git a/include/Response.hpp b/include/Response.hpp index 3e42d0d..82edb53 100644 --- a/include/Response.hpp +++ b/include/Response.hpp @@ -11,11 +11,6 @@ namespace Response { // create a full response of just plain text json simple_response(std::string const &text, std::string const &session = "null", bool success = true); - // create file attachment (is an annotation) - json create_attachment(std::string const &file_path); - json create_attachment(std::string const &file_path, std::string const &file_name); - json create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type); - // "nested" annotations: the extra field is again an array of text-annotation pairs json create_annotation(AnnotationType annotation, std::vector &&extra); // construct an extra field with no special annotations in the extra diff --git a/src/Response.cpp b/src/Response.cpp index d97ab40..53b0d8c 100644 --- a/src/Response.cpp +++ b/src/Response.cpp @@ -45,108 +45,3 @@ Response::json Response::create_response(std::vector &&reply, std::string response["reply"] = std::move(reply); return response; } - -static std::string const base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -std::string base64_encode(unsigned char const *input, unsigned int const len) { - std::string ret; - size_t i = 0; - unsigned char bytes[3]; - unsigned char sextets[4]; - - while (i <= (len - 3)) { - bytes[0] = *(input++); - bytes[1] = *(input++); - bytes[2] = *(input++); - - sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte - sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) - >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte - sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) - >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte - sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte - - for (size_t j = 0; j < 4; ++j) { - ret += base64_chars[sextets[j]]; - } - - i += 3; // increases to go to third byte - } - - if (i != len) { - size_t k = 0; - size_t j = len - i; // Find index of last byte - while (k < j) { // Sets first bytes - bytes[k] = *(input++); - ++k; - } - - while (j < 3) { // Set last bytes to 0x00 - bytes[j] = '\0'; - ++j; - } - - sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte - sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) - >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte - sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) - >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte - // No last one is needed, because if there were 4, then (i == len) == true - - for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data - ret += base64_chars[sextets[j]]; // Appends them to string - } - - while ((j++) < 4) // Appends remaining ='s - ret += '='; - - } - - return ret; -} - -std::string base64_encode_file(std::string const &path) { - std::vector temp; - - std::ifstream infile; - infile.open(path, std::ios::binary); // Open file in binary mode - if (infile.is_open()) { - while (!infile.eof()) { - char c = (char) infile.get(); - temp.push_back(c); - } - infile.close(); - } else return "File could not be opened"; - std::string ret(temp.begin(), temp.end() - 1); - ret = base64_encode((unsigned const char *) ret.c_str(), ret.size()); - - return ret; -} - -Response::json Response::create_attachment(std::string const &file_path) { - std::string name = file_path; - if (auto pos = file_path.find_last_of('/'); pos != std::string::npos) { - name = file_path.substr(pos + 1); - } - return create_attachment(file_path, name); -} - -Response::json Response::create_attachment(std::string const &file_path, std::string const &file_name) { - std::string type = "unknown"; - if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) { - type = file_name.substr(pos + 1); - } - return create_attachment(file_path, file_name, type); -} - -Response::json -Response::create_attachment(std::string const &file_path, std::string const &file_name, std::string const &file_type) { - json attachment(crow::json::type::Object); - attachment["type"] = file_type; - attachment["name"] = file_name; - attachment["content"] = base64_encode_file(file_path); - return attachment; -} diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index d9c6448..70b3a8c 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -116,7 +116,6 @@ std::string url_encode(std::string const &value) { return escaped.str(); } - std::string exec(const char* cmd) { std::array buffer{}; std::string result; @@ -130,6 +129,86 @@ std::string exec(const char* cmd) { return result; } +static std::string const base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +std::string base64_encode(unsigned char const *input, unsigned int const len) { + std::string ret; + size_t i = 0; + unsigned char bytes[3]; + unsigned char sextets[4]; + + while (i <= (len - 3)) { + bytes[0] = *(input++); + bytes[1] = *(input++); + bytes[2] = *(input++); + + sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte + sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) + >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte + sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) + >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte + sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte + + for (unsigned char sextet : sextets) { + ret += base64_chars[sextet]; + } + + i += 3; // increases to go to third byte + } + + if (i != len) { + size_t k = 0; + size_t j = len - i; // Find index of last byte + while (k < j) { // Sets first bytes + bytes[k] = *(input++); + ++k; + } + + while (j < 3) { // Set last bytes to 0x00 + bytes[j] = '\0'; + ++j; + } + + sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte + sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) + >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte + sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) + >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte + // No last one is needed, because if there were 4, then (i == len) == true + + for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data + ret += base64_chars[sextets[j]]; // Appends them to string + } + + while ((j++) < 4) // Appends remaining ='s + ret += '='; + + } + + return ret; +} + +std::string base64_encode_file(std::string const &path) { + std::vector temp; + + std::ifstream infile; + infile.open(path, std::ios::binary); // Open file in binary mode + if (infile.is_open()) { + while (!infile.eof()) { + char c = (char) infile.get(); + temp.push_back(c); + } + infile.close(); + } else return "File could not be opened"; + std::string ret(temp.begin(), temp.end() - 1); + ret = base64_encode((unsigned const char *) ret.c_str(), ret.size()); + + return ret; +} + json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) { (void) payload; @@ -141,5 +220,17 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); - return simple_response(result, session, true); + if (!result.empty()) + return simple_response("Error: " + result + "\n" + "Please report to an admin", session, false); + + std::vector reply_vec; + std::vector annotations; + + annotations.emplace_back( + create_annotation(Reply::AnnotationType::attachment, "latex.png;png;" + base64_encode_file(file))); + + reply_vec.emplace_back(create_text("", std::move(annotations))); + + return create_response(std::move(reply_vec), session, true); } -- cgit v1.2.3-54-g00ecf From 6c79252090c7be65c1a0f5a485de75e613af2160 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:48:09 +0200 Subject: debug statements --- src/SimpleHandlers.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 70b3a8c..323db44 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -214,12 +214,17 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const std::string file = exec("mktemp"); + std::cout << ("file " + file) << ": " << exec(("file " + file).c_str()) << std::endl; + std::cout << ("ls -lisa " + file) << ": " << exec(("ls -lisa " + file).c_str()) << std::endl; + std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' " "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' " "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' " "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); + std::cout << ("ls -lisa " + file) << ": " << exec(("ls -lisa " + file).c_str()) << std::endl; + if (!result.empty()) return simple_response("Error: " + result + "\n" "Please report to an admin", session, false); -- cgit v1.2.3-54-g00ecf From 52ddb20eed3036ebcc2e4b88fc6c0403af209317 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:53:14 +0200 Subject: more info --- src/SimpleHandlers.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 323db44..16b1a52 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -202,7 +202,10 @@ std::string base64_encode_file(std::string const &path) { temp.push_back(c); } infile.close(); - } else return "File could not be opened"; + } else { + std::cerr << "Error: " << strerror(errno) << std::endl; + return "File could not be opened"; + } std::string ret(temp.begin(), temp.end() - 1); ret = base64_encode((unsigned const char *) ret.c_str(), ret.size()); @@ -214,8 +217,7 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const std::string file = exec("mktemp"); - std::cout << ("file " + file) << ": " << exec(("file " + file).c_str()) << std::endl; - std::cout << ("ls -lisa " + file) << ": " << exec(("ls -lisa " + file).c_str()) << std::endl; + std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' " "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' " @@ -223,7 +225,7 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); - std::cout << ("ls -lisa " + file) << ": " << exec(("ls -lisa " + file).c_str()) << std::endl; + std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; if (!result.empty()) return simple_response("Error: " + result + "\n" -- cgit v1.2.3-54-g00ecf From a03485aeba7a055ba4ef8ffb7854d85bfb5dcfda Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:54:11 +0200 Subject: even more info --- src/SimpleHandlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 16b1a52..5e235e3 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -203,7 +203,7 @@ std::string base64_encode_file(std::string const &path) { } infile.close(); } else { - std::cerr << "Error: " << strerror(errno) << std::endl; + std::cerr << path << " Error: " << strerror(errno) << std::endl; return "File could not be opened"; } std::string ret(temp.begin(), temp.end() - 1); -- cgit v1.2.3-54-g00ecf From 7af4cfcbd1c794eaff5a1c1f7a11efb4d9025db1 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:56:06 +0200 Subject: fix --- src/SimpleHandlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 5e235e3..f7c1c6d 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -216,6 +216,7 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const (void) payload; std::string file = exec("mktemp"); + file.pop_back(); // remove trailing new line std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; -- cgit v1.2.3-54-g00ecf From f7a614b4486a35bdd2e02d3ea45a1a661521821a Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Fri, 18 Sep 2020 16:57:16 +0200 Subject: remove debug statements --- src/SimpleHandlers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index f7c1c6d..66d10d7 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -218,7 +218,7 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const std::string file = exec("mktemp"); file.pop_back(); // remove trailing new line - std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; + //std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' " "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' " @@ -226,7 +226,7 @@ json Handler::latexRenderHandler(std::string const &arguments, std::string const "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); - std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; + //std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; if (!result.empty()) return simple_response("Error: " + result + "\n" -- cgit v1.2.3-54-g00ecf From ee89b895d4f04baa1ea493fe916b3d499c4b4ec4 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Sun, 20 Sep 2020 14:48:43 +0200 Subject: convert to jpg, basic file cleanup --- src/SimpleHandlers.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 66d10d7..eba9331 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -215,30 +215,44 @@ std::string base64_encode_file(std::string const &path) { json Handler::latexRenderHandler(std::string const &arguments, std::string const &session, void *payload) { (void) payload; - std::string file = exec("mktemp"); - file.pop_back(); // remove trailing new line + std::string png_file = exec("mktemp"); + png_file.pop_back(); // remove trailing new line + std::string jpg_file = png_file + ".jpg"; - //std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; + //std::cout << ("png_file " + png_file) << exec(("png_file " + png_file).c_str()) << std::endl; std::string result = exec(("curl -s 'https://latex.codecogs.com/png.latex?" + url_encode(arguments) + "' " "-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0' " "-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' " "-H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' " - "-H 'Upgrade-Insecure-Requests: 1' --output " + file).c_str()); + "-H 'Upgrade-Insecure-Requests: 1' --output " + png_file).c_str()); - //std::cout << ("file " + file) << exec(("file " + file).c_str()) << std::endl; + //std::cout << ("png_file " + png_file) << exec(("png_file " + png_file).c_str()) << std::endl; if (!result.empty()) - return simple_response("Error: " + result + "\n" + return simple_response("Error getting image: " + result + "\n" + "Please report to an admin", session, false); + + // convert to jpg, mainly to loose background transparency ( :( ), so the images work in dark theme clients too + result = exec(("convert " + png_file + " " + jpg_file).c_str()); + + if (!result.empty()) + return simple_response("Error converting image: " + result + "\n" "Please report to an admin", session, false); std::vector reply_vec; std::vector annotations; annotations.emplace_back( - create_annotation(Reply::AnnotationType::attachment, "latex.png;png;" + base64_encode_file(file))); + create_annotation( + Reply::AnnotationType::attachment, + "latex.png;png;" + base64_encode_file(jpg_file))); reply_vec.emplace_back(create_text("", std::move(annotations))); + // single shot try to remove the files + std::remove(jpg_file.c_str()); + std::remove(png_file.c_str()); + return create_response(std::move(reply_vec), session, true); } -- cgit v1.2.3-54-g00ecf