about summary refs log tree commit diff stats
path: root/fanmail.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fanmail.cpp')
-rw-r--r--fanmail.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/fanmail.cpp b/fanmail.cpp new file mode 100644 index 0000000..785a574 --- /dev/null +++ b/fanmail.cpp
@@ -0,0 +1,106 @@
1#include "fanmail.h"
2#include <yaml-cpp/yaml.h>
3#include <thread>
4#include <chrono>
5#include <fstream>
6#include <iostream>
7
8fanmail::fanmail(
9 std::string configFile,
10 std::mt19937& rng) :
11 rng_(rng)
12{
13 // Load the config file.
14 YAML::Node config = YAML::LoadFile(configFile);
15
16 // Set up the Twitter client.
17 auth_ =
18 std::unique_ptr<twitter::auth>(
19 new twitter::auth(
20 config["consumer_key"].as<std::string>(),
21 config["consumer_secret"].as<std::string>(),
22 config["access_key"].as<std::string>(),
23 config["access_secret"].as<std::string>()));
24
25 client_ =
26 std::unique_ptr<twitter::client>(
27 new twitter::client(*auth_));
28
29 // Set up the layout designer.
30 layout_ = std::unique_ptr<designer>(
31 new designer(config["images"].as<std::string>()));
32
33 // Set up librawr.
34 std::ifstream infile(config["corpus"].as<std::string>());
35 std::string corpus;
36 std::string line;
37 while (getline(infile, line))
38 {
39 if (line.back() == '\r')
40 {
41 line.pop_back();
42 }
43
44 corpus += line + "\n";
45 }
46
47 kgramstats_.addCorpus(corpus);
48 kgramstats_.compile(3);
49}
50
51void fanmail::run() const
52{
53 for (;;)
54 {
55 std::cout << "Generating tweet..." << std::endl;
56
57 try
58 {
59 // Design the comic strip.
60 Magick::Image image = layout_->generate(rng_);
61
62 // Write the tweet.
63 std::string doc = kgramstats_.randomSentence(15);
64 doc.resize(40);
65
66 std::cout << doc << std::endl;
67
68 // Send the tweet.
69 std::cout << "Sending tweet..." << std::endl;
70
71 sendTweet(std::move(image), std::move(doc));
72
73 std::cout << "Tweeted!" << std::endl;
74
75 // Wait.
76 std::binomial_distribution<int> waitDist(35, 0.5);
77 int waitTime = waitDist(rng_) + 1;
78
79 std::cout << "Waiting for " << waitTime << " hours..." << std::endl;
80
81 std::this_thread::sleep_for(std::chrono::hours(waitTime));
82 } catch (const Magick::ErrorImage& ex)
83 {
84 std::cout << "Image error: " << ex.what() << std::endl;
85 } catch (const twitter::twitter_error& ex)
86 {
87 std::cout << "Twitter error: " << ex.what() << std::endl;
88
89 std::this_thread::sleep_for(std::chrono::hours(1));
90 }
91
92 std::cout << std::endl;
93 }
94}
95
96void fanmail::sendTweet(Magick::Image image, std::string doc) const
97{
98 Magick::Blob outputimg;
99 image.magick("png");
100 image.write(&outputimg);
101
102 long media_id = client_->uploadMedia("image/png",
103 static_cast<const char*>(outputimg.data()), outputimg.length());
104
105 client_->updateStatus(std::move(doc), {media_id});
106}