Add --dry-run.

Do everything like normal, but don't post anything and don't update the
config file.
This commit is contained in:
tastytea 2020-11-21 20:32:15 +01:00
parent 99a843e0a2
commit dfd32e5bbf
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
4 changed files with 112 additions and 72 deletions

View File

@ -2,7 +2,7 @@
:doctype: manpage
:Author: tastytea
:Email: tastytea@tastytea.de
:Date: 2020-10-29
:Date: 2020-11-21
:Revision: 0.0.0
:man source: mastorss
:man manual: General Commands Manual
@ -22,6 +22,11 @@ support Atom at the moment.
== OPTIONS
*--dry-run*::
Do everything like normal, but don't post anything and don't update the config
file. The initial config file is still created, if the profile doesn't
exist. The interval between posts is set to 1 second.
*--help*::
Show help message.

View File

@ -34,8 +34,13 @@
namespace mastorss
{
using std::cerr;
using std::cout;
using std::runtime_error;
using std::string_view;
using std::chrono::seconds;
using std::this_thread::sleep_for;
namespace error
{
@ -50,6 +55,7 @@ constexpr int unknown = 9;
void print_version();
void print_help(const string_view &command);
int run(string_view profile_name, bool dry_run);
void print_version()
{
@ -67,18 +73,84 @@ void print_help(const string_view &command)
{
cerr << "Usage: " << command << " [--version|--help] <profile>\n";
}
int run(const string_view profile_name, const bool dry_run)
{
const string_view profilename{profile_name};
BOOST_LOG_TRIVIAL(debug) << "Using profile: " << profilename;
try
{
Config cfg{profilename.data()};
Document doc{cfg};
doc.parse();
MastoAPI masto{cfg.profiledata};
if (!doc.new_items.empty())
{
for (const auto &item : doc.new_items)
{
masto.post_item(item, dry_run);
if (item != *doc.new_items.rbegin())
{ // Don't sleep if this is the last item.
if (!dry_run)
{
sleep_for(seconds(cfg.profiledata.interval));
}
else
{
sleep_for(seconds(1));
}
}
}
if (!dry_run)
{
cfg.write();
}
}
}
catch (const FileException &e)
{
cerr << e.what() << '\n';
return error::file;
}
catch (const HTTPException &e)
{
cerr << e.what() << '\n';
return error::network;
}
catch (const CURLException &e)
{
cerr << e.what() << '\n';
return error::network;
}
catch (const Json::RuntimeError &e)
{
cerr << "JSON error:\n" << e.what() << '\n';
return error::json;
}
catch (const ParseException &e)
{
cerr << e.what() << '\n';
return error::parse;
}
catch (const runtime_error &e)
{
cerr << e.what() << '\n';
return error::unknown;
}
return 0;
}
} // namespace mastorss
int main(int argc, char *argv[])
{
using namespace mastorss;
using std::cerr;
using std::getenv;
using std::runtime_error;
using std::string_view;
using std::vector;
using std::chrono::seconds;
using std::this_thread::sleep_for;
const vector<string_view> args(argv, argv + argc);
@ -109,61 +181,13 @@ int main(int argc, char *argv[])
{
print_help(args[0]);
}
else if (args[1] == "--dry-run")
{
return run(args[2], true);
}
else
{
const string_view profilename{args[1]};
BOOST_LOG_TRIVIAL(debug) << "Using profile: " << profilename;
try
{
Config cfg{profilename.data()};
Document doc{cfg};
doc.parse();
MastoAPI masto{cfg.profiledata};
if (!doc.new_items.empty())
{
for (const auto &item : doc.new_items)
{
masto.post_item(item);
if (item != *doc.new_items.rbegin())
{ // Don't sleep if this is the last item.
sleep_for(seconds(cfg.profiledata.interval));
}
}
cfg.write();
}
}
catch (const FileException &e)
{
cerr << e.what() << '\n';
return error::file;
}
catch (const HTTPException &e)
{
cerr << e.what() << '\n';
return error::network;
}
catch (const CURLException &e)
{
cerr << e.what() << '\n';
return error::network;
}
catch (const Json::RuntimeError &e)
{
cerr << "JSON error:\n" << e.what() << '\n';
return error::json;
}
catch (const ParseException &e)
{
cerr << e.what() << '\n';
return error::parse;
}
catch (const runtime_error &e)
{
cerr << e.what() << '\n';
return error::unknown;
}
return run(args[1], false);
}
}

View File

@ -21,6 +21,7 @@
#include <boost/log/trivial.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <string>
#include <string_view>
@ -36,7 +37,7 @@ MastoAPI::MastoAPI(ProfileData &data)
, _instance{_profile.instance, _profile.access_token}
{}
void MastoAPI::post_item(const Item &item)
void MastoAPI::post_item(const Item &item, bool dry_run)
{
string title = replacements_apply(item.title);
string link = replacements_apply(item.link);
@ -109,21 +110,31 @@ void MastoAPI::post_item(const Item &item)
BOOST_LOG_TRIVIAL(debug) << "Status length: " << status.size();
BOOST_LOG_TRIVIAL(debug) << "Status: \"" << status << '"';
mastodonpp::parametermap params{{"status", status}};
if (_profile.titles_as_cw)
if (!dry_run)
{
params.insert({"spoiler_text", title});
}
mastodonpp::Connection connection{_instance};
const auto ret = connection.post(mastodonpp::API::v1::statuses, params);
if (!ret)
{
if (ret.http_status != 200)
mastodonpp::parametermap params{{"status", status}};
if (_profile.titles_as_cw)
{
throw HTTPException{ret.http_status};
params.insert({"spoiler_text", title});
}
throw CURLException{ret.curl_error_code};
mastodonpp::Connection connection{_instance};
const auto ret = connection.post(mastodonpp::API::v1::statuses, params);
if (!ret)
{
if (ret.http_status != 200)
{
throw HTTPException{ret.http_status};
}
throw CURLException{ret.curl_error_code};
}
}
else
{
using std::cout;
cout << " WOULD POST: \n";
cout << "Subject: " << title << '\n';
cout << "Status:\n" << status << '\n';
}
BOOST_LOG_TRIVIAL(debug) << "Posted status with GUID: " << item.guid;

View File

@ -33,7 +33,7 @@ class MastoAPI
public:
explicit MastoAPI(ProfileData &data);
void post_item(const Item &item);
void post_item(const Item &item, bool dry_run);
private:
ProfileData &_profile;