about summary refs log tree commit diff stats
path: root/lunatic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lunatic.cpp')
-rw-r--r--lunatic.cpp105
1 files changed, 68 insertions, 37 deletions
diff --git a/lunatic.cpp b/lunatic.cpp index daebc73..59241fa 100644 --- a/lunatic.cpp +++ b/lunatic.cpp
@@ -10,30 +10,9 @@
10#include <string> 10#include <string>
11#include <set> 11#include <set>
12#include <sstream> 12#include <sstream>
13#include "database.h" 13#include <hkutil/string.h>
14 14#include <hkutil/database.h>
15template <class Container> 15#include <iomanip>
16Container split(std::string input, std::string delimiter)
17{
18 Container result;
19
20 while (!input.empty())
21 {
22 int divider = input.find(delimiter);
23 if (divider == std::string::npos)
24 {
25 result.push_back(input);
26
27 input = "";
28 } else {
29 result.push_back(input.substr(0, divider));
30
31 input = input.substr(divider+delimiter.length());
32 }
33 }
34
35 return result;
36}
37 16
38int main(int argc, char** argv) 17int main(int argc, char** argv)
39{ 18{
@@ -56,7 +35,9 @@ int main(int argc, char** argv)
56 35
57 twitter::client client(auth); 36 twitter::client client(auth);
58 37
59 database db(config["database"].as<std::string>()); 38 hatkirby::database database(
39 config["database"].as<std::string>(),
40 hatkirby::dbmode::read);
60 41
61 std::random_device randomDevice; 42 std::random_device randomDevice;
62 std::mt19937 rng(randomDevice()); 43 std::mt19937 rng(randomDevice());
@@ -87,15 +68,29 @@ int main(int argc, char** argv)
87 { 68 {
88 std::cout << "Generating tweet" << std::endl; 69 std::cout << "Generating tweet" << std::endl;
89 70
90 achievement ach = db.getRandomAchievement(); 71 hatkirby::row achRow =
91 72 database.queryFirst(
92 if (blacklist.count(ach.title)) 73 "SELECT achievements.achievement_id, \
74 achievements.game_id, \
75 achievements.title, \
76 games.color \
77 FROM achievements \
78 INNER JOIN games ON games.game_id = achievements.game_id \
79 ORDER BY RANDOM() \
80 LIMIT 1");
81
82 int achId = mpark::get<int>(achRow[0]);
83 int gameId = mpark::get<int>(achRow[1]);
84 std::string achTitle = mpark::get<std::string>(achRow[2]);
85 std::string achColor = mpark::get<std::string>(achRow[3]);
86
87 if (blacklist.count(achTitle))
93 { 88 {
94 continue; 89 continue;
95 } 90 }
96 91
97 Magick::Image moonColor; 92 Magick::Image moonColor;
98 moonColor.read("res/" + ach.color + ".png"); 93 moonColor.read("res/" + achColor + ".png");
99 94
100 // Start with the Odyssey text overlay 95 // Start with the Odyssey text overlay
101 Magick::Image overlay; 96 Magick::Image overlay;
@@ -115,9 +110,11 @@ int main(int argc, char** argv)
115 overlay.fillColor("white"); 110 overlay.fillColor("white");
116 overlay.font("@" + config["title_font"].as<std::string>()); 111 overlay.font("@" + config["title_font"].as<std::string>());
117 112
118 std::list<std::string> words = split<std::list<std::string>>( 113 std::list<std::string> words =
119 ach.title, 114 hatkirby::split<std::list<std::string>>(
120 " "); 115 achTitle,
116 " ");
117
121 std::ostringstream wrappingStream; 118 std::ostringstream wrappingStream;
122 std::string curline; 119 std::string curline;
123 int lines = 1; 120 int lines = 1;
@@ -163,14 +160,32 @@ int main(int argc, char** argv)
163 Magick::GravityType::NorthGravity); 160 Magick::GravityType::NorthGravity);
164 161
165 // Add the achievement date 162 // Add the achievement date
166 did theDid = db.getRandomDidForAchievement(ach.achievementId); 163 hatkirby::row didRow =
164 database.queryFirst(
165 "SELECT DATETIME(achieved_at) \
166 FROM dids \
167 WHERE achievement_id = ? \
168 ORDER BY RANDOM() \
169 LIMIT 1",
170 { achId });
171
172 std::tm achievedAt = {};
173
174 std::stringstream dateParser;
175 dateParser << mpark::get<std::string>(didRow[0]);
176 dateParser >> std::get_time(&achievedAt, "%Y-%m-%d %H:%M:%S");
177
178 std::stringstream dateFormatter;
179 dateFormatter << std::put_time(&achievedAt, "%m/%d/%Y");
180
181 std::string didDate = dateFormatter.str();
167 182
168 overlay.fontTypeMetrics(wrapped, &metric); 183 overlay.fontTypeMetrics(wrapped, &metric);
169 184
170 overlay.fontPointsize(20); 185 overlay.fontPointsize(20);
171 overlay.font("@" + config["date_font"].as<std::string>()); 186 overlay.font("@" + config["date_font"].as<std::string>());
172 overlay.annotate( 187 overlay.annotate(
173 theDid.date, 188 didDate,
174 Magick::Geometry(1600, 228, 0, 710 + metric.textHeight() * lines - 22), 189 Magick::Geometry(1600, 228, 0, 710 + metric.textHeight() * lines - 22),
175 Magick::GravityType::NorthGravity); 190 Magick::GravityType::NorthGravity);
176 191
@@ -182,9 +197,25 @@ int main(int argc, char** argv)
182 // Read the game image, using a default if the game has no images 197 // Read the game image, using a default if the game has no images
183 Magick::Image image; 198 Magick::Image image;
184 199
185 if (db.doesGameHaveImages(ach.gameId)) 200 hatkirby::row checkRow =
201 database.queryFirst(
202 "SELECT COUNT(*) \
203 FROM images \
204 WHERE game_id = ?",
205 { gameId });
206
207 if (mpark::get<int>(checkRow[0]) > 0)
186 { 208 {
187 std::string imageName = db.getRandomImageForGame(ach.gameId); 209 hatkirby::row imageRow =
210 database.queryFirst(
211 "SELECT filename \
212 FROM images \
213 WHERE game_id = ? \
214 ORDER BY RANDOM() \
215 LIMIT 1",
216 { gameId });
217
218 std::string imageName = mpark::get<std::string>(imageRow[0]);
188 std::string imagePath = config["images"].as<std::string>() 219 std::string imagePath = config["images"].as<std::string>()
189 + "/" + imageName; 220 + "/" + imageName;
190 221
@@ -229,7 +260,7 @@ int main(int argc, char** argv)
229 } 260 }
230 261
231 std::string header = "YOU GOT A MOON!"; 262 std::string header = "YOU GOT A MOON!";
232 std::string action = header + "\n" + ach.title; 263 std::string action = header + "\n" + achTitle;
233 action.resize(140); 264 action.resize(140);
234 265
235 std::cout << action << std::endl; 266 std::cout << action << std::endl;