summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt17
-rw-r--r--chemist.cpp156
-rw-r--r--data.txt226
m---------vendor/twitcurl0
m---------vendor/verbly0
6 files changed, 405 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..16192d6 --- /dev/null +++ b/.gitmodules
@@ -0,0 +1,6 @@
1[submodule "vendor/verbly"]
2 path = vendor/verbly
3 url = https://github.com/hatkirby/verbly
4[submodule "vendor/twitcurl"]
5 path = vendor/twitcurl
6 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 @@
1cmake_minimum_required (VERSION 2.6)
2project (chemist)
3
4set(CMAKE_BUILD_TYPE Debug)
5
6add_subdirectory(vendor/twitcurl/libtwitcurl)
7add_subdirectory(vendor/verbly)
8
9find_package(PkgConfig)
10pkg_check_modules(YamlCpp yaml-cpp REQUIRED)
11pkg_check_modules(sqlite3 sqlite3 REQUIRED)
12
13include_directories(vendor/twitcurl/libtwitcurl ${sqlite3_INCLUDE_DIR} vendor/verbly/lib)
14add_executable(chemist chemist.cpp)
15set_property(TARGET chemist PROPERTY CXX_STANDARD 11)
16set_property(TARGET chemist PROPERTY CXX_STANDARD_REQUIRED ON)
17target_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 @@
1#include <yaml-cpp/yaml.h>
2#include <iostream>
3#include <cstdlib>
4#include <ctime>
5#include <sstream>
6#include <twitcurl.h>
7#include <verbly.h>
8
9int main(int argc, char** argv)
10{
11 srand(time(NULL));
12
13 YAML::Node config = YAML::LoadFile("config.yml");
14
15 twitCurl twitter;
16 twitter.getOAuth().setConsumerKey(config["consumer_key"].as<std::string>());
17 twitter.getOAuth().setConsumerSecret(config["consumer_secret"].as<std::string>());
18 twitter.getOAuth().setOAuthTokenKey(config["access_key"].as<std::string>());
19 twitter.getOAuth().setOAuthTokenSecret(config["access_secret"].as<std::string>());
20
21 std::map<std::string, std::vector<std::string>> groups;
22 std::ifstream datafile("data.txt");
23 if (!datafile.is_open())
24 {
25 std::cout << "Could not find data.txt" << std::endl;
26 return 1;
27 }
28
29 bool newgroup = true;
30 std::string line;
31 std::string curgroup;
32 while (getline(datafile, line))
33 {
34 if (line.back() == '\r')
35 {
36 line.pop_back();
37 }
38
39 if (newgroup)
40 {
41 curgroup = line;
42 newgroup = false;
43 } else {
44 if (line.empty())
45 {
46 newgroup = true;
47 } else {
48 groups[curgroup].push_back(line);
49 }
50 }
51 }
52
53 verbly::data database {"data.sqlite3"};
54 for (;;)
55 {
56 std::cout << "Generating tweet" << std::endl;
57 std::string action = "{Main}";
58 int tknloc;
59 while ((tknloc = action.find("{")) != std::string::npos)
60 {
61 std::string token = action.substr(tknloc+1, action.find("}")-tknloc-1);
62 std::string modifier;
63 int modloc;
64 if ((modloc = token.find(":")) != std::string::npos)
65 {
66 modifier = token.substr(modloc+1);
67 token = token.substr(0, modloc);
68 }
69
70 std::string canontkn;
71 std::transform(std::begin(token), std::end(token), std::back_inserter(canontkn), [] (char ch) {
72 return std::toupper(ch);
73 });
74
75 std::string result;
76 if (canontkn == "NOUN")
77 {
78 result = database.nouns().is_not_proper().random().limit(1).run().front().singular_form();
79 } else if (canontkn == "ADJECTIVE")
80 {
81 result = database.adjectives().random().limit(1).run().front().base_form();
82 } else if (canontkn == "VERBING")
83 {
84 result = database.verbs().random().limit(1).run().front().ing_form();
85 } else if (canontkn == "YEAR")
86 {
87 result = std::to_string(rand() % 100 + 1916);
88 } else if (canontkn == "REGION")
89 {
90 auto hem1 = database.nouns().with_singular_form("eastern hemisphere").limit(1).run().front();
91 auto hem2 = database.nouns().with_singular_form("western hemisphere").limit(1).run().front();
92 verbly::filter<verbly::noun> region{hem1, hem2};
93 region.set_orlogic(true);
94
95 result = database.nouns().full_part_holonym_of(region).random().limit(1).run().front().singular_form();
96 } else if (canontkn == "FAMOUSNAME")
97 {
98 auto person = database.nouns().with_singular_form("person").limit(1).run().front();
99 auto ptypes = database.nouns().full_hyponym_of({person}).is_class().random().limit(1).run().front();
100 result = database.nouns().instance_of({ptypes}).random().limit(1).run().front().singular_form();
101 } else {
102 auto group = groups[canontkn];
103 result = group[rand() % group.size()];
104 }
105
106 if (modifier == "indefinite")
107 {
108 if ((result.length() > 1) && (isupper(result[0])) && (isupper(result[1])))
109 {
110 result = "an " + result;
111 } else if ((result[0] == 'a') || (result[0] == 'e') || (result[0] == 'i') || (result[0] == 'o') || (result[0] == 'u'))
112 {
113 result = "an " + result;
114 } else {
115 result = "a " + result;
116 }
117 }
118
119 std::string finalresult;
120 if (islower(token[0]))
121 {
122 std::transform(std::begin(result), std::end(result), std::back_inserter(finalresult), [] (char ch) {
123 return std::tolower(ch);
124 });
125 } else if (isupper(token[0]) && !isupper(token[1]))
126 {
127 auto words = verbly::split<std::list<std::string>>(result, " ");
128 for (auto& word : words)
129 {
130 word[0] = std::toupper(word[0]);
131 }
132
133 finalresult = verbly::implode(std::begin(words), std::end(words), " ");
134 } else {
135 finalresult = result;
136 }
137
138 action.replace(tknloc, action.find("}")-tknloc+1, finalresult);
139 }
140
141 action.resize(140);
142
143 std::string replyMsg;
144 if (twitter.statusUpdate(action))
145 {
146 twitter.getLastWebResponse(replyMsg);
147 std::cout << "Twitter message: " << replyMsg << std::endl;
148 } else {
149 twitter.getLastCurlError(replyMsg);
150 std::cout << "Curl error: " << replyMsg << std::endl;
151 }
152
153 std::cout << "Waiting" << std::endl;
154 sleep(60 * 60);
155 }
156}
diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..6a7c6ea --- /dev/null +++ b/data.txt
@@ -0,0 +1,226 @@
1MAIN
2{PRIMARY} {SECONDARY}
3
4PRIMARY
5{NAME} is {CLASS:indefinite} commonly used to treat {syndrome}.
6{NAME} is {CLASS:indefinite} primarily used for {syndrome}.
7{NAME} is {CLASS:indefinite} prescribed for {syndrome}.
8{NAME} is {CLASS:indefinite} approved for treatment of {syndrome}, {syndrome}, and {syndrome}.
9{NAME} is {CLASS:indefinite} used for {syndrome} and {syndrome}.
10{NAME} is {CLASS:indefinite} used with {existent} to treat {syndrome}.
11
12SECONDARY
13Developed in {year} in response to the Great {Noun} Epidemic in {Region}.
14Frequently prescribed off-label for {syndrome}.
15Sometimes used for {syndrome} because of its {verbing} effect.
16Illegal to own in the US because of its {verbing} effect.
17Developed in {year} to replace {existent}.
18Overtook {existent} as the primary treatment, having fewer side effects.
19Synthesized by {FamousName} in {year} in a {verbing} accident.
20Used mainly in {year}, before {existent} became popular.
21
22SYNDROME
23Irritable {Noun} Syndrome
24{Adjective} {Noun} Syndrome
25Severe {Noun}
26Major {Adjective} Disorder
27{Adjective} {Noun} Disorder
28Obsessive {Adjective} Disorder
29Clinical {Noun}
30
31CLASS
32analgesic
33painkiller
34anaesthetic
35antihistamine
36anticonvulsant
37antiepileptic
38antidepressant
39antimigraine
40antipsychotic
41benzodiazepine
42antiparkinsonian
43immunosuppressive
44antianaemia
45anticoagulant
46blood thinner
47antiarrhythmic
48antithrombotic
49antifungal
50anti-infective
51anti-inflammatory
52disinfectant
53antispetic
54antiemetic
55diuretic
56opiod painkiller
57antiulcer
58laxative
59sedative
60hormone
61estrogen
62androgen
63contraceptive
64ovulation inducer
65thyroid stimulant
66antithyroid
67insulin
68vaccine
69oxytocin
70SSRI
71anxiolytic
72antipanic agent
73tricyclic
74MAOI
75SNRI
76antiandrogen
77psychedelic
78vitamin
79probiotic
80antibiotic
81antiviral drug
82stimulant
83depressant
84
85EXISTENT
86Fluoxetine
87Prozac
88Sertraline
89Zoloft
90Escitalopram
91Lexapro
92Venlafaxine
93Effexor
94Aripiprazole
95Abilify
96Alprazolam
97Xanax
98Diazepam
99Valium
100Lamotrigine
101Lamictal
102Gabapentin
103Neurontin
104Acetaminophen
105Tylenol
106Ibuprofin
107Advil
108Lurasidone
109Latuda
110Lithium
111Activated charcoal
112Estradiol
113AndroGel
114Ziprasidone
115Geodon
116Risperidone
117Risperdal
118Quetiapine
119Seroquel
120Cymbalta
121Duloxetine
122Bupropion
123Welbutrin
124Buspirone
125Buspar
126Oxycontin
127Oxycodone
128Concerta
129Methylphenidate
130Ritalin
131Vyvanse
132Lisdexamfetamine
133Adderall
134Epinephrine
135Adrenaline
136Testosterone gel
137Cialis
138Viagra
139Heroin
140Morphine
141Crystal meth
142
143NAME
144{PRENAME}{NAMEMID}{NAMEIFX}
145
146PRENAME
147Oxy
148Ari
149Zi
150Quetia
151Mor
152Her
153Cia
154Via
155He
156Con
157Flu
158Ser
159Es
160Ven
161Al
162Dia
163Lamo
164Gaba
165Aceta
166Ibu
167Lura
168Ris
169Li
170Estra
171Du
172Bus
173Epin
174
175NAMEMID
176pipra
177pi
178to
179stero
180cer
181oxe
182tra
183cita
184lo
185la
186fa
187pra
188zo
189ze
190tri
191pen
192mino
193pro
194si
195peri
196thi
197loxe
198con
199epher
200{NAMEMID}
201{NAMEMID}
202
203NAMEIFX
204zole
205ne
206tine
207lin
208tamine
209gra
210phine
211ta
212line
213pram
214xine
215lam
216pam
217gine
218tin
219phen
220fin
221done
222um
223diol
224tin
225rone
226ine \ No newline at end of file
diff --git a/vendor/twitcurl b/vendor/twitcurl new file mode 160000
Subproject 6659e86de7481e50977b7569c75138f7f69ad3c
diff --git a/vendor/verbly b/vendor/verbly new file mode 160000
Subproject 6b7c77f3a28d9a44afacb76e3db58a5ff5f59f4