about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--cadence.cpp73
-rw-r--r--cadence.h30
-rw-r--r--main.cpp32
4 files changed, 95 insertions, 42 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a64833d..34827c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -13,7 +13,7 @@ include_directories(
13 ${yaml-cpp_INCLUDE_DIRS} 13 ${yaml-cpp_INCLUDE_DIRS}
14 vendor/hkutil) 14 vendor/hkutil)
15 15
16add_executable(cadence cadence.cpp) 16add_executable(cadence cadence.cpp main.cpp)
17set_property(TARGET cadence PROPERTY CXX_STANDARD 11) 17set_property(TARGET cadence PROPERTY CXX_STANDARD 11)
18set_property(TARGET cadence PROPERTY CXX_STANDARD_REQUIRED ON) 18set_property(TARGET cadence PROPERTY CXX_STANDARD_REQUIRED ON)
19target_link_libraries(cadence ${sqlite3_LIBRARIES} twitter++ ${yaml-cpp_LIBRARIES}) 19target_link_libraries(cadence ${sqlite3_LIBRARIES} twitter++ ${yaml-cpp_LIBRARIES})
diff --git a/cadence.cpp b/cadence.cpp index 97a74b7..feb02e1 100644 --- a/cadence.cpp +++ b/cadence.cpp
@@ -1,45 +1,26 @@
1#include "cadence.h"
1#include <stdexcept> 2#include <stdexcept>
2#include <vector>
3#include <string>
4#include <yaml-cpp/yaml.h> 3#include <yaml-cpp/yaml.h>
5#include <sqlite3.h>
6#include <iostream> 4#include <iostream>
7#include <fstream> 5#include <fstream>
8#include <twitter.h>
9#include <chrono> 6#include <chrono>
10#include <thread> 7#include <thread>
11#include <random>
12#include <list> 8#include <list>
13#include <hkutil/string.h> 9#include <hkutil/string.h>
14#include <hkutil/database.h>
15 10
16int main(int argc, char** argv) 11cadence::cadence(
12 std::string configFile,
13 std::mt19937& rng) :
14 rng_(rng)
17{ 15{
18 if (argc != 2) 16 // Load the config file.
19 { 17 YAML::Node config = YAML::LoadFile(configFile);
20 std::cout << "usage: cadence [configfile]" << std::endl;
21 return -1;
22 }
23
24 std::string configfile(argv[1]);
25 YAML::Node config = YAML::LoadFile(configfile);
26
27 // Set up the Twitter client.
28 twitter::auth auth;
29 auth.setConsumerKey(config["consumer_key"].as<std::string>());
30 auth.setConsumerSecret(config["consumer_secret"].as<std::string>());
31 auth.setAccessKey(config["access_key"].as<std::string>());
32 auth.setAccessSecret(config["access_secret"].as<std::string>());
33
34 twitter::client client(auth);
35 18
36 // Read in the forms file. 19 // Read in the forms file.
37 std::map<std::string, std::vector<std::string>> groups;
38 std::ifstream datafile(config["forms"].as<std::string>()); 20 std::ifstream datafile(config["forms"].as<std::string>());
39 if (!datafile.is_open()) 21 if (!datafile.is_open())
40 { 22 {
41 std::cout << "Could not find forms file." << std::endl; 23 throw std::invalid_argument("Could not find forms file");
42 return 1;
43 } 24 }
44 25
45 bool newgroup = true; 26 bool newgroup = true;
@@ -61,30 +42,40 @@ int main(int argc, char** argv)
61 { 42 {
62 newgroup = true; 43 newgroup = true;
63 } else { 44 } else {
64 groups[curgroup].push_back(line); 45 groups_[curgroup].push_back(line);
65 } 46 }
66 } 47 }
67 } 48 }
68 49
69 // Initialize the random number generator.
70 std::random_device random_device;
71 std::mt19937 random_engine{random_device()};
72
73 // Connect to the AcousticBrainz data file. 50 // Connect to the AcousticBrainz data file.
74 hatkirby::database abdb( 51 database_ =
75 config["acoustic_datafile"].as<std::string>(), 52 std::unique_ptr<hatkirby::database>(
76 hatkirby::dbmode::read); 53 new hatkirby::database(
54 config["acoustic_datafile"].as<std::string>(),
55 hatkirby::dbmode::read));
77 56
57 // Set up the Twitter client.
58 twitter::auth auth;
59 auth.setConsumerKey(config["consumer_key"].as<std::string>());
60 auth.setConsumerSecret(config["consumer_secret"].as<std::string>());
61 auth.setAccessKey(config["access_key"].as<std::string>());
62 auth.setAccessSecret(config["access_secret"].as<std::string>());
63
64 client_ = std::unique_ptr<twitter::client>(new twitter::client(auth));
65}
66
67void cadence::run() const
68{
78 for (;;) 69 for (;;)
79 { 70 {
80 std::cout << "Generating tweet..." << std::endl; 71 std::cout << "Generating tweet..." << std::endl;
81 72
82 hatkirby::row songRow = 73 hatkirby::row songRow =
83 abdb.queryFirst( 74 database_->queryFirst(
84 "SELECT song_id, title, artist FROM songs ORDER BY RANDOM() LIMIT 1"); 75 "SELECT song_id, title, artist FROM songs ORDER BY RANDOM() LIMIT 1");
85 76
86 hatkirby::row moodRow = 77 hatkirby::row moodRow =
87 abdb.queryFirst( 78 database_->queryFirst(
88 "SELECT mood FROM moods WHERE song_id = ? ORDER BY RANDOM() LIMIT 1", 79 "SELECT mood FROM moods WHERE song_id = ? ORDER BY RANDOM() LIMIT 1",
89 { mpark::get<int>(songRow[0]) }); 80 { mpark::get<int>(songRow[0]) });
90 81
@@ -118,11 +109,11 @@ int main(int argc, char** argv)
118 } else if (canontkn == "SONG") 109 } else if (canontkn == "SONG")
119 { 110 {
120 result = "\"" + songTitle + "\""; 111 result = "\"" + songTitle + "\"";
121 } else if (groups.count(canontkn)) { 112 } else if (groups_.count(canontkn)) {
122 auto& group = groups.at(canontkn); 113 auto& group = groups_.at(canontkn);
123 std::uniform_int_distribution<int> dist(0, group.size() - 1); 114 std::uniform_int_distribution<int> dist(0, group.size() - 1);
124 115
125 result = group[dist(random_engine)]; 116 result = group[dist(rng_)];
126 } else { 117 } else {
127 throw std::logic_error("No such form as " + canontkn); 118 throw std::logic_error("No such form as " + canontkn);
128 } 119 }
@@ -175,7 +166,7 @@ int main(int argc, char** argv)
175 { 166 {
176 try 167 try
177 { 168 {
178 client.updateStatus(action); 169 client_->updateStatus(action);
179 170
180 std::cout << action << std::endl; 171 std::cout << action << std::endl;
181 } catch (const twitter::twitter_error& e) 172 } catch (const twitter::twitter_error& e)
diff --git a/cadence.h b/cadence.h new file mode 100644 index 0000000..408c258 --- /dev/null +++ b/cadence.h
@@ -0,0 +1,30 @@
1#ifndef CADENCE_H_D4AE737D
2#define CADENCE_H_D4AE737D
3
4#include <random>
5#include <string>
6#include <map>
7#include <vector>
8#include <hkutil/database.h>
9#include <twitter.h>
10
11class cadence {
12public:
13
14 cadence(
15 std::string configFile,
16 std::mt19937& rng);
17
18 void run() const;
19
20private:
21
22 std::mt19937& rng_;
23 std::map<std::string, std::vector<std::string>> groups_;
24 std::unique_ptr<hatkirby::database> database_;
25 std::unique_ptr<twitter::client> client_;
26
27};
28
29
30#endif /* end of include guard: CADENCE_H_D4AE737D */
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..fe12ea5 --- /dev/null +++ b/main.cpp
@@ -0,0 +1,32 @@
1#include "cadence.h"
2#include <iostream>
3
4int main(int argc, char** argv)
5{
6 std::random_device randomDevice;
7 std::mt19937 rng(randomDevice());
8
9 if (argc != 2)
10 {
11 std::cout << "usage: cadence [configfile]" << std::endl;
12 return -1;
13 }
14
15 std::string configfile(argv[1]);
16
17 try
18 {
19 cadence bot(configfile, rng);
20
21 try
22 {
23 bot.run();
24 } catch (const std::exception& ex)
25 {
26 std::cout << "Error running bot: " << ex.what() << std::endl;
27 }
28 } catch (const std::exception& ex)
29 {
30 std::cout << "Error initializing bot: " << ex.what() << std::endl;
31 }
32}