Ups, habe das committen vergessen. :-)

This commit is contained in:
tastytea 2019-02-12 01:46:48 +01:00
parent 377d2d768d
commit 3fb2225392
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
5 changed files with 201 additions and 17 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "xdgjson"]
path = xdgjson
url = https://schlomp.space/tastytea/xdgjson.git

View File

@ -6,7 +6,6 @@ project(feiertagebot
include(GNUInstallDirs)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBXDG_BASEDIR REQUIRED libxdg-basedir)
pkg_check_modules(LIBCONFIG REQUIRED libconfig++)
pkg_check_modules(CURLPP REQUIRED curlpp)
pkg_check_modules(JSONCPP REQUIRED jsoncpp)
@ -19,20 +18,18 @@ set(CMAKE_CXX_FLAGS_DEBUG
include_directories(${PROJECT_BINARY_DIR})
include_directories(${LIBXDG_BASEDIR_INCLUDE_DIRS})
include_directories(${LIBCONFIG_INCLUDE_DIRS})
include_directories(${CURL_INCLUDE_DIRS})
include_directories(${CURLPP_INCLUDE_DIRS})
include_directories(${JSONCPP_INCLUDE_DIRS})
link_directories(${LIBXDG_BASEDIR_LIBRARY_DIRS})
link_directories(${LIBCONFIG_LIBRARY_DIRS})
link_directories(${CURL_LIBRARY_DIRS})
link_directories(${CURLPP_LIBRARY_DIRS})
link_directories(${JSONCPP_LIBRARY_DIRS})
add_executable(${CMAKE_PROJECT_NAME} feiertagebot.cpp)
add_executable(${CMAKE_PROJECT_NAME} feiertagebot.cpp xdgjson/src/xdgjson.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME}
"${LIBXDG_BASEDIR_LDFLAGS} ${LIBCONFIG_LDFLAGS}"
"${CURLPP_LDFLAGS} ${JSONCPP_LDFLAGS}"
"-lstdc++fs")
"-lstdc++fs -lmastodon-cpp")
install(TARGETS ${CMAKE_PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})

View File

@ -3,8 +3,6 @@
*feiertagebot* ist ein Mastodon-bot, der über anstehende feiertage in
Deutschland informiert. Die daten stammen von https://feiertage-api.de/.
NOTE: Ist noch in arbeit, tut bis jetzt noch nix.
== Installation
=== Gentoo
@ -17,9 +15,9 @@ https://schlomp.space/tastytea/overlay[repository].
* C++ compiler
* https://cmake.org/[cmake] (mindestens 3.2)
* http://repo.or.cz/w/libxdg-basedir.git[libxdg-basedir] (getested: 1.2)
* https://github.com/hyperrealm/libconfig[libconfig++] (getested: 1.5)
* http://www.curlpp.org/[curlpp] (getested: 0.8)
* https://github.com/open-source-parsers/jsoncpp[jsoncpp] (getested: 1.8)
* https://schlomp.space/tastytea/mastodon-cpp[mastodon-cpp] (mindestens 0.30.1)
=== Kompilieren
@ -35,6 +33,19 @@ make install
.cmake options:
* `-DCMAKE_BUILD_TYPE=Debug` für ein debug-build
== Benutzung
Beim ersten aufruf wirst du nach der instanz gefragt, dann wird ein access_token
generiert. Danach kannst du das programm einfach per cron aufrufen
(`crontab -e`).
.Beispieleintrag crontab
[source,crontab]
----
# m h dom mon dow command
10 14 * * * feiertagebot
----
== Lizenz
CC-0 / Public Domain

View File

