diff --git a/CMakeLists.txt b/CMakeLists.txt index b4c3e16..80f2efe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "The type of build.") option(BUILD_SHARED_LIBS "Build shared libraries." YES) project (mastorss - VERSION 0.11.1 + VERSION 0.12.0 DESCRIPTION "Another RSS to Mastodon bot." LANGUAGES CXX) diff --git a/man/mastorss.1.adoc b/man/mastorss.1.adoc index 556a107..3cbabab 100644 --- a/man/mastorss.1.adoc +++ b/man/mastorss.1.adoc @@ -2,7 +2,7 @@ :doctype: manpage :Author: tastytea :Email: tastytea@tastytea.de -:Date: 2020-01-16 +:Date: 2020-05-10 :Revision: 0.0.0 :man source: mastorss :man manual: General Commands Manual @@ -90,6 +90,11 @@ content warning) of the post. *titles_only*:: If true, only post titles, no descriptions. +*replacements*:: +Object with a list of regular expressions and replacements. Applies to posts, +subjects and links, but not to the string in _append_. For information about the +syntax see *perlre*(1). + == EXAMPLES === Configuration file @@ -117,7 +122,12 @@ If true, only post titles, no descriptions. "Skip me too!" ], "titles_as_cw" : true, - "titles_only" : false + "titles_only" : false, + "replacements" : + { + "apple" : "strawberry", + "(chest|wal)nut" : "hazelnut" + } } } -------------------------------------------------------------------------------- diff --git a/src/config.cpp b/src/config.cpp index 3b79f59..56b3eda 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,5 +1,5 @@ /* This file is part of mastorss. - * Copyright © 2019 tastytea + * Copyright © 2019, 2020 tastytea * * 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 @@ -80,7 +80,18 @@ std::ostream &operator <<(std::ostream &out, const ProfileData &data) } out << "], " << "titles_as_cw: " << data.titles_as_cw << ", " - << "titles_only: " << data.titles_only; + << "titles_only: " << data.titles_only << ", "; + out << "replacements: ["; + for (const auto &replacement : data.replacements) + { + out << '"' << replacement.first << "\": \"" + << replacement.second << '"'; + if (replacement != *data.replacements.rbegin()) + { + out << ", "; + } + } + out << "]"; return out; } @@ -238,6 +249,11 @@ void Config::parse() profiledata.skip = jsonarray_to_stringlist(_json[profile]["skip"]); profiledata.titles_as_cw = _json[profile]["titles_as_cw"].asBool(); profiledata.titles_only = _json[profile]["titles_only"].asBool(); + for (const auto &search : _json[profile]["replacements"].getMemberNames()) + { + profiledata.replacements.push_back({search, + _json[profile]["replacements"][search].asString()}); + } BOOST_LOG_TRIVIAL(debug) << "Read config: " << profiledata; } @@ -257,6 +273,10 @@ void Config::write() _json[profile]["skip"] = stringlist_to_jsonarray(profiledata.skip); _json[profile]["titles_as_cw"] = profiledata.titles_as_cw; _json[profile]["titles_only"] = profiledata.titles_only; + for (const auto &replacement : profiledata.replacements) + { + _json[profile]["replacements"][replacement.first] = replacement.second; + } ofstream file{get_filename().c_str()}; if (file.good()) diff --git a/src/config.hpp b/src/config.hpp index 59a0543..dcb567e 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -1,5 +1,5 @@ /* This file is part of mastorss. - * Copyright © 2019 tastytea + * Copyright © 2019, 2020 tastytea * * 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 @@ -24,6 +24,7 @@ #include #include #include +#include namespace mastorss { @@ -32,6 +33,7 @@ using std::uint32_t; using std::list; using std::string; using std::string_view; +using std::pair; /*! * @brief The configuration for a profile as data structure. @@ -52,6 +54,7 @@ struct ProfileData list skip; bool titles_as_cw{false}; bool titles_only{false}; + list> replacements; friend std::ostream &operator <<(std::ostream &out, const ProfileData &data); diff --git a/src/mastoapi.cpp b/src/mastoapi.cpp index 5a39fd6..fb2543c 100644 --- a/src/mastoapi.cpp +++ b/src/mastoapi.cpp @@ -1,5 +1,5 @@ /* This file is part of mastorss. - * Copyright © 2019 tastytea + * Copyright © 2019, 2020 tastytea * * 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 @@ -18,12 +18,15 @@ #include "mastoapi.hpp" #include +#include #include #include namespace mastorss { +using boost::regex; +using boost::regex_replace; using std::string; using std::string_view; @@ -35,6 +38,9 @@ MastoAPI::MastoAPI(ProfileData &data) void MastoAPI::post_item(const Item &item) { + string title = replacements_apply(item.title); + string link = replacements_apply(item.link); + string status{[&] { if (_profile.titles_as_cw) @@ -43,13 +49,13 @@ void MastoAPI::post_item(const Item &item) { return string{}; } - return item.description; + return replacements_apply(item.description); } - string s{item.title}; + string s{title}; if (!_profile.titles_only) { - s.append("\n\n" + item.description); + s.append("\n\n" + replacements_apply(item.description)); } return s; }()}; @@ -62,20 +68,19 @@ void MastoAPI::post_item(const Item &item) } return _profile.append.size() + 2; }()}; - const size_t len_status{status.size()}; const size_t len_max{[&] { if (_profile.titles_as_cw) { // Subjects (CWs) count into the post length. - return _profile.max_size - item.title.size(); + return _profile.max_size - title.size(); } return _profile.max_size; - }() - item.link.size() - 2 - len_append}; + }() - link.size() - 2 - len_append}; BOOST_LOG_TRIVIAL(debug) << "Maximum text (without link and appendix) length: " << len_max; - if (len_status > len_max) + if (status.size() > len_max) { constexpr string_view omission = " […]"; status.resize(len_max - omission.size()); @@ -91,7 +96,7 @@ void MastoAPI::post_item(const Item &item) BOOST_LOG_TRIVIAL(debug) << "Status resized to: " << status.size(); } - status.append("\n\n" + item.link); + status.append("\n\n" + link); if (!_profile.append.empty()) { @@ -103,7 +108,7 @@ void MastoAPI::post_item(const Item &item) mastodonpp::parametermap params{{"status", status}}; if (_profile.titles_as_cw) { - params.insert({"spoiler_text", item.title}); + params.insert({"spoiler_text", title}); } mastodonpp::Connection connection{_instance}; @@ -124,4 +129,14 @@ void MastoAPI::post_item(const Item &item) _profile.guids.pop_front(); } } + +string MastoAPI::replacements_apply(const string &text) +{ + string out = text; + for (const auto &replacement : _profile.replacements) + { + out = regex_replace(out, regex{replacement.first}, replacement.second); + } + return out; +} } // namespace mastorss diff --git a/src/mastoapi.hpp b/src/mastoapi.hpp index 63775cc..2c5653a 100644 --- a/src/mastoapi.hpp +++ b/src/mastoapi.hpp @@ -1,5 +1,5 @@ /* This file is part of mastorss. - * Copyright © 2019 tastytea + * Copyright © 2019, 2020 tastytea * * 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 @@ -22,8 +22,12 @@ #include +#include + namespace mastorss { +using std::string; + class MastoAPI { public: @@ -35,6 +39,8 @@ private: ProfileData &_profile; mastodonpp::Instance _instance; constexpr static size_t _max_guids{100}; + + string replacements_apply(const string &text); }; } // namespace mastorss