mastorss/src/mastorss.cpp

165 lines
4.5 KiB
C++
Raw Normal View History

2018-02-10 12:35:06 +01:00
/* This file is part of mastorss.
2019-04-21 04:00:55 +02:00
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
2018-01-26 02:33:58 +01:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <vector>
#include <string>
2018-02-18 14:27:01 +01:00
#include <cstdlib> // getenv()
2018-01-26 02:33:58 +01:00
#include <cstdint>
#include <thread>
#include <chrono>
2018-04-14 13:57:03 +02:00
#include <jsoncpp/json/json.h>
#include <mastodon-cpp/mastodon-cpp.hpp>
2018-08-25 14:29:13 +02:00
#include <mastodon-cpp/easy/all.hpp>
2018-02-10 12:35:06 +01:00
#include "version.hpp"
#include "mastorss.hpp"
2018-01-26 02:33:58 +01:00
2019-04-21 04:00:55 +02:00
using namespace Mastodon;
2018-01-26 02:33:58 +01:00
using std::cout;
using std::cerr;
2018-02-10 12:35:06 +01:00
using std::cin;
2019-04-21 04:00:55 +02:00
using std::endl;
2018-01-26 02:33:58 +01:00
using std::string;
using std::this_thread::sleep_for;
using std::chrono::seconds;
2018-01-26 02:33:58 +01:00
2018-02-18 14:27:01 +01:00
// Initialize global variables
2018-02-06 13:53:34 +01:00
std::uint16_t max_size = 500;
2018-02-10 12:35:06 +01:00
const string filepath = string(getenv("HOME")) + "/.config/mastorss/";
2018-04-14 13:57:03 +02:00
Json::Value config;
2018-03-15 13:20:26 +01:00
std::string profile;
2018-01-26 02:33:58 +01:00
int main(int argc, char *argv[])
{
if (argc < 2)
{
2018-02-01 12:03:16 +01:00
cerr << "usage: " << argv[0] << " <profile> [max size]\n";
return 10;
2018-01-26 02:33:58 +01:00
}
2018-02-01 12:03:16 +01:00
if (argc == 3)
{
2018-02-01 12:03:43 +01:00
max_size = std::stoi(argv[2]);
2018-02-01 12:03:16 +01:00
}
2018-01-26 02:33:58 +01:00
string instance = "";
string access_token = "";
2018-01-26 03:35:52 +01:00
string feedurl = "";
2018-03-15 13:20:26 +01:00
profile = argv[1];
std::uint_fast16_t ret;
2018-01-26 02:33:58 +01:00
string answer;
2018-08-25 14:29:13 +02:00
std::vector<Mastodon::Easy::Status> entries;
2018-03-15 13:20:26 +01:00
read_config(instance, access_token, feedurl);
curlpp_init();
2018-02-10 12:35:06 +01:00
ret = http_get(feedurl, answer, "mastorss/" + (string)global::version);
2018-02-01 12:03:16 +01:00
if (ret != 0)
{
2018-04-29 17:14:48 +02:00
std::cerr << "Error code: " << ret << '\n';
std::cerr << answer << '\n';
2018-02-01 12:03:16 +01:00
return ret;
}
entries = parse_feed(answer);
2018-01-26 02:33:58 +01:00
2018-04-14 14:10:14 +02:00
string last_entry = config[profile]["last_entry"].asString();
2018-01-26 20:59:01 +01:00
if (last_entry.empty())
{
2018-03-15 13:20:26 +01:00
// If no last_entry is stored in the config file,
// make last_entry the second-newest entry.
2018-08-25 14:29:13 +02:00
last_entry = entries.at(1).content();
2018-01-26 20:59:01 +01:00
}
2018-08-25 14:29:13 +02:00
config[profile]["last_entry"] = entries.front().content();
2018-01-26 02:33:58 +01:00
bool new_content = false;
for (auto rit = entries.rbegin(); rit != entries.rend(); ++rit)
{
2018-08-25 14:29:13 +02:00
if (!new_content && (*rit).content().compare(last_entry) == 0)
2018-01-26 02:33:58 +01:00
{
2018-03-15 13:20:26 +01:00
// If the last entry is found in entries,
// start tooting in the next loop.
2018-01-26 02:33:58 +01:00
new_content = true;
continue;
}
else if (!new_content)
{
continue;
}
2019-04-21 04:00:55 +02:00
Easy::return_entity<Easy::Status> ret_status;
Mastodon::Easy::API masto(instance, access_token);
2018-01-26 03:35:52 +01:00
2019-04-21 04:00:55 +02:00
ret_status = masto.send_post(*rit);
2018-01-26 03:35:52 +01:00
2019-04-21 04:00:55 +02:00
if (!ret_status)
2018-01-26 03:35:52 +01:00
{
2019-04-21 04:00:55 +02:00
const uint8_t err = ret_status.error_code;
switch (err)
{
case 110:
{
cerr << "Error " << err << ": Timeout\n";
break;
}
case 111:
{
cerr << "Error " << err << ": Connection refused\n";
cerr << "HTTP Error " << ret_status.http_error_code << endl;
break;
}
case 113:
{
2019-04-21 04:00:55 +02:00
cerr << "Error " << err << ": Could not reach host.\n";
break;
}
case 192:
case 193:
{
cerr << "Error " << err << ": curlpp error\n";
break;
}
default:
{
cerr << "Error " << err << '\n';
cerr << "HTTP status " << ret_status.http_error_code << endl;
}
}
2019-04-21 04:00:55 +02:00
cerr << ret_status.entity.to_string() << '\n';
2018-01-26 03:35:52 +01:00
return ret;
}
2019-04-21 04:00:55 +02:00
if (!ret_status.entity.valid())
{
2019-04-21 04:00:55 +02:00
cerr << "Could not send post for unknown reasons.\n";
cerr << "Please file a bug at "
"<https://schlomp.space/tastytea/mastorss/issues>.\n";
return 1;
}
2018-09-20 05:45:22 +02:00
if (rit != entries.rend())
{ // Only sleep if this is not the last entry
sleep_for(seconds(config[profile]["interval"].asUInt64()));
}
2018-01-26 02:33:58 +01:00
}
2018-03-15 13:20:26 +01:00
// Write the new last_entry only if no error happened.
2018-04-14 13:57:03 +02:00
write_config();
2018-02-18 14:27:01 +01:00
2018-01-26 02:33:58 +01:00
return 0;
}