diff options
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | CMakeLists.txt | 16 | ||||
| -rw-r--r-- | lunatic.cpp | 84 | ||||
| -rw-r--r-- | scrape.rb | 38 | ||||
| m--------- | vendor/libtwittercpp | 0 |
6 files changed, 147 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae9dcf9 --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | .AppleDouble | ||
| 2 | .DS_Store | ||
| 3 | CMakeCache.txt | ||
| 4 | Makefile | ||
| 5 | cmake_install.cmake | ||
| 6 | CMakeFiles | ||
| diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b7a969a --- /dev/null +++ b/.gitmodules | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | [submodule "vendor/libtwittercpp"] | ||
| 2 | path = vendor/libtwittercpp | ||
| 3 | url = git@github.com:hatkirby/libtwittercpp | ||
| diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..55a671b --- /dev/null +++ b/CMakeLists.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | cmake_minimum_required (VERSION 3.1) | ||
| 2 | project (lunatic) | ||
| 3 | |||
| 4 | add_subdirectory(vendor/libtwittercpp) | ||
| 5 | |||
| 6 | find_package(PkgConfig) | ||
| 7 | pkg_check_modules(yaml-cpp yaml-cpp REQUIRED) | ||
| 8 | |||
| 9 | include_directories( | ||
| 10 | vendor/libtwittercpp/src | ||
| 11 | ${yaml-cpp_INCLUDE_DIRS}) | ||
| 12 | |||
| 13 | add_executable(lunatic lunatic.cpp) | ||
| 14 | set_property(TARGET lunatic PROPERTY CXX_STANDARD 11) | ||
| 15 | set_property(TARGET lunatic PROPERTY CXX_STANDARD_REQUIRED ON) | ||
| 16 | target_link_libraries(lunatic ${yaml-cpp_LIBRARIES} twitter++) \ No newline at end of file | ||
| diff --git a/lunatic.cpp b/lunatic.cpp new file mode 100644 index 0000000..2438788 --- /dev/null +++ b/lunatic.cpp | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | #include <yaml-cpp/yaml.h> | ||
| 2 | #include <iostream> | ||
| 3 | #include <random> | ||
| 4 | #include <fstream> | ||
| 5 | #include <twitter.h> | ||
| 6 | #include <chrono> | ||
| 7 | #include <thread> | ||
| 8 | |||
| 9 | int main(int argc, char** argv) | ||
| 10 | { | ||
| 11 | if (argc != 2) | ||
| 12 | { | ||
| 13 | std::cout << "usage: lunatic [configfile]" << std::endl; | ||
| 14 | return -1; | ||
| 15 | } | ||
| 16 | |||
| 17 | std::string configfile(argv[1]); | ||
| 18 | YAML::Node config = YAML::LoadFile(configfile); | ||
| 19 | |||
| 20 | twitter::auth auth; | ||
| 21 | auth.setConsumerKey(config["consumer_key"].as<std::string>()); | ||
| 22 | auth.setConsumerSecret(config["consumer_secret"].as<std::string>()); | ||
| 23 | auth.setAccessKey(config["access_key"].as<std::string>()); | ||
| 24 | auth.setAccessSecret(config["access_secret"].as<std::string>()); | ||
| 25 | |||
| 26 | twitter::client client(auth); | ||
| 27 | |||
| 28 | std::random_device randomDevice; | ||
| 29 | std::mt19937 rng(randomDevice()); | ||
| 30 | |||
| 31 | for (;;) | ||
| 32 | { | ||
| 33 | std::cout << "Generating tweet" << std::endl; | ||
| 34 | |||
| 35 | // Reload achievements list every time in case it has been updated | ||
| 36 | std::vector<std::string> achievements; | ||
| 37 | std::ifstream datafile(config["achievements"].as<std::string>()); | ||
| 38 | if (!datafile.is_open()) | ||
| 39 | { | ||
| 40 | std::cout << "Could not find achievements file." << std::endl; | ||
| 41 | return 1; | ||
| 42 | } | ||
| 43 | |||
| 44 | std::string line; | ||
| 45 | while (getline(datafile, line)) | ||
| 46 | { | ||
| 47 | if (line.back() == '\r') | ||
| 48 | { | ||
| 49 | line.pop_back(); | ||
| 50 | } | ||
| 51 | |||
| 52 | achievements.push_back(line); | ||
| 53 | } | ||
| 54 | |||
| 55 | std::uniform_int_distribution<int> dist(0, achievements.size() - 1); | ||
| 56 | std::string achievement = achievements[dist(rng)]; | ||
| 57 | |||
| 58 | std::string header; | ||
| 59 | if (std::bernoulli_distribution(1.0 / 50.0)(rng)) | ||
| 60 | { | ||
| 61 | header = "YOU GOT A MULTI MOON!"; | ||
| 62 | } else { | ||
| 63 | header = "YOU GOT A MOON!"; | ||
| 64 | } | ||
| 65 | |||
| 66 | std::string action = header + "\n" + achievement; | ||
| 67 | action.resize(140); | ||
| 68 | |||
| 69 | try | ||
| 70 | { | ||
| 71 | client.updateStatus(action); | ||
| 72 | } catch (const twitter::twitter_error& e) | ||
| 73 | { | ||
| 74 | std::cout << "Twitter error: " << e.what() << std::endl; | ||
| 75 | } | ||
| 76 | |||
| 77 | std::cout << action << std::endl; | ||
| 78 | std::cout << "Waiting" << std::endl; | ||
| 79 | |||
| 80 | std::this_thread::sleep_for(std::chrono::hours(3)); | ||
| 81 | |||
| 82 | std::cout << std::endl; | ||
| 83 | } | ||
| 84 | } | ||
| diff --git a/scrape.rb b/scrape.rb new file mode 100644 index 0000000..5d62e89 --- /dev/null +++ b/scrape.rb | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | require 'json' | ||
| 2 | require 'nokogiri' | ||
| 3 | require 'open-uri' | ||
| 4 | require 'yaml' | ||
| 5 | |||
| 6 | config = YAML.load(open("config.yml")) | ||
| 7 | usernames = config["usernames"] | ||
| 8 | |||
| 9 | achieves = usernames.map do |username| | ||
| 10 | page = Nokogiri::HTML(open("https://steamcommunity.com/id/#{username}/games/?tab=all")) | ||
| 11 | script = page.css(".responsive_page_template_content script").text[18..-1] | ||
| 12 | data = JSON.parse(script[0..script.index(";\r\n\t\t")-1]) | ||
| 13 | ids = data.map { |d| d["appid"] } | ||
| 14 | |||
| 15 | ids.map do |id| | ||
| 16 | achsp = Nokogiri::HTML(open("https://steamcommunity.com/id/#{username}/stats/#{id}/")) | ||
| 17 | achsp.css(".achieveTxt .achieveUnlockTime + h3").map { |d| d.text } | ||
| 18 | end | ||
| 19 | end.flatten | ||
| 20 | |||
| 21 | if File.exists?("achieves.txt") | ||
| 22 | already = File.read("achieves.txt").split("\n") | ||
| 23 | all_achieves = achieves + already | ||
| 24 | else | ||
| 25 | all_achieves = achieves | ||
| 26 | end | ||
| 27 | |||
| 28 | all_achieves.sort! | ||
| 29 | all_achieves.uniq! | ||
| 30 | |||
| 31 | if config.key? "blacklist" | ||
| 32 | blacklist = File.read(config["blacklist"]).split("\n") | ||
| 33 | all_achieves.reject! { |l| blacklist.include? l } | ||
| 34 | end | ||
| 35 | |||
| 36 | File.open("achieves.txt", "w") do |f| | ||
| 37 | f << all_achieves.join("\n") | ||
| 38 | end | ||
| diff --git a/vendor/libtwittercpp b/vendor/libtwittercpp new file mode 160000 | |||
| Subproject d1d20515281e32b23657762e72bf37dcff14f0a | |||
