Use pugixml for RSS generation.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
Makes the whole thing easier to follow and change.
This commit is contained in:
parent
0b71b1129d
commit
851eb47987
|
@ -26,7 +26,7 @@ steps:
|
||||||
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
||||||
- apt-get update -q
|
- apt-get update -q
|
||||||
- apt-get install -qq build-essential cmake g++-10 clang pkg-config
|
- 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
|
- rm -rf build && mkdir -p build && cd build
|
||||||
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
||||||
- make VERBOSE=1
|
- make VERBOSE=1
|
||||||
|
@ -62,7 +62,7 @@ steps:
|
||||||
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
||||||
- apt-get update -q
|
- apt-get update -q
|
||||||
- apt-get install -qq build-essential cmake clang pkg-config
|
- 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
|
- rm -rf build && mkdir -p build && cd build
|
||||||
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
||||||
- make VERBOSE=1
|
- make VERBOSE=1
|
||||||
|
@ -92,7 +92,7 @@ steps:
|
||||||
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
- alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get'
|
||||||
- apt-get update -q
|
- apt-get update -q
|
||||||
- apt-get install -qq build-essential cmake clang pkg-config
|
- 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
|
- rm -rf build && mkdir -p build && cd build
|
||||||
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
- cmake -G "Unix Makefiles" -DWITH_TESTS=YES ..
|
||||||
- make VERBOSE=1
|
- make VERBOSE=1
|
||||||
|
|
|
@ -43,6 +43,7 @@ pkg_check_modules(libgit2 REQUIRED IMPORTED_TARGET libgit2)
|
||||||
find_package(CURL 7.56 REQUIRED)
|
find_package(CURL 7.56 REQUIRED)
|
||||||
find_package(ICU REQUIRED COMPONENTS uc)
|
find_package(ICU REQUIRED COMPONENTS uc)
|
||||||
find_package(fmt 4 REQUIRED CONFIG)
|
find_package(fmt 4 REQUIRED CONFIG)
|
||||||
|
find_package(pugixml REQUIRED CONFIG)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(src/generators)
|
add_subdirectory(src/generators)
|
||||||
|
|
5
CREDITS
5
CREDITS
|
@ -44,3 +44,8 @@ FediBlock-backend makes direct use of the following libraries and programs:
|
||||||
From: Victor Zverovich, Jonathan Müller and community
|
From: Victor Zverovich, Jonathan Müller and community
|
||||||
https://fmt.dev/
|
https://fmt.dev/
|
||||||
License: MIT
|
License: MIT
|
||||||
|
|
||||||
|
pugixml
|
||||||
|
From: Arseny KapoulkineVictor and community
|
||||||
|
https://pugixml.org/
|
||||||
|
License: MIT
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
:uri-libcurl: https://curl.haxx.se/libcurl/
|
:uri-libcurl: https://curl.haxx.se/libcurl/
|
||||||
:uri-icu: http://site.icu-project.org/
|
:uri-icu: http://site.icu-project.org/
|
||||||
:uri-fmt: https://github.com/fmtlib/fmt
|
:uri-fmt: https://github.com/fmtlib/fmt
|
||||||
|
:uri-pugixml: https://pugixml.org/
|
||||||
|
|
||||||
*{project}* turns form data into JSON and opens a pull request on
|
*{project}* turns form data into JSON and opens a pull request on
|
||||||
link:https://schlomp.space/FediBlock/data[FediBlock/data]. Also included are
|
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-libcurl}[libcurl] (at least: 7.56)
|
||||||
* link:{uri-icu}[ICU] (tested: 67.1 / 60.2)
|
* link:{uri-icu}[ICU] (tested: 67.1 / 60.2)
|
||||||
* link:{uri-fmt}[fmt] (tested: 7.0 / 4.0)
|
* link:{uri-fmt}[fmt] (tested: 7.0 / 4.0)
|
||||||
|
* link:{uri-pugixml}[pugixml] (tested: 1.10 / 1.8)
|
||||||
* Optional
|
* Optional
|
||||||
** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.10)
|
** Tests: link:{uri-catch}[Catch] (tested: 2.5 / 1.10)
|
||||||
** DEB package: link:{uri-dpkg}[dpkg] (tested: 1.19)
|
** DEB package: link:{uri-dpkg}[dpkg] (tested: 1.19)
|
||||||
|
|
|
@ -20,7 +20,8 @@ target_link_libraries(fediblock
|
||||||
std::filesystem
|
std::filesystem
|
||||||
PkgConfig::libgit2
|
PkgConfig::libgit2
|
||||||
ICU::uc
|
ICU::uc
|
||||||
fmt::fmt)
|
fmt::fmt
|
||||||
|
pugixml)
|
||||||
|
|
||||||
if(${CMAKE_VERSION} VERSION_LESS 3.12)
|
if(${CMAKE_VERSION} VERSION_LESS 3.12)
|
||||||
target_link_libraries(fediblock PUBLIC ${CURL_LIBRARIES})
|
target_link_libraries(fediblock PUBLIC ${CURL_LIBRARIES})
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "time.hpp"
|
#include "time.hpp"
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -47,27 +48,6 @@ using std::string_view;
|
||||||
using std::uint8_t;
|
using std::uint8_t;
|
||||||
using std::chrono::system_clock;
|
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,
|
void write_rss(ostream &out, const vector<entry_type> &entries,
|
||||||
const vector<string> &tags)
|
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"};
|
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">
|
pugi::xml_document doc;
|
||||||
<channel>
|
auto rss{doc.append_child("rss")};
|
||||||
)";
|
rss.append_attribute("version") = "2.0";
|
||||||
out << R"( <atom:link href=")" + selfurl
|
rss.append_attribute("xmlns:atom") = "http://www.w3.org/2005/Atom";
|
||||||
<< R"(" rel="self" type="application/rss+xml"/>)" << '\n';
|
|
||||||
string title{"FediBlock: "};
|
auto channel{rss.append_child("channel")};
|
||||||
string description{"The newest FediBlock entries. "};
|
string tmp_title{"FediBlock: "};
|
||||||
|
string tmp_description{"The newest FediBlock entries. "};
|
||||||
if (tags.empty())
|
if (tags.empty())
|
||||||
{
|
{
|
||||||
title += "All tags";
|
tmp_title += "All tags";
|
||||||
description += "All tags";
|
tmp_description += "All tags";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
description += "Tags: ";
|
tmp_description += "Tags: ";
|
||||||
}
|
}
|
||||||
for (const auto &tag : tags)
|
for (const auto &tag : tags)
|
||||||
{
|
{
|
||||||
if (tag != *tags.begin())
|
if (tag != *tags.begin())
|
||||||
{
|
{
|
||||||
title += ", ";
|
tmp_title += ", ";
|
||||||
description += ", ";
|
tmp_description += ", ";
|
||||||
}
|
}
|
||||||
title += tag;
|
tmp_title += tag;
|
||||||
description += tag;
|
tmp_description += tag;
|
||||||
}
|
}
|
||||||
description += ".";
|
tmp_description += ".";
|
||||||
write_line(out, 4, "title", title);
|
auto title{channel.append_child("title")};
|
||||||
write_line(out, 4, "link", baseurl);
|
title.text() = tmp_title.c_str();
|
||||||
write_line(out, 4, "description", description);
|
auto link{channel.append_child("link")};
|
||||||
write_line(out, 4, "lastBuildDate",
|
link.text() = baseurl.c_str();
|
||||||
time::to_string(system_clock::now(), rss_time_format));
|
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)
|
for (const auto &entry : entries)
|
||||||
{
|
{
|
||||||
|
@ -146,47 +131,53 @@ void write_rss(ostream &out, const vector<entry_type> &entries,
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " <item>\n";
|
auto item{channel.append_child("item")};
|
||||||
write_line(out, 6, "title", entry.instance);
|
auto item_title{item.append_child("title")};
|
||||||
write_line(out, 6, "guid isPermaLink=\"false\"",
|
item_title.text() = entry.instance.c_str();
|
||||||
"FediBlock: " + entry.report_time + " " + entry.instance);
|
auto item_guid{item.append_child("guid")};
|
||||||
write_line(out, 6, "pubDate",
|
item_guid.append_attribute("isPermaLink") = "false";
|
||||||
time::to_string(entry.report_time, rss_time_format));
|
item_guid.text() = format("FediBlock: {:s} {:s}", entry.report_time,
|
||||||
write_line(out, 6, "link",
|
entry.instance)
|
||||||
format("{:s}#{:s}", baseurl, 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> ",
|
string tmp_item_description{format("<p>{:s}</p>"
|
||||||
cgi::text2html(entry.description))};
|
"<p><strong>Tags:</strong> ",
|
||||||
|
cgi::text2html(entry.description))};
|
||||||
for (const auto &tag : entry.tags)
|
for (const auto &tag : entry.tags)
|
||||||
{
|
{
|
||||||
if (tag != *entry.tags.begin())
|
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)
|
for (const auto &receipt : entry.receipts)
|
||||||
{
|
{
|
||||||
item_description +=
|
tmp_item_description += format(
|
||||||
format("<li><a href=\"{0:s}\">{0:s}</a></li>", receipt);
|
"<li><a href=\"{0:s}\">{0:s}</a></li>", receipt);
|
||||||
}
|
}
|
||||||
item_description += "</ul>";
|
tmp_item_description += "</ul>";
|
||||||
if (!entry.screenshot_filepath.empty())
|
if (!entry.screenshot_filepath.empty())
|
||||||
{
|
{
|
||||||
item_description += "<p><strong>Screenshot:</strong><br>";
|
tmp_item_description += "<p><strong>Screenshot:</strong><br>";
|
||||||
item_description +=
|
tmp_item_description += format(
|
||||||
format("<a href=\"{0:s}{1:s}\"><img "
|
"<a href=\"{0:s}{1:s}\"><img "
|
||||||
"src=\"{0:s}{1:s}\" height=\"200\"></a></p>\n",
|
"src=\"{0:s}{1:s}\" height=\"200\"></a></p>\n",
|
||||||
baseurl, entry.screenshot_filepath);
|
baseurl, entry.screenshot_filepath);
|
||||||
}
|
}
|
||||||
write_line(out, 6, "description",
|
auto item_description{item.append_child("description")};
|
||||||
format("<![CDATA[{:s}]]>", item_description));
|
item_description.append_child(pugi::node_cdata)
|
||||||
|
.set_value(tmp_item_description.c_str());
|
||||||
out << " </item>\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " </channel>\n</rss>\n";
|
doc.print(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace FediBlock::rss
|
} // namespace FediBlock::rss
|
||||||
|
|
Reference in New Issue