This repository has been archived on 2021-03-22. You can view files and clone it, but cannot push or open issues or pull requests.
backend/src/generators/html.cpp

206 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* This file is part of FediBlock-backend.
* Copyright © 2020 tastytea <tastytea@tastytea.de>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "html.hpp"
#include "cgi.hpp"
#include "config.hpp"
#include "files.hpp"
#include "fs-compat.hpp"
#include "git.hpp"
#include "json.hpp"
#include <exception>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string_view>
#include <vector>
namespace FediBlock::html
{
using std::cerr;
using std::cout;
using std::exception;
using std::ifstream;
using std::runtime_error;
using std::string_view;
using std::stringstream;
using std::vector;
void write_html(ostream &out, const vector<entry_type> &entries)
{
out << R"(<!doctype html>
<html lang="en">
<head>
<title>FediBlock Blocklist</title>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
<style>
.small
{
font-size: small;
}
img
{
max-height: 10em;
max-width: 40ch;
}
summary
{
font-size: large;
font-weight: bold;
}
details:nth-of-type(even)
{
background-color: #0001;
}
</style>
<link rel="alternate" type="application/rss+xml"
title="The newest FediBlock entries. All tags." href="/rss">
</head>
<body>
<h1>Blocklist</h1>
)";
for (const auto &entry : entries)
{
out << "\n";
out << " <details id=\"" << entry.instance << "\">\n";
out << " <summary>" << entry.report_time.substr(0, 10) << ": "
<< entry.instance << "</summary>\n";
out << R"( <a href="#)" << entry.instance
<< R"(" class="small">Hyperlink to this entry</a>)" << '\n';
out << " <p>" << cgi::text2html(entry.description) << "</p>\n";
out << " <p><strong>Tags:</strong> ";
for (const auto &tag : entry.tags)
{
if (tag != *(entry.tags.begin()))
{
out << ", ";
}
out << tag;
}
out << "</p>\n";
out << " <strong>Receipts:</strong>\n <ul>\n";
for (const auto &receipt : entry.receipts)
{
out << " <li><a href=\"" << receipt << "\">" << receipt
<< "</a></li>\n";
}
out << " </ul>\n";
if (!entry.screenshot_filepath.empty())
{
out << " <p><strong>Screenshot:</strong><br>"
<< "<a href=\"" << entry.screenshot_filepath << "\"><img src=\""
<< entry.screenshot_filepath << R"("></a></p>)" << '\n';
}
out << " </details>\n";
}
out << R"(
<p class="footer" style="text-align: right;">
<a href="https://)"
<< config::forge_domain << "/" << config::forge_org
<< R"(">Sourcecode</a> licensed under the
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL-3.0-only</a>.
</p>
<script>
// Open details when called with ID.
function open_details()
{
const hash = decodeURI(location.hash.substring(1));
if(hash)
{
const details = document.getElementById(hash);
if(details && details.tagName.toLowerCase() === 'details')
{
details.open = true;
}
}
}
window.addEventListener('hashchange', open_details);
open_details();
</script>
</body>
</html>
)";
}
void copy_screenshots(const fs::path &directory)
{
const auto dir_iter{fs::directory_iterator(files::get_cachedir() / "repo")};
for (const fs::path &path : dir_iter)
{
if (path.filename().string()[0] == '.')
{
continue;
}
if (path.extension() == ".json")
{
continue;
}
fs::copy_file(path, directory / path.filename(),
fs::copy_options::skip_existing);
}
}
} // namespace FediBlock::html
using namespace FediBlock;
using namespace FediBlock::html;
int main(int argc, char *argv[])
{
const vector<string_view> args(argv, argv + argc);
if (argc <= 1)
{
cerr << "usage: " << args[0] << " <target directory>\n";
return 1;
}
const string_view target_dir{args[1]};
git::init(true);
bool remove_lockfile{false};
try
{
try
{
git::update_cached_repo();
remove_lockfile = true;
}
catch (const runtime_error &)
{
// Ignore, use old version of repo.
}
const auto entries{files::read_json_files(true)};
write_html(cout, entries);
copy_screenshots(target_dir);
}
catch (const exception &e)
{
cerr << "Error: " << e.what() << '\n';
}
git::cleanup(remove_lockfile);
return 0;
}