diff options
Diffstat (limited to 'ebooks.cpp')
| -rw-r--r-- | ebooks.cpp | 79 |
1 files changed, 37 insertions, 42 deletions
| diff --git a/ebooks.cpp b/ebooks.cpp index 3918b78..08be38e 100644 --- a/ebooks.cpp +++ b/ebooks.cpp | |||
| @@ -4,12 +4,13 @@ | |||
| 4 | #include "kgramstats.h" | 4 | #include "kgramstats.h" |
| 5 | #include <fstream> | 5 | #include <fstream> |
| 6 | #include <iostream> | 6 | #include <iostream> |
| 7 | #include <twitter.h> | 7 | #include <mastodonpp/mastodonpp.hpp> |
| 8 | #include <yaml-cpp/yaml.h> | 8 | #include <yaml-cpp/yaml.h> |
| 9 | #include <thread> | 9 | #include <thread> |
| 10 | #include <chrono> | 10 | #include <chrono> |
| 11 | #include <algorithm> | 11 | #include <algorithm> |
| 12 | #include <random> | 12 | #include <random> |
| 13 | #include "timeline.h" | ||
| 13 | 14 | ||
| 14 | const auto QUEUE_TIMEOUT = std::chrono::minutes(1); | 15 | const auto QUEUE_TIMEOUT = std::chrono::minutes(1); |
| 15 | const auto POLL_TIMEOUT = std::chrono::minutes(5); | 16 | const auto POLL_TIMEOUT = std::chrono::minutes(5); |
| @@ -22,13 +23,13 @@ int main(int argc, char** args) | |||
| 22 | YAML::Node config = YAML::LoadFile("config.yml"); | 23 | YAML::Node config = YAML::LoadFile("config.yml"); |
| 23 | int delay = config["delay"].as<int>(); | 24 | int delay = config["delay"].as<int>(); |
| 24 | 25 | ||
| 25 | twitter::auth auth( | 26 | mastodonpp::Instance instance{ |
| 26 | config["consumer_key"].as<std::string>(), | 27 | config["mastodon_instance"].as<std::string>(), |
| 27 | config["consumer_secret"].as<std::string>(), | 28 | config["mastodon_token"].as<std::string>()}; |
| 28 | config["access_key"].as<std::string>(), | 29 | mastodonpp::Connection connection{instance}; |
| 29 | config["access_secret"].as<std::string>()); | ||
| 30 | 30 | ||
| 31 | twitter::client client(auth); | 31 | timeline mentions(mastodonpp::API::v1::notifications); |
| 32 | mentions.poll(connection); // just ignore the results | ||
| 32 | 33 | ||
| 33 | std::ifstream infile(config["corpus"].as<std::string>().c_str()); | 34 | std::ifstream infile(config["corpus"].as<std::string>().c_str()); |
| 34 | std::string corpus; | 35 | std::string corpus; |
| @@ -78,7 +79,7 @@ int main(int argc, char** args) | |||
| 78 | return form; | 79 | return form; |
| 79 | }); | 80 | }); |
| 80 | 81 | ||
| 81 | std::list<std::tuple<std::string, bool, twitter::tweet_id>> postQueue; | 82 | std::list<std::tuple<std::string, bool, std::string>> postQueue; |
| 82 | 83 | ||
| 83 | auto startedTime = std::chrono::system_clock::now(); | 84 | auto startedTime = std::chrono::system_clock::now(); |
| 84 | 85 | ||
| @@ -93,13 +94,11 @@ int main(int argc, char** args) | |||
| 93 | if (currentTime >= genTimer) | 94 | if (currentTime >= genTimer) |
| 94 | { | 95 | { |
| 95 | std::string doc = kgramstats.randomSentence(140, rng); | 96 | std::string doc = kgramstats.randomSentence(140, rng); |
| 96 | doc.resize(140); | 97 | doc.resize(500); |
| 97 | 98 | ||
| 98 | postQueue.emplace_back(std::move(doc), false, 0); | 99 | postQueue.emplace_back(std::move(doc), false, ""); |
| 99 | 100 | ||
| 100 | int genwait = std::uniform_int_distribution<int>(1, delay)(rng); | 101 | genTimer = currentTime + std::chrono::seconds(delay); |
| 101 | |||
| 102 | genTimer = currentTime + std::chrono::seconds(genwait); | ||
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | if (currentTime >= pollTimer) | 104 | if (currentTime >= pollTimer) |
| @@ -108,36 +107,27 @@ int main(int argc, char** args) | |||
| 108 | 107 | ||
| 109 | try | 108 | try |
| 110 | { | 109 | { |
| 111 | std::list<twitter::tweet> newTweets = | 110 | std::list<nlohmann::json> newNotifs = mentions.poll(connection); |
| 112 | client.getMentionsTimeline().poll(); | ||
| 113 | 111 | ||
| 114 | for (const twitter::tweet& tweet : newTweets) | 112 | for (const nlohmann::json& notif : newNotifs) |
| 115 | { | 113 | { |
| 116 | auto createdTime = | ||
| 117 | std::chrono::system_clock::from_time_t(tweet.getCreatedAt()); | ||
| 118 | |||
| 119 | if ( | 114 | if ( |
| 120 | // Ignore tweets from before the bot started up | 115 | notif["type"].get<std::string>() == "mention" |
| 121 | createdTime > startedTime | ||
| 122 | // Ignore retweets | 116 | // Ignore retweets |
| 123 | && !tweet.isRetweet() | 117 | && notif["status"]["reblog"].is_null()) |
| 124 | // Ignore tweets from yourself | ||
| 125 | && tweet.getAuthor() != client.getUser()) | ||
| 126 | { | 118 | { |
| 127 | std::string doc = tweet.generateReplyPrefill(client.getUser()); | 119 | std::string doc = "@" + notif["status"]["account"]["acct"].get<std::string>() + " "; |
| 128 | doc += kgramstats.randomSentence(140 - doc.length(), rng); | 120 | doc += kgramstats.randomSentence(500 - doc.length(), rng); |
| 129 | doc.resize(140); | 121 | doc.resize(500); |
| 130 | 122 | ||
| 131 | postQueue.emplace_back(std::move(doc), true, tweet.getID()); | 123 | postQueue.emplace_back(std::move(doc), true, notif["status"]["id"]); |
| 132 | } | 124 | } |
| 133 | } | 125 | } |
| 134 | } catch (const twitter::rate_limit_exceeded&) | 126 | } catch (const std::exception& e) |
| 135 | { | 127 | { |
| 128 | std::cout << "Twitter error while polling: " << e.what() << std::endl; | ||
| 136 | // Wait out the rate limit (10 minutes here and 5 below = 15). | 129 | // Wait out the rate limit (10 minutes here and 5 below = 15). |
| 137 | pollTimer += std::chrono::minutes(10); | 130 | pollTimer += std::chrono::minutes(10); |
| 138 | } catch (const twitter::twitter_error& e) | ||
| 139 | { | ||
| 140 | std::cout << "Twitter error while polling: " << e.what() << std::endl; | ||
| 141 | } | 131 | } |
| 142 | 132 | ||
| 143 | pollTimer += std::chrono::minutes(POLL_TIMEOUT); | 133 | pollTimer += std::chrono::minutes(POLL_TIMEOUT); |
| @@ -145,21 +135,26 @@ int main(int argc, char** args) | |||
| 145 | 135 | ||
| 146 | if ((currentTime >= queueTimer) && (!postQueue.empty())) | 136 | if ((currentTime >= queueTimer) && (!postQueue.empty())) |
| 147 | { | 137 | { |
| 148 | auto post = postQueue.front(); | 138 | auto [result, isReply, replyTo] = postQueue.front(); |
| 149 | postQueue.pop_front(); | 139 | postQueue.pop_front(); |
| 150 | 140 | ||
| 151 | try | 141 | mastodonpp::parametermap parameters{{"status", result}}; |
| 142 | if (isReply) { | ||
| 143 | parameters["in_reply_to_id"] = replyTo; | ||
| 144 | } | ||
| 145 | |||
| 146 | auto answer{connection.post(mastodonpp::API::v1::statuses, parameters)}; | ||
| 147 | if (!answer) | ||
| 152 | { | 148 | { |
| 153 | if (std::get<1>(post)) | 149 | if (answer.curl_error_code == 0) |
| 154 | { | 150 | { |
| 155 | client.replyToTweet(std::get<0>(post), std::get<2>(post)); | 151 | std::cout << "HTTP status: " << answer.http_status << std::endl; |
| 156 | } else { | 152 | } |
| 157 | client.updateStatus(std::get<0>(post)); | 153 | else |
| 154 | { | ||
| 155 | std::cout << "libcurl error " << std::to_string(answer.curl_error_code) | ||
| 156 | << ": " << answer.error_message << std::endl; | ||
| 158 | } | 157 | } |
| 159 | } catch (const twitter::twitter_error& error) | ||
| 160 | { | ||
| 161 | std::cout << "Twitter error while tweeting: " << error.what() | ||
| 162 | << std::endl; | ||
| 163 | } | 158 | } |
| 164 | 159 | ||
| 165 | queueTimer = currentTime + std::chrono::minutes(QUEUE_TIMEOUT); | 160 | queueTimer = currentTime + std::chrono::minutes(QUEUE_TIMEOUT); |
