Use pugixml for RSS generation.
continuous-integration/drone/push Build is failing Details

Makes the whole thing easier to follow and change.
This commit is contained in:
tastytea 2020-10-30 16:59:14 +01:00
parent 0b71b1129d
commit 851eb47987
Signed by: tastytea
GPG Key ID: CFC39497F1B26E07
6 changed files with 71 additions and 71 deletions

View File

@ -26,7 +26,7 @@ steps:
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
- apt-get update -q
- apt-get install -qq build-essential cmake g++-10 clang pkg-config
- apt-get install -qq catch libcgicc-dev nlohmann-json3-dev libgit2-dev libcurl4-openssl-dev libicu-dev libfmt-dev
- apt-get install -qq catch libcgicc-dev nlohmann-json3-dev libgit2-dev libcurl4-openssl-dev libicu-dev libfmt-dev libpugixml-dev
- rm -rf build && mkdir -p build && cd build
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
- make VERBOSE=1
@ -62,7 +62,7 @@ steps:
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
- apt-get update -q
- apt-get install -qq build-essential cmake clang pkg-config
- apt-get install -qq catch libcgicc-dev nlohmann-json-dev libgit2-dev libcurl4-openssl-dev libicu-dev libfmt-dev
- apt-get install -qq catch libcgicc-dev nlohmann-json-dev libgit2-dev libcurl4-openssl-dev libicu-dev libfmt-dev libpugixml-dev
- rm -rf build && mkdir -p build && cd build
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
- make VERBOSE=1
@ -92,7 +92,7 @@ steps:
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
- apt-get update -q
- apt-get install -qq build-essential cmake clang pkg-config
- apt-get install -qq catch libcgicc-dev nlohmann-json-dev libgit2-dev libcurl4-gnutls-dev libicu-dev libfmt-dev
- apt-get install -qq catch libcgicc-dev nlohmann-json-dev libgit2-dev libcurl4-gnutls-dev libicu-dev libfmt-dev libpugixml-dev
- rm -rf build && mkdir -p build && cd build
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
- make VERBOSE=1

View File

@ -43,6 +43,7 @@ pkg_check_modules(libgit2 REQUIRED IMPORTED_TARGET libgit2)
find_package(CURL 7.56 REQUIRED)
find_package(ICU REQUIRED COMPONENTS uc)
find_package(fmt 4 REQUIRED CONFIG)
find_package(pugixml REQUIRED CONFIG)
add_subdirectory(src)
add_subdirectory(src/generators)

View File

@ -44,3 +44,8 @@ FediBlock-backend makes direct use of the following libraries and programs:
From: Victor Zverovich, Jonathan Müller and community
https://fmt.dev/
License: MIT
pugixml
From: Arseny KapoulkineVictor and community
https://pugixml.org/
License: MIT

View File

@ -18,6 +18,7 @@
:uri-libcurl: https://curl.haxx.se/libcurl/
:uri-icu: http://site.icu-project.org/
:uri-fmt: https://github.com/fmtlib/fmt
:uri-pugixml: https://pugixml.org/
*{project}* turns form data into JSON and opens a pull request on
link:https://schlomp.space/FediBlock/data[FediBlock/data]. Also included are
@ -115,6 +116,7 @@ The RSS generator expects the blocklist to be in
* link:{uri-libcurl}[libcurl] (at least: 7.56)
* link:{uri-icu}[ICU] (tested: 67.1 / 60.2)
* link:{uri-fmt}[fmt] (tested: 7.0 / 4.0)
* link:{uri-pugixml}[pugixml] (tested: 1.10 / 1.8)
* Optional
** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.10)
** DEB package: link:{uri-dpkg}[dpkg] (tested: 1.19)

View File

@ -20,7 +20,8 @@ target_link_libraries(fediblock
std::filesystem
PkgConfig::libgit2
ICU::uc
fmt::fmt)
fmt::fmt
pugixml)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
target_link_libraries(fediblock PUBLIC ${CURL_LIBRARIES})

View File

