diff options
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | CMakeLists.txt | 10 | ||||
| m--------- | vendor/mastodonpp | 0 | ||||
| -rw-r--r-- | yandere.cpp | 115 |
5 files changed, 77 insertions, 56 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf41023 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | chemist | ||
| 2 | cmake_install.cmake | ||
| 3 | CMakeCache.txt | ||
| 4 | CMakeFiles | ||
| 5 | Makefile | ||
| diff --git a/.gitmodules b/.gitmodules index 78fd03a..6d4576f 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -4,3 +4,6 @@ | |||
| 4 | [submodule "vendor/libtwittercpp"] | 4 | [submodule "vendor/libtwittercpp"] |
| 5 | path = vendor/libtwittercpp | 5 | path = vendor/libtwittercpp |
| 6 | url = https://github.com/hatkirby/libtwittercpp | 6 | url = https://github.com/hatkirby/libtwittercpp |
| 7 | [submodule "vendor/mastodonpp"] | ||
| 8 | path = vendor/mastodonpp | ||
| 9 | url = https://schlomp.space/tastytea/mastodonpp.git | ||
| diff --git a/CMakeLists.txt b/CMakeLists.txt index 94776f1..c77e9fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -1,13 +1,11 @@ | |||
| 1 | cmake_minimum_required (VERSION 3.1) | 1 | cmake_minimum_required (VERSION 3.1) |
| 2 | project (yandere) | 2 | project (yandere) |
| 3 | 3 | ||
| 4 | set(CMAKE_BUILD_TYPE Debug) | 4 | add_subdirectory(vendor/mastodonpp) |
| 5 | |||
| 6 | add_subdirectory(vendor/libtwittercpp) | ||
| 7 | add_subdirectory(vendor/yaml-cpp EXCLUDE_FROM_ALL) | 5 | add_subdirectory(vendor/yaml-cpp EXCLUDE_FROM_ALL) |
| 8 | 6 | ||
| 9 | include_directories(vendor/libtwittercpp/src vendor/yaml-cpp/include) | 7 | include_directories(vendor/mastodonpp/include vendor/yaml-cpp/include) |
| 10 | add_executable(yandere yandere.cpp) | 8 | add_executable(yandere yandere.cpp) |
| 11 | set_property(TARGET yandere PROPERTY CXX_STANDARD 11) | 9 | set_property(TARGET yandere PROPERTY CXX_STANDARD 17) |
| 12 | set_property(TARGET yandere PROPERTY CXX_STANDARD_REQUIRED ON) | 10 | set_property(TARGET yandere PROPERTY CXX_STANDARD_REQUIRED ON) |
| 13 | target_link_libraries(yandere yaml-cpp twitter++) | 11 | target_link_libraries(yandere yaml-cpp mastodonpp) |
| diff --git a/vendor/mastodonpp b/vendor/mastodonpp new file mode 160000 | |||
| Subproject c48f1dc3d0566cef2baf96df7b3a7c55490a3e9 | |||
| diff --git a/yandere.cpp b/yandere.cpp index 4edb550..31746e1 100644 --- a/yandere.cpp +++ b/yandere.cpp | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | #include <random> | 3 | #include <random> |
| 4 | #include <sstream> | 4 | #include <sstream> |
| 5 | #include <fstream> | 5 | #include <fstream> |
| 6 | #include <twitter.h> | 6 | #include <mastodonpp.hpp> |
| 7 | #include <chrono> | 7 | #include <chrono> |
| 8 | #include <thread> | 8 | #include <thread> |
| 9 | #include <algorithm> | 9 | #include <algorithm> |
| @@ -12,17 +12,17 @@ template <class InputIterator> | |||
| 12 | std::string implode(InputIterator first, InputIterator last, std::string delimiter) | 12 | std::string implode(InputIterator first, InputIterator last, std::string delimiter) |
| 13 | { | 13 | { |
| 14 | std::stringstream result; | 14 | std::stringstream result; |
| 15 | 15 | ||
| 16 | for (InputIterator it = first; it != last; it++) | 16 | for (InputIterator it = first; it != last; it++) |
| 17 | { | 17 | { |
| 18 | if (it != first) | 18 | if (it != first) |
| 19 | { | 19 | { |
| 20 | result << delimiter; | 20 | result << delimiter; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | result << *it; | 23 | result << *it; |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | return result.str(); | 26 | return result.str(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| @@ -30,52 +30,41 @@ template <class Container> | |||
| 30 | Container split(std::string input, std::string delimiter) | 30 | Container split(std::string input, std::string delimiter) |
| 31 | { | 31 | { |
| 32 | Container result; | 32 | Container result; |
| 33 | 33 | ||
| 34 | while (!input.empty()) | 34 | while (!input.empty()) |
| 35 | { | 35 | { |
| 36 | int divider = input.find(delimiter); | 36 | int divider = input.find(delimiter); |
| 37 | if (divider == std::string::npos) | 37 | if (divider == std::string::npos) |
| 38 | { | 38 | { |
| 39 | result.push_back(input); | 39 | result.push_back(input); |
| 40 | 40 | ||
| 41 | input = ""; | 41 | input = ""; |
| 42 | } else { | 42 | } else { |
| 43 | result.push_back(input.substr(0, divider)); | 43 | result.push_back(input.substr(0, divider)); |
| 44 | 44 | ||
| 45 | input = input.substr(divider+delimiter.length()); | 45 | input = input.substr(divider+delimiter.length()); |
| 46 | } | 46 | } |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | return result; | 49 | return result; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | int main(int argc, char** argv) | 52 | void run(const std::string& configfile) |
| 53 | { | 53 | { |
| 54 | if (argc != 2) | ||
| 55 | { | ||
| 56 | std::cout << "usage: yandere [configfile]" << std::endl; | ||
| 57 | return -1; | ||
| 58 | } | ||
| 59 | |||
| 60 | std::string configfile(argv[1]); | ||
| 61 | YAML::Node config = YAML::LoadFile(configfile); | 54 | YAML::Node config = YAML::LoadFile(configfile); |
| 62 | 55 | ||
| 63 | twitter::auth auth; | 56 | mastodonpp::Instance instance{ |
| 64 | auth.setConsumerKey(config["consumer_key"].as<std::string>()); | 57 | config["mastodon_instance"].as<std::string>(), |
| 65 | auth.setConsumerSecret(config["consumer_secret"].as<std::string>()); | 58 | config["mastodon_token"].as<std::string>()}; |
| 66 | auth.setAccessKey(config["access_key"].as<std::string>()); | 59 | mastodonpp::Connection connection{instance}; |
| 67 | auth.setAccessSecret(config["access_secret"].as<std::string>()); | 60 | |
| 68 | |||
| 69 | twitter::client client(auth); | ||
| 70 | |||
| 71 | std::map<std::string, std::vector<std::string>> groups; | 61 | std::map<std::string, std::vector<std::string>> groups; |
| 72 | std::ifstream datafile(config["forms"].as<std::string>()); | 62 | std::ifstream datafile(config["forms"].as<std::string>()); |
| 73 | if (!datafile.is_open()) | 63 | if (!datafile.is_open()) |
| 74 | { | 64 | { |
| 75 | std::cout << "Could not find forms file." << std::endl; | 65 | std::cout << "Could not find forms file." << std::endl; |
| 76 | return 1; | ||
| 77 | } | 66 | } |
| 78 | 67 | ||
| 79 | bool newgroup = true; | 68 | bool newgroup = true; |
| 80 | std::string line; | 69 | std::string line; |
| 81 | std::string curgroup; | 70 | std::string curgroup; |
| @@ -85,7 +74,7 @@ int main(int argc, char** argv) | |||
| 85 | { | 74 | { |
| 86 | line.pop_back(); | 75 | line.pop_back(); |
| 87 | } | 76 | } |
| 88 | 77 | ||
| 89 | if (newgroup) | 78 | if (newgroup) |
| 90 | { | 79 | { |
| 91 | curgroup = line; | 80 | curgroup = line; |
| @@ -112,10 +101,10 @@ int main(int argc, char** argv) | |||
| 112 | 101 | ||
| 113 | for (;;) | 102 | for (;;) |
| 114 | { | 103 | { |
| 115 | std::cout << "Generating tweet" << std::endl; | 104 | std::cout << "Generating post" << std::endl; |
| 116 | 105 | ||
| 117 | std::map<std::string, std::string> variables; | 106 | std::map<std::string, std::string> variables; |
| 118 | 107 | ||
| 119 | std::string action = "{MAIN}"; | 108 | std::string action = "{MAIN}"; |
| 120 | int tknloc; | 109 | int tknloc; |
| 121 | while ((tknloc = action.find("{")) != std::string::npos) | 110 | while ((tknloc = action.find("{")) != std::string::npos) |
| @@ -128,7 +117,7 @@ int main(int argc, char** argv) | |||
| 128 | modifier = token.substr(modloc+1); | 117 | modifier = token.substr(modloc+1); |
| 129 | token = token.substr(0, modloc); | 118 | token = token.substr(0, modloc); |
| 130 | } | 119 | } |
| 131 | 120 | ||
| 132 | int eqloc; | 121 | int eqloc; |
| 133 | std::string eqvarname; | 122 | std::string eqvarname; |
| 134 | if ((eqloc = token.find("=")) != std::string::npos) | 123 | if ((eqloc = token.find("=")) != std::string::npos) |
| @@ -136,12 +125,12 @@ int main(int argc, char** argv) | |||
| 136 | eqvarname = token.substr(0, eqloc); | 125 | eqvarname = token.substr(0, eqloc); |
| 137 | token = token.substr(eqloc+1); | 126 | token = token.substr(eqloc+1); |
| 138 | } | 127 | } |
| 139 | 128 | ||
| 140 | std::string canontkn; | 129 | std::string canontkn; |
| 141 | std::transform(std::begin(token), std::end(token), std::back_inserter(canontkn), [] (char ch) { | 130 | std::transform(std::begin(token), std::end(token), std::back_inserter(canontkn), [] (char ch) { |
| 142 | return std::toupper(ch); | 131 | return std::toupper(ch); |
| 143 | }); | 132 | }); |
| 144 | 133 | ||
| 145 | std::string result; | 134 | std::string result; |
| 146 | if (canontkn == "\\N") | 135 | if (canontkn == "\\N") |
| 147 | { | 136 | { |
| @@ -155,12 +144,12 @@ int main(int argc, char** argv) | |||
| 155 | 144 | ||
| 156 | result = group[dist(random_engine)]; | 145 | result = group[dist(random_engine)]; |
| 157 | } | 146 | } |
| 158 | 147 | ||
| 159 | if (!eqvarname.empty()) | 148 | if (!eqvarname.empty()) |
| 160 | { | 149 | { |
| 161 | variables[eqvarname] = result; | 150 | variables[eqvarname] = result; |
| 162 | } | 151 | } |
| 163 | 152 | ||
| 164 | if (modifier == "indefinite") | 153 | if (modifier == "indefinite") |
| 165 | { | 154 | { |
| 166 | if ((result.length() > 1) && (isupper(result[0])) && (isupper(result[1]))) | 155 | if ((result.length() > 1) && (isupper(result[0])) && (isupper(result[1]))) |
| @@ -173,7 +162,7 @@ int main(int argc, char** argv) | |||
| 173 | result = "a " + result; | 162 | result = "a " + result; |
| 174 | } | 163 | } |
| 175 | } | 164 | } |
| 176 | 165 | ||
| 177 | std::string finalresult; | 166 | std::string finalresult; |
| 178 | if (islower(token[0])) | 167 | if (islower(token[0])) |
| 179 | { | 168 | { |
| @@ -187,30 +176,56 @@ int main(int argc, char** argv) | |||
| 187 | { | 176 | { |
| 188 | word[0] = std::toupper(word[0]); | 177 | word[0] = std::toupper(word[0]); |
| 189 | } | 178 | } |
| 190 | 179 | ||
| 191 | finalresult = implode(std::begin(words), std::end(words), " "); | 180 | finalresult = implode(std::begin(words), std::end(words), " "); |
| 192 | } else { | 181 | } else { |
| 193 | finalresult = result; | 182 | finalresult = result; |
| 194 | } | 183 | } |
| 195 | 184 | ||
| 196 | action.replace(tknloc, action.find("}")-tknloc+1, finalresult); | 185 | action.replace(tknloc, action.find("}")-tknloc+1, finalresult); |
| 197 | } | 186 | } |
| 198 | 187 | ||
| 199 | action.resize(140); | 188 | const mastodonpp::parametermap parameters{{"status", action}}; |
| 200 | 189 | auto answer{connection.post(mastodonpp::API::v1::statuses, parameters)}; | |
| 201 | try | 190 | if (!answer) |
| 202 | { | ||
| 203 | client.updateStatus(action); | ||
| 204 | } catch (const twitter::twitter_error& e) | ||
| 205 | { | 191 | { |
| 206 | std::cout << "Twitter error: " << e.what() << std::endl; | 192 | if (answer.curl_error_code == 0) |
| 193 | { | ||
| 194 | std::cout << "HTTP status: " << answer.http_status << std::endl; | ||
| 195 | } | ||
| 196 | else | ||
| 197 | { | ||
| 198 | std::cout << "libcurl error " << std::to_string(answer.curl_error_code) | ||
| 199 | << ": " << answer.error_message << std::endl; | ||
| 200 | } | ||
| 207 | } | 201 | } |
| 208 | 202 | ||
| 209 | std::cout << action << std::endl; | 203 | std::cout << action << std::endl; |
| 210 | std::cout << "Waiting" << std::endl; | 204 | std::cout << "Waiting" << std::endl; |
| 211 | 205 | ||
| 212 | std::this_thread::sleep_for(std::chrono::hours(1)); | 206 | std::this_thread::sleep_for(std::chrono::hours(1)); |
| 213 | 207 | ||
| 214 | std::cout << std::endl; | 208 | std::cout << std::endl; |
| 215 | } | 209 | } |
| 216 | } | 210 | } |
| 211 | |||
| 212 | int main(int argc, char** argv) | ||
| 213 | { | ||
| 214 | if (argc != 2) | ||
| 215 | { | ||
| 216 | std::cout << "usage: yandere [configfile]" << std::endl; | ||
| 217 | return -1; | ||
| 218 | } | ||
| 219 | |||
| 220 | std::string configfile(argv[1]); | ||
| 221 | |||
| 222 | try | ||
| 223 | { | ||
| 224 | run(configfile); | ||
| 225 | } catch (const mastodonpp::CURLException& e) | ||
| 226 | { | ||
| 227 | std::cout << e.what() << std::endl; | ||
| 228 | } | ||
| 229 | |||
| 230 | return 0; | ||
| 231 | } | ||
