/* This file is part of FediBlock-backend. * Copyright © 2020 tastytea * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include "rss.hpp" #include "files.hpp" #include "git.hpp" #include "time.hpp" #include #include #include #include #include #include #include #include #include #include namespace FediBlock::rss { using std::find; using std::getenv; using std::none_of; using std::ostream; using std::string; using std::string_view; using std::uint8_t; using std::chrono::system_clock; void write_line(ostream &out, const uint8_t spaces, const string_view rsstag, const string_view value) { string endtag; // If there is a space in the rsstag, use only the part up until the space // for the ending rsstag. const size_t pos = rsstag.find(' '); if (pos == string_view::npos) { endtag = rsstag; } else { endtag = rsstag.substr(0, pos); } out << string(spaces, ' '); out << '<' << rsstag << '>' << value << "\n"; } void write_rss(ostream &out, const vector &entries, const vector &tags) { string selfurl; char *env{getenv("HTTPS")}; if (env == nullptr || string(env) != "on") { selfurl = "http://"; } else { selfurl = "https://"; } env = getenv("SERVER_NAME"); if (env != nullptr) { selfurl += env; } const string baseurl{selfurl + "/blocklist/"}; env = getenv("REQUEST_URI"); if (env != nullptr) { selfurl += env; } constexpr string_view blocklist_url{ "https://fediblock-test.tastytea.de/blocklist/"}; constexpr string_view rss_time_format{"%a, %d %b %Y %T %z"}; out << R"( )"; out << R"( )" << '\n'; write_line(out, 4, "title", "FediBlock: newest entries"); write_line(out, 4, "link", blocklist_url); string description; if (tags.empty()) { description = "All tags."; } else { description = "Tags: "; } for (const auto &tag : tags) { if (tag == *(tags.begin())) { description += ", "; } description += tag; } write_line(out, 4, "description", description); write_line(out, 4, "lastBuildDate", time::to_string(system_clock::now(), rss_time_format)); for (const auto &entry : entries) { // If tags are specified and none of them match, go to the next entry. if (!tags.empty()) { // clang-format off if (none_of(entry.tags.begin(), entry.tags.end(), [&tags](const auto &tag) { return find(tags.begin(), tags.end(), tag) != tags.end(); })) { continue; } // clang-format on } out << " \n"; write_line(out, 6, "title", entry.instance); write_line(out, 6, "guid isPermaLink=\"false\"", "FediBlock: " + entry.report_time + " " + entry.instance); write_line(out, 6, "pubDate", time::to_string(entry.report_time, rss_time_format)); string item_description{"

" + entry.description + "

"}; item_description += "

Tags: "; for (const auto &tag : entry.tags) { if (tag != *(entry.tags.begin())) { item_description += ", "; } item_description += tag; } item_description += "

"; item_description += "

Receipts: "; for (const auto &receipt : entry.receipts) { if (receipt != *(entry.receipts.begin())) { item_description += "
"; } ((((item_description += "") += receipt) += ""; } item_description += "

"; if (!entry.screenshot_filepath.empty()) { item_description += "

Screenshot:
"; ((item_description += "

)") += '\n'; } write_line(out, 6, "description", ""); out << "
\n"; } out << "
\n
\n"; } } // namespace FediBlock::rss using std::cerr; using std::cout; using std::exception; using std::string_view; using std::vector; using namespace FediBlock; using namespace FediBlock::rss; int main(int argc, char *argv[]) { const vector args(argv, argv + argc); git_libgit2_init(); try { git::clone(); const auto entries{files::read_json_files()}; write_rss(cout, entries, {}); } catch (const exception &e) { cerr << "Error: " << e.what() << '\n'; } files::remove_tmpdir(); git_libgit2_shutdown(); return 0; }