From ce7f42f1f3a45b9167a9cc4e85e1bc4488013c70 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 26 Mar 2016 09:42:45 -0400 Subject: Initial commit --- .gitmodules | 6 ++ CMakeLists.txt | 17 +++++ chemist.cpp | 156 ++++++++++++++++++++++++++++++++++++++ data.txt | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vendor/twitcurl | 1 + vendor/verbly | 1 + 6 files changed, 407 insertions(+) create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 chemist.cpp create mode 100644 data.txt create mode 160000 vendor/twitcurl create mode 160000 vendor/verbly diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..16192d6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "vendor/verbly"] + path = vendor/verbly + url = https://github.com/hatkirby/verbly +[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..9508ca5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required (VERSION 2.6) +project (chemist) + +set(CMAKE_BUILD_TYPE Debug) + +add_subdirectory(vendor/twitcurl/libtwitcurl) +add_subdirectory(vendor/verbly) + +find_package(PkgConfig) +pkg_check_modules(YamlCpp yaml-cpp REQUIRED) +pkg_check_modules(sqlite3 sqlite3 REQUIRED) + +include_directories(vendor/twitcurl/libtwitcurl ${sqlite3_INCLUDE_DIR} vendor/verbly/lib) +add_executable(chemist chemist.cpp) +set_property(TARGET chemist PROPERTY CXX_STANDARD 11) +set_property(TARGET chemist PROPERTY CXX_STANDARD_REQUIRED ON) +target_link_libraries(chemist verbly ${sqlite3_LIBRARIES} ${YamlCpp_LIBRARIES} twitcurl curl) diff --git a/chemist.cpp b/chemist.cpp new file mode 100644 index 0000000..a111931 --- /dev/null +++ b/chemist.cpp @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + srand(time(NULL)); + + YAML::Node config = YAML::LoadFile("config.yml"); + + 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()); + + std::map> groups; + std::ifstream datafile("data.txt"); + if (!datafile.is_open()) + { + std::cout << "Could not find data.txt" << std::endl; + return 1; + } + + bool newgroup = true; + std::string line; + std::string curgroup; + while (getline(datafile, line)) + { + if (line.back() == '\r') + { + line.pop_back(); + } + + if (newgroup) + { + curgroup = line; + newgroup = false; + } else { + if (line.empty()) + { + newgroup = true; + } else { + groups[curgroup].push_back(line); + } + } + } + + verbly::data database {"data.sqlite3"}; + for (;;) + { + std::cout << "Generating tweet" << std::endl; + std::string action = "{Main}"; + int tknloc; + while ((tknloc = action.find("{")) != std::string::npos) + { + std::string token = action.substr(tknloc+1, action.find("}")-tknloc-1); + std::string modifier; + int modloc; + if ((modloc = token.find(":")) != std::string::npos) + { + modifier = token.substr(modloc+1); + token = token.substr(0, modloc); + } + + std::string canontkn; + std::transform(std::begin(token), std::end(token), std::back_inserter(canontkn), [] (char ch) { + return std::toupper(ch); + }); + + std::string result; + if (canontkn == "NOUN") + { + result = database.nouns().is_not_proper().random().limit(1).run().front().singular_form(); + } else if (canontkn == "ADJECTIVE") + { + result = database.adjectives().random().limit(1).run().front().base_form(); + } else if (canontkn == "VERBING") + { + result = database.verbs().random().limit(1).run().front().ing_form(); + } else if (canontkn == "YEAR") + { + result = std::to_string(rand() % 100 + 1916); + } else if (canontkn == "REGION") + { + auto hem1 = database.nouns().with_singular_form("eastern hemisphere").limit(1).run().front(); + auto hem2 = database.nouns().with_singular_form("western hemisphere").limit(1).run().front(); + verbly::filter region{hem1, hem2}; + region.set_orlogic(true); + + result = database.nouns().full_part_holonym_of(region).random().limit(1).run().front().singular_form(); + } else if (canontkn == "FAMOUSNAME") + { + auto person = database.nouns().with_singular_form("person").limit(1).run().front(); + auto ptypes = database.nouns().full_hyponym_of({person}).is_class().random().limit(1).run().front(); + result = database.nouns().instance_of({ptypes}).random().limit(1).run().front().singular_form(); + } else { + auto group = groups[canontkn]; + result = group[rand() % group.size()]; + } + + if (modifier == "indefinite") + { + if ((result.length() > 1) && (isupper(result[0])) && (isupper(result[1]))) + { + result = "an " + result; + } else if ((result[0] == 'a') || (result[0] == 'e') || (result[0] == 'i') || (result[0] == 'o') || (result[0] == 'u')) + { + result = "an " + result; + } else { + result = "a " + result; + } + } + + std::string finalresult; + if (islower(token[0])) + { + std::transform(std::begin(result), std::end(result), std::back_inserter(finalresult), [] (char ch) { + return std::tolower(ch); + }); + } else if (isupper(token[0]) && !isupper(token[1])) + { + auto words = verbly::split>(result, " "); + for (auto& word : words) + { + word[0] = std::toupper(word[0]); + } + + finalresult = verbly::implode(std::begin(words), std::end(words), " "); + } else { + finalresult = result; + } + + action.replace(tknloc, action.find("}")-tknloc+1, finalresult); + } + + action.resize(140); + + std::string replyMsg; + if (twitter.statusUpdate(action)) + { + 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); + } +} diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..6a7c6ea --- /dev/null +++ b/data.txt @@ -0,0 +1,226 @@ +MAIN +{PRIMARY} {SECONDARY} + +PRIMARY +{NAME} is {CLASS:indefinite} commonly used to treat {syndrome}. +{NAME} is {CLASS:indefinite} primarily used for {syndrome}. +{NAME} is {CLASS:indefinite} prescribed for {syndrome}. +{NAME} is {CLASS:indefinite} approved for treatment of {syndrome}, {syndrome}, and {syndrome}. +{NAME} is {CLASS:indefinite} used for {syndrome} and {syndrome}. +{NAME} is {CLASS:indefinite} used with {existent} to treat {syndrome}. + +SECONDARY +Developed in {year} in response to the Great {Noun} Epidemic in {Region}. +Frequently prescribed off-label for {syndrome}. +Sometimes used for {syndrome} because of its {verbing} effect. +Illegal to own in the US because of its {verbing} effect. +Developed in {year} to replace {existent}. +Overtook {existent} as the primary treatment, having fewer side effects. +Synthesized by {FamousName} in {year} in a {verbing} accident. +Used mainly in {year}, before {existent} became popular. + +SYNDROME +Irritable {Noun} Syndrome +{Adjective} {Noun} Syndrome +Severe {Noun} +Major {Adjective} Disorder +{Adjective} {Noun} Disorder +Obsessive {Adjective} Disorder +Clinical {Noun} + +CLASS +analgesic +painkiller +anaesthetic +antihistamine +anticonvulsant +antiepileptic +antidepressant +antimigraine +antipsychotic +benzodiazepine +antiparkinsonian +immunosuppressive +antianaemia +anticoagulant +blood thinner +antiarrhythmic +antithrombotic +antifungal +anti-infective +anti-inflammatory +disinfectant +antispetic +antiemetic +diuretic +opiod painkiller +antiulcer +laxative +sedative +hormone +estrogen +androgen +contraceptive +ovulation inducer +thyroid stimulant +antithyroid +insulin +vaccine +oxytocin +SSRI +anxiolytic +antipanic agent +tricyclic +MAOI +SNRI +antiandrogen +psychedelic +vitamin +probiotic +antibiotic +antiviral drug +stimulant +depressant + +EXISTENT +Fluoxetine +Prozac +Sertraline +Zoloft +Escitalopram +Lexapro +Venlafaxine +Effexor +Aripiprazole +Abilify +Alprazolam +Xanax +Diazepam +Valium +Lamotrigine +Lamictal +Gabapentin +Neurontin +Acetaminophen +Tylenol +Ibuprofin +Advil +Lurasidone +Latuda +Lithium +Activated charcoal +Estradiol +AndroGel +Ziprasidone +Geodon +Risperidone +Risperdal +Quetiapine +Seroquel +Cymbalta +Duloxetine +Bupropion +Welbutrin +Buspirone +Buspar +Oxycontin +Oxycodone +Concerta +Methylphenidate +Ritalin +Vyvanse +Lisdexamfetamine +Adderall +Epinephrine +Adrenaline +Testosterone gel +Cialis +Viagra +Heroin +Morphine +Crystal meth + +NAME +{PRENAME}{NAMEMID}{NAMEIFX} + +PRENAME +Oxy +Ari +Zi +Quetia +Mor +Her +Cia +Via +He +Con +Flu +Ser +Es +Ven +Al +Dia +Lamo +Gaba +Aceta +Ibu +Lura +Ris +Li +Estra +Du +Bus +Epin + +NAMEMID +pipra +pi +to +stero +cer +oxe +tra +cita +lo +la +fa +pra +zo +ze +tri +pen +mino +pro +si +peri +thi +loxe +con +epher +{NAMEMID} +{NAMEMID} + +NAMEIFX +zole +ne +tine +lin +tamine +gra +phine +ta +line +pram +xine +lam +pam +gine +tin +phen +fin +done +um +diol +tin +rone +ine \ No newline at end of file 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 diff --git a/vendor/verbly b/vendor/verbly new file mode 160000 index 0000000..6b7c77f --- /dev/null +++ b/vendor/verbly @@ -0,0 +1 @@ +Subproject commit 6b7c77f3a28d9a44afacb76e3db58a5ff5f59f4d -- cgit 1.4.1