diff options
-rw-r--r-- | .gitmodules | 6 | ||||
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | furries.cpp | 72 | ||||
m--------- | vendor/libtwittercpp | 0 | ||||
m--------- | vendor/twitcurl | 0 | ||||
m--------- | vendor/verbly | 0 |
6 files changed, 45 insertions, 42 deletions
diff --git a/.gitmodules b/.gitmodules index ad942bc..79aa7f0 100644 --- a/.gitmodules +++ b/.gitmodules | |||
@@ -1,9 +1,9 @@ | |||
1 | [submodule "vendor/twitcurl"] | ||
2 | path = vendor/twitcurl | ||
3 | url = https://github.com/swatkat/twitcurl | ||
4 | [submodule "vendor/verbly"] | 1 | [submodule "vendor/verbly"] |
5 | path = vendor/verbly | 2 | path = vendor/verbly |
6 | url = https://github.com/hatkirby/verbly | 3 | url = https://github.com/hatkirby/verbly |
7 | [submodule "vendor/yaml-cpp"] | 4 | [submodule "vendor/yaml-cpp"] |
8 | path = vendor/yaml-cpp | 5 | path = vendor/yaml-cpp |
9 | url = https://github.com/jbeder/yaml-cpp | 6 | url = https://github.com/jbeder/yaml-cpp |
7 | [submodule "vendor/libtwittercpp"] | ||
8 | path = vendor/libtwittercpp | ||
9 | url = https://github.com/hatkirby/libtwittercpp | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index 266c9d0..e6a8aa7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -1,15 +1,12 @@ | |||
1 | cmake_minimum_required (VERSION 3.1) | 1 | cmake_minimum_required (VERSION 3.1) |
2 | project (furries) | 2 | project (furries) |
3 | 3 | ||
4 | find_package(PkgConfig) | 4 | add_subdirectory(vendor/libtwittercpp) |
5 | pkg_check_modules(sqlite3 sqlite3 REQUIRED) | ||
6 | |||
7 | add_subdirectory(vendor/twitcurl/libtwitcurl) | ||
8 | add_subdirectory(vendor/verbly) | 5 | add_subdirectory(vendor/verbly) |
9 | add_subdirectory(vendor/yaml-cpp EXCLUDE_FROM_ALL) | 6 | add_subdirectory(vendor/yaml-cpp EXCLUDE_FROM_ALL) |
10 | 7 | ||
11 | include_directories(vendor/twitcurl/libtwitcurl ${sqlite3_INCLUDE_DIR} vendor/verbly/lib vendor/yaml-cpp/include) | 8 | include_directories(vendor/libtwittercpp/src vendor/verbly/lib vendor/yaml-cpp/include) |
12 | add_executable(furries furries.cpp) | 9 | add_executable(furries furries.cpp) |
13 | set_property(TARGET furries PROPERTY CXX_STANDARD 11) | 10 | set_property(TARGET furries PROPERTY CXX_STANDARD 11) |
14 | set_property(TARGET furries PROPERTY CXX_STANDARD_REQUIRED ON) | 11 | set_property(TARGET furries PROPERTY CXX_STANDARD_REQUIRED ON) |
15 | target_link_libraries(furries verbly ${sqlite3_LIBRARIES} yaml-cpp twitcurl curl) | 12 | target_link_libraries(furries verbly twitter++ yaml-cpp) |
diff --git a/furries.cpp b/furries.cpp index 1d10ccf..7e2f591 100644 --- a/furries.cpp +++ b/furries.cpp | |||
@@ -1,11 +1,11 @@ | |||
1 | #include <yaml-cpp/yaml.h> | 1 | #include <yaml-cpp/yaml.h> |
2 | #include <twitter.h> | ||
3 | #include <verbly.h> | ||
2 | #include <iostream> | 4 | #include <iostream> |
3 | #include <cstdlib> | ||
4 | #include <ctime> | ||
5 | #include <sstream> | 5 | #include <sstream> |
6 | #include <twitcurl.h> | 6 | #include <chrono> |
7 | #include <verbly.h> | 7 | #include <thread> |
8 | #include <unistd.h> | 8 | #include <random> |
9 | 9 | ||
10 | class fill_blanks { | 10 | class fill_blanks { |
11 | private: | 11 | private: |
@@ -150,7 +150,8 @@ class fill_blanks { | |||
150 | } | 150 | } |
151 | } | 151 | } |
152 | 152 | ||
153 | void visit(verbly::token& it) | 153 | template <typename RNG> |
154 | void visit(verbly::token& it, RNG&& rng) | ||
154 | { | 155 | { |
155 | switch (it.get_type()) | 156 | switch (it.get_type()) |
156 | { | 157 | { |
@@ -160,7 +161,7 @@ class fill_blanks { | |||
160 | { | 161 | { |
161 | if (!tkn.is_complete()) | 162 | if (!tkn.is_complete()) |
162 | { | 163 | { |
163 | visit(tkn); | 164 | visit(tkn, rng); |
164 | 165 | ||
165 | break; | 166 | break; |
166 | } | 167 | } |
@@ -209,7 +210,8 @@ class fill_blanks { | |||
209 | continue; | 210 | continue; |
210 | } | 211 | } |
211 | 212 | ||
212 | verbly::frame fr = filtered[rand() % filtered.size()]; | 213 | int fr_i = std::uniform_int_distribution<int>(0, filtered.size()-1)(rng); |
214 | verbly::frame fr = filtered[fr_i]; | ||
213 | verbly::token utter; | 215 | verbly::token utter; |
214 | for (auto part : fr.parts()) | 216 | for (auto part : fr.parts()) |
215 | { | 217 | { |
@@ -251,7 +253,7 @@ class fill_blanks { | |||
251 | continue; | 253 | continue; |
252 | } else if (part.get_synrestrs().count("adv_loc") == 1) | 254 | } else if (part.get_synrestrs().count("adv_loc") == 1) |
253 | { | 255 | { |
254 | if (rand() % 2 == 0) | 256 | if (std::bernoulli_distribution(1.0/2.0)(rng)) |
255 | { | 257 | { |
256 | utter << verbly::token{"here"}; | 258 | utter << verbly::token{"here"}; |
257 | } else { | 259 | } else { |
@@ -286,7 +288,7 @@ class fill_blanks { | |||
286 | auto selrestrs = fr.roles()[part.get_role()]; | 288 | auto selrestrs = fr.roles()[part.get_role()]; |
287 | auto query = database.nouns().limit(1).random().is_not_proper().full_hyponym_of(parse_selrestrs(selrestrs)); | 289 | auto query = database.nouns().limit(1).random().is_not_proper().full_hyponym_of(parse_selrestrs(selrestrs)); |
288 | verbly::noun n = query.run().front(); | 290 | verbly::noun n = query.run().front(); |
289 | if ((rand() % 2 == 0) && (part.get_synrestrs().count("definite") == 0)) | 291 | if ((std::bernoulli_distribution(1.0/2.0)(rng)) && (part.get_synrestrs().count("definite") == 0)) |
290 | { | 292 | { |
291 | utter << verbly::token{"the"}; | 293 | utter << verbly::token{"the"}; |
292 | } else { | 294 | } else { |
@@ -322,7 +324,8 @@ class fill_blanks { | |||
322 | 324 | ||
323 | case verbly::frame::part::type::literal_preposition: | 325 | case verbly::frame::part::type::literal_preposition: |
324 | { | 326 | { |
325 | utter << verbly::token{part.get_choices()[rand() % part.get_choices().size()]}; | 327 | int ch_i = std::uniform_int_distribution<int>(0, part.get_choices().size()-1)(rng); |
328 | utter << verbly::token{part.get_choices()[ch_i]}; | ||
326 | 329 | ||
327 | break; | 330 | break; |
328 | } | 331 | } |
@@ -374,12 +377,12 @@ class fill_blanks { | |||
374 | { | 377 | { |
375 | verbly::token phrase; | 378 | verbly::token phrase; |
376 | 379 | ||
377 | if (rand() % 4 == 0) | 380 | if (std::bernoulli_distribution(1.0/4.0)(rng)) |
378 | { | 381 | { |
379 | phrase << verbly::token{verbly::token::fillin_type::adverb_phrase}; | 382 | phrase << verbly::token{verbly::token::fillin_type::adverb_phrase}; |
380 | } | 383 | } |
381 | 384 | ||
382 | if (rand() % 2 == 0) | 385 | if (std::bernoulli_distribution(1.0/2.0)(rng)) |
383 | { | 386 | { |
384 | phrase << verbly::token{verbly::token::fillin_type::participle_phrase}; | 387 | phrase << verbly::token{verbly::token::fillin_type::participle_phrase}; |
385 | } else { | 388 | } else { |
@@ -429,21 +432,23 @@ class fill_blanks { | |||
429 | 432 | ||
430 | int main(int argc, char** argv) | 433 | int main(int argc, char** argv) |
431 | { | 434 | { |
432 | srand(time(NULL)); | 435 | std::random_device random_device; |
436 | std::mt19937 random_engine{random_device()}; | ||
433 | 437 | ||
434 | YAML::Node config = YAML::LoadFile("config.yml"); | 438 | YAML::Node config = YAML::LoadFile("config.yml"); |
435 | 439 | ||
436 | twitCurl twitter; | 440 | twitter::auth auth; |
437 | twitter.getOAuth().setConsumerKey(config["consumer_key"].as<std::string>()); | 441 | auth.setConsumerKey(config["consumer_key"].as<std::string>()); |
438 | twitter.getOAuth().setConsumerSecret(config["consumer_secret"].as<std::string>()); | 442 | auth.setConsumerSecret(config["consumer_secret"].as<std::string>()); |
439 | twitter.getOAuth().setOAuthTokenKey(config["access_key"].as<std::string>()); | 443 | auth.setAccessKey(config["access_key"].as<std::string>()); |
440 | twitter.getOAuth().setOAuthTokenSecret(config["access_secret"].as<std::string>()); | 444 | auth.setAccessSecret(config["access_secret"].as<std::string>()); |
445 | |||
446 | twitter::client client(auth); | ||
447 | verbly::data database {"data.sqlite3"}; | ||
441 | 448 | ||
442 | for (;;) | 449 | for (;;) |
443 | { | 450 | { |
444 | std::cout << "Generating tweet" << std::endl; | 451 | std::cout << "Generating tweet..." << std::endl; |
445 | |||
446 | verbly::data database {"data.sqlite3"}; | ||
447 | 452 | ||
448 | fill_blanks yeah {database}; | 453 | fill_blanks yeah {database}; |
449 | verbly::token action{ | 454 | verbly::token action{ |
@@ -452,23 +457,24 @@ int main(int argc, char** argv) | |||
452 | }; | 457 | }; |
453 | while (!action.is_complete()) | 458 | while (!action.is_complete()) |
454 | { | 459 | { |
455 | yeah.visit(action); | 460 | yeah.visit(action, random_engine); |
456 | } | 461 | } |
457 | 462 | ||
458 | std::string result = action.compile(); | 463 | std::string result = action.compile(); |
459 | result.resize(140); | 464 | result.resize(140); |
460 | 465 | ||
461 | std::string replyMsg; | 466 | try |
462 | if (twitter.statusUpdate(result)) | 467 | { |
468 | client.updateStatus(result); | ||
469 | |||
470 | std::cout << "Tweeted!" << std::endl; | ||
471 | } catch (const twitter::twitter_error& e) | ||
463 | { | 472 | { |
464 | twitter.getLastWebResponse(replyMsg); | 473 | std::cout << "Twitter error: " << e.what() << std::endl; |
465 | std::cout << "Twitter message: " << replyMsg << std::endl; | ||
466 | } else { | ||
467 | twitter.getLastCurlError(replyMsg); | ||
468 | std::cout << "Curl error: " << replyMsg << std::endl; | ||
469 | } | 474 | } |
470 | 475 | ||
471 | std::cout << "Waiting" << std::endl; | 476 | std::cout << "Waiting..." << std::endl; |
472 | sleep(60 * 60 * 2); | 477 | |
478 | std::this_thread::sleep_for(std::chrono::hours(1)); | ||
473 | } | 479 | } |
474 | } | 480 | } |
diff --git a/vendor/libtwittercpp b/vendor/libtwittercpp new file mode 160000 | |||
Subproject d90a1e74c77ba67f25a812609fd49d479bc464d | |||
diff --git a/vendor/twitcurl b/vendor/twitcurl deleted file mode 160000 | |||
Subproject 6659e86de7481e50977b7569c75138f7f69ad3c | |||
diff --git a/vendor/verbly b/vendor/verbly | |||
Subproject 965a3206df834f846f2c560438c80a707dcee4c | Subproject 1f898f3bd66c29672275c2c884b17ba662ced62 | ||