@ -21,6 +21,7 @@
#include "time.hpp"
#include <fmt/format.h>
#include <pugixml.hpp>
#include <algorithm>
#include <chrono>
@ -47,27 +48,6 @@ 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)
{
// clang-format off
const string endtag{[&rsstag]
{
// If there is a space in the rsstag, use only the part up until the
// space for the ending RSS tag.
const size_t pos = rsstag.find(' ');
if (pos == string_view::npos)
{
return rsstag;
}
return rsstag.substr(0, pos);
}()};
// clang-format off
out << string(spaces, ' ');
out << '<' << rsstag << '>' << value << "</" << endtag << ">\n";
}
void write_rss(ostream &out, const vector<entry_type> &entries,
const vector<string> &tags)
{
@ -95,38 +75,43 @@ void write_rss(ostream &out, const vector<entry_type> &entries,
constexpr string_view rss_time_format{"%a, %d %b %Y %T %z"};
out << R"(<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
)";
out << R"( <atom:link href=")" + selfurl
<< R"(" rel="self" type="application/rss+xml"/>)" << '\n';
string title{"FediBlock: "};
string description{"The newest FediBlock entries. "};
pugi::xml_document doc;
auto rss{doc.append_child("rss")};
rss.append_attribute("version") = "2.0";
rss.append_attribute("xmlns:atom") = "http://www.w3.org/2005/Atom";
auto channel{rss.append_child("channel")};
string tmp_title{"FediBlock: "};
string tmp_description{"The newest FediBlock entries. "};
if (tags.empty())
{
title += "All tags";
description += "All tags";
tmp_title += "All tags";
tmp_description += "All tags";
}
else
{
description += "Tags: ";
tmp_description += "Tags: ";
}
for (const auto &tag : tags)
{
if (tag != *tags.begin())
{
title += ", ";
description += ", ";
tmp_title += ", ";
tmp_description += ", ";
}
title += tag;
description += tag;
tmp_title += tag;
tmp_description += tag;
}
description += ".";
write_line(out, 4, "title", title);
write_line(out, 4, "link", baseurl);
write_line(out, 4, "description", description);
write_line(out, 4, "lastBuildDate",
time::to_string(system_clock::now(), rss_time_format));
tmp_description += ".";
auto title{channel.append_child("title")};
title.text() = tmp_title.c_str();
auto link{channel.append_child("link")};
link.text() = baseurl.c_str();
auto description{channel.append_child("description")};
description.text() = tmp_description.c_str();
auto lastBuildDate{channel.append_child("lastBuildDate")};
lastBuildDate.text() = time::to_string(system_clock::now(), rss_time_format)
.c_str();
for (const auto &entry : entries)
{
@ -146,47 +131,53 @@ void write_rss(ostream &out, const vector<entry_type> &entries,
// clang-format on
}
out << " <item>\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));
write_line(out, 6, "link",
format("{:s}#{:s}", baseurl, entry.instance));
auto item{channel.append_child("item")};
auto item_title{item.append_child("title")};
item_title.text() = entry.instance.c_str();
auto item_guid{item.append_child("guid")};
item_guid.append_attribute("isPermaLink") = "false";
item_guid.text() = format("FediBlock: {:s} {:s}", entry.report_time,
entry.instance)
.c_str();
auto item_pubDate{item.append_child("pubDate")};
item_pubDate.text() = time::to_string(entry.report_time,
rss_time_format)
.c_str();
auto item_link{item.append_child("link")};
item_link.text() = format("{:s}#{:s}", baseurl, entry.instance).c_str();
string item_description{format("<p>{:s}</p><p><strong>Tags:</strong> ",
cgi::text2html(entry.description))};
string tmp_item_description{format("<p>{:s}</p>"
"<p><strong>Tags:</strong> ",
cgi::text2html(entry.description))};
for (const auto &tag : entry.tags)
{
if (tag != *entry.tags.begin())
{
item_description += ", ";
tmp_item_description += ", ";
}
item_description += tag;
tmp_item_description += tag;
}
item_description += "</p><strong>Receipts:</strong><ul>";
tmp_item_description += "</p><strong>Receipts:</strong><ul>";
for (const auto &receipt : entry.receipts)
{
item_description +=
format("<li><a href=\"{0:s}\">{0:s}</a></li>", receipt);
tmp_item_description += format(
"<li><a href=\"{0:s}\">{0:s}</a></li>", receipt);
}
item_description += "</ul>";
tmp_item_description += "</ul>";
if (!entry.screenshot_filepath.empty())
{
item_description += "<p><strong>Screenshot:</strong><br>";
item_description +=
format("<a href=\"{0:s}{1:s}\"><img "
"src=\"{0:s}{1:s}\" height=\"200\"></a></p>\n",
baseurl, entry.screenshot_filepath);
tmp_item_description += "<p><strong>Screenshot:</strong><br>";
tmp_item_description += format(
"<a href=\"{0:s}{1:s}\"><img "
"src=\"{0:s}{1:s}\" height=\"200\"></a></p>\n",
baseurl, entry.screenshot_filepath);
}
write_line(out, 6, "description",
format("<![CDATA[{:s}]]>", item_description));
out << " </item>\n";
auto item_description{item.append_child("description")};
item_description.append_child(pugi::node_cdata)
.set_value(tmp_item_description.c_str());
}
out << " </channel>\n</rss>\n";
doc.print(out);
}
} // namespace FediBlock::rss