@ -5,26 +5,149 @@
#include <exception>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <map>
#include <chrono>
#include <ctime>
#include <cstdint>
#include <curlpp/Options.hpp>
#include <curlpp/Exception.hpp>
#include <curlpp/Infos.hpp>
#include <json/json.h>
#include <mastodon-cpp/easy/all.hpp>
#include "xdgjson/src/xdgjson.hpp"
namespace curlopts = curlpp::options;
using std::string;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::chrono::system_clock;
using std::chrono::hours;
using std::uint_fast16_t;
const string version = "2019-02-12_1";
struct Holiday
{
string date;
string description;
vector<string> regions;
};
const string decode_state(const string &abbr)
{
const std::map<string, string> states =
{
{ "BW", "Baden-Württemberg" },
{ "BY", "Bayern" },
{ "BE", "Berlin" },
{ "BB", "Brandenburg" },
{ "HB", "Bremen" },
{ "HH", "Hamburg" },
{ "HE", "Hessen" },
{ "MV", "Mecklenburg-Vorpommern" },
{ "NI", "Niedersachsen" },
{ "NW", "Nordrhein-Westfalen" },
{ "RP", "Rheinland-Pfalz" },
{ "SL", "Saarland" },
{ "SN", "Sachsen" },
{ "ST", "Sachsen-Anhalt" },
{ "SH", "Schleswig-Holstein" },
{ "TH", "Thüringen" }
};
if (states.find(abbr) != states.end())
{
return states.find(abbr)->second;
}
else
{
return abbr;
}
}
const string get_date(const system_clock::time_point &timepoint, const string &format)
{
std::time_t time = system_clock::to_time_t(timepoint);
std::tm *timeinfo = std::localtime(&time);
char buffer[1024];
std::strftime(buffer, 1024, format.c_str(), timeinfo);
return string(buffer);
}
const string get_token(const string &instance)
{
Mastodon::API masto(instance, "");
uint_fast16_t ret = 0;
string client_id, client_secret, url;
string code, access_token;
ret = masto.register_app1("feiertagebot",
"urn:ietf:wg:oauth:2.0:oob",
"write:statuses",
"",
client_id,
client_secret,
url);
if (ret > 0)
{
cerr << "Error " << std::to_string(ret) << endl;
return "";
}
cout << "Visit " << url << " to authorize this application.\n";
cout << "Insert code: ";
std::getline(std::cin, code);
ret = masto.register_app2(client_id,
client_secret,
"urn:ietf:wg:oauth:2.0:oob",
code,
access_token);
if (ret > 0)
{
cerr << "Error " << std::to_string(ret) << endl;
return "";
}
return access_token;
}
int main()
{
const string version = "2019-02-11_1";
string instance, access_token;
xdgjson config("feiertagebot.json");
config.read();
Json::Value &json = config.get_json();
if (json["instance"].isString())
{
instance = json["instance"].asString();
}
else
{
cout << "Instance domain: ";
std::getline(std::cin, instance);
json["instance"] = instance;
}
if (json["access_token"].isString())
{
access_token = json["access_token"].asString();
}
else
{
access_token = get_token(instance);
json["access_token"] = access_token;
config.write();
}
try
{
string year = "2019";
string today = "2019-12-25";
string tomorrow = "2019-12-26";
string year = get_date(system_clock::now(), "%Y");
string today = get_date(system_clock::now(), "%F");
string tomorrow = get_date(system_clock::now() + hours(24), "%F");
tomorrow = "2019-01-06";
curlpp::Easy request;
std::stringstream ss;
@ -32,19 +155,67 @@ int main()
request.setOpt<curlopts::UserAgent>("feiertagebot/" + version);
request.setOpt<curlopts::FollowLocation>(true);
ss << request;
Json::Value root;
ss >> root;
for (Json::Value::const_iterator it_root = root.begin(); it_root != root.end(); ++it_root)
string output;
for (const string &date : { today, tomorrow })
{
for (Json::Value::const_iterator it_region = it_root->begin(); it_region != it_root->end(); ++it_region)
Holiday current_day;
for (Json::Value::const_iterator it_root = root.begin(); it_root != root.end(); ++it_root)
{
if ((*it_region)["datum"] == today)
for (Json::Value::const_iterator it_region = it_root->begin(); it_region != it_root->end(); ++it_region)
{
cout << it_root.key() << ": " << (*it_region)["datum"] << ": " << it_region.key() << endl;
if ((*it_region)["datum"] == date)
{
current_day.date = date;
current_day.description = it_region.key().asString();
current_day.regions.push_back(it_root.key().asString());
}
}
}
if (current_day.date.empty())
{
continue;
}
output += "Am " + current_day.date + " ist "+ current_day.description + " in ";
if (std::find(current_day.regions.begin(), current_day.regions.end(), "NATIONAL") != current_day.regions.end())
{
output += "Deutschland.\n";
}
else
{
bool firstrun = true;
for (const string &region : current_day.regions)
{
if (!firstrun)
{
output += ", ";
}
else
{
firstrun = false;
}
output += decode_state(region);
}
output += "\n";
}
}
if (!output.empty())
{
uint_fast16_t ret;
Mastodon::Easy masto(instance, access_token);
masto.exceptions(true);
Mastodon::Easy::Status status;
status.content(output);
masto.send_post(status, ret);
if (ret > 0)
{
cerr << "Error " << std::to_string(ret) << endl;
return ret;
}
}
}
catch (const std::exception &e)
@ -52,5 +223,6 @@ int main()
cerr << e.what() << endl;
return 1;
}
return 0;
}

1
xdgjson Submodule

@ -0,0 +1 @@
Subproject commit 1a10ef6686a34b7170f52490b7b9841da4476a2c