From bdd0f853177dce9e67c3268bec0b77094ef30fa6 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 9 Mar 2016 09:37:28 -0500 Subject: Initial commit --- .gitignore | 1 + .gitmodules | 3 ++ CMakeLists.txt | 18 ++++++++ forms.txt | 16 +++++++ nancy.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vendor/twitcurl | 1 + 6 files changed, 180 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 forms.txt create mode 100644 nancy.cpp create mode 160000 vendor/twitcurl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d3ed4c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.yml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..037e2c6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/twitcurl"] + path = vendor/twitcurl + url = https://github.com/swatkat/twitcurl diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..307a777 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required (VERSION 2.6) +project (nancy) + +set(CMAKE_BUILD_TYPE Debug) + +add_subdirectory(vendor/twitcurl/libtwitcurl) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + +find_package(PkgConfig) +pkg_check_modules(YamlCpp yaml-cpp REQUIRED) +find_package(Mysql REQUIRED) + +include_directories(vendor/twitcurl/libtwitcurl ${MYSQL_INCLUDE_DIR}) +add_executable(nancy nancy.cpp) +set_property(TARGET nancy PROPERTY CXX_STANDARD 11) +set_property(TARGET nancy PROPERTY CXX_STANDARD_REQUIRED ON) +target_link_libraries(nancy ${YamlCpp_LIBRARIES} ${MYSQL_LIBRARIES} twitcurl curl) diff --git a/forms.txt b/forms.txt new file mode 100644 index 0000000..307935d --- /dev/null +++ b/forms.txt @@ -0,0 +1,16 @@ +Nancy Drew and the Hidden {noun} +Nancy Drew and the Secret of the {noun} +Nancy Drew and the Secret of the {adj} {noun} +Nancy Drew and the Mystery of the {noun} +Nancy Drew and the Mystery of the {adj} {noun} +Nancy Drew on {adj} Island +Nancy Drew and the {adj} {noun} +Nancy Drew and the Missing {noun} +Nancy Drew and the {adj} Holiday +Nancy Drew and the Quest of the {adj} {noun} +Nancy Drew and the Quest of the {noun} +Nancy Drew and the Clue in the {adj} {noun} +Nancy Drew and the Clue in the {noun} +Nancy Drew and the {noun}'s Secret +Nancy Drew and the Phantom of {adj} {noun} +Nancy Drew and the Strange {noun} \ No newline at end of file diff --git a/nancy.cpp b/nancy.cpp new file mode 100644 index 0000000..3e40be1 --- /dev/null +++ b/nancy.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include + +int db_error(MYSQL* driver, const char* error) +{ + std::cout << error << ": " << mysql_error(driver) << std::endl; + return 1; +} + +int main(int argc, char** argv) +{ + srand(time(NULL)); + + YAML::Node config = YAML::LoadFile("config.yml"); + const char* host = config["host"].as().c_str(); + const char* user = config["user"].as().c_str(); + const char* pass = config["pass"].as().c_str(); + const char* db = config["db"].as().c_str(); + + // Forms + std::vector forms; + std::ifstream formfile("forms.txt"); + if (formfile.is_open()) + { + while (!formfile.eof()) + { + std::string l; + getline(formfile, l); + if (l.back() == '\r') + { + l.pop_back(); + } + + forms.push_back(l); + } + + formfile.close(); + } + + if (forms.size() == 0) + { + std::cout << "No forms found... check forms.txt." << std::endl; + + return 2; + } + + // WordNet data + MYSQL* driver = mysql_init(NULL); + if (!mysql_real_connect(driver, host, user, pass, db, 0, NULL, 0)) + { + return db_error(driver, "Error connecting to database"); + } + + twitCurl twitter; + twitter.getOAuth().setConsumerKey(config["consumer_key"].as()); + twitter.getOAuth().setConsumerSecret(config["consumer_secret"].as()); + twitter.getOAuth().setOAuthTokenKey(config["access_key"].as()); + twitter.getOAuth().setOAuthTokenSecret(config["access_secret"].as()); + + for (;;) + { + std::cout << "Generating tweet" << std::endl; + + std::string form = forms[rand() % forms.size()]; + + // Adjectives + int i; + while ((i = form.find("{adj}")) != std::string::npos) + { + const char* getword = "SELECT word FROM wn_synset WHERE ss_type = 'a' OR ss_type = 's' ORDER BY RAND() LIMIT 1"; + if (mysql_query(driver, getword)) return db_error(driver, "Query failed"); + MYSQL_RES* getword2 = mysql_use_result(driver); if (getword2 == NULL) return db_error(driver, "Query failed"); + MYSQL_ROW getword3 = mysql_fetch_row(getword2); if (getword3 == NULL) return db_error(driver, "Query failed"); + std::string adj {getword3[0]}; + mysql_free_result(getword2); + + adj[0] = toupper(adj[0]); + + int j; + while ((j = adj.find("_")) != std::string::npos) + { + adj[j] = ' '; + adj[j+1] = toupper(adj[j+1]); + } + + if (adj[adj.size()-1] == ')') + { + adj.resize(adj.size()-3); + } + + form.replace(i, 5, adj); + } + + // Nouns + while ((i = form.find("{noun}")) != std::string::npos) + { + const char* getword = "SELECT word FROM wn_synset WHERE ss_type = 'n' ORDER BY RAND() LIMIT 1"; + if (mysql_query(driver, getword)) return db_error(driver, "Query failed"); + MYSQL_RES* getword2 = mysql_use_result(driver); if (getword2 == NULL) return db_error(driver, "Query failed"); + MYSQL_ROW getword3 = mysql_fetch_row(getword2); if (getword3 == NULL) return db_error(driver, "Query failed"); + std::string noun {getword3[0]}; + mysql_free_result(getword2); + + noun[0] = toupper(noun[0]); + + int j; + while ((j = noun.find("_")) != std::string::npos) + { + noun[j] = ' '; + noun[j+1] = toupper(noun[j+1]); + } + + form.replace(i, 6, noun); + } + + if (form.size() > 140) + { + continue; + } + + std::string replyMsg; + if (twitter.statusUpdate(form)) + { + twitter.getLastWebResponse(replyMsg); + std::cout << "Twitter message: " << replyMsg << std::endl; + } else { + twitter.getLastCurlError(replyMsg); + std::cout << "Curl error: " << replyMsg << std::endl; + } + + std::cout << "Waiting" << std::endl; + sleep(60 * 60 * 3); + } + + mysql_close(driver); +} diff --git a/vendor/twitcurl b/vendor/twitcurl new file mode 160000 index 0000000..6659e86 --- /dev/null +++ b/vendor/twitcurl @@ -0,0 +1 @@ +Subproject commit 6659e86de7481e50977b7569c75138f7f69ad3c7 -- cgit 1.4.1