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

183 lines
4.6 KiB
C++

/* 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 "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>
using namespace FediBlock;
namespace FediBlock
{
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;
vector<entry_type> read_json_files()
{
vector<entry_type> entries;
auto dir_iter{fs::directory_iterator(files::get_tmpdir() / "repo")};
for (const fs::path &path : dir_iter)
{
if (path.filename().string()[0] == '.')
{
continue;
}
if (path.extension() != ".json")
{
continue;
}
ifstream file(path);
if (!file.good())
{
throw runtime_error{"Could not open file: " + path.string()};
}
stringstream ss;
ss << file.rdbuf();
auto entry{json::from_json(ss.str())};
if (!entry.screenshot_filepath.empty())
{
const fs::path sh_path{entry.screenshot_filepath};
entry.screenshot_filepath = path.stem().string() +=
sh_path.extension();
}
entries.push_back(entry);
}
return entries;
}
void write_html(ostream &out, const vector<entry_type> &entries)
{
out << R"(<!doctype html>
<html>
<head>
<title>FediBlock prototype</title>
<meta charset="utf-8">
</head>
<body>
<h1>Blocklist</h1>
)";
for (const auto &entry : entries)
{
out << "\n";
out << " <details>\n";
out << " <summary>" << entry.instance << "</summary>\n";
out << " <p>" << 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 << " <p><strong>Receipts:</strong><br>\n";
for (const auto &receipt : entry.receipts)
{
if (receipt != *(entry.receipts.begin()))
{
out << "<br>\n";
}
out << " <a href=\"" << receipt << "\">" << receipt
<< "</a>";
}
out << "\n </p>\n";
if (!entry.screenshot_filepath.empty())
{
out << " <p><strong>Screenshot:</strong><br>"
<< "<a href=\"" << entry.screenshot_filepath << "\"><img src=\""
<< entry.screenshot_filepath << R"(" height="100"></a></p>)"
<< '\n';
}
out << " </details>\n";
}
out << " </body>\n</html>\n";
}
void copy_screenshots(const fs::path &directory)
{
auto dir_iter{fs::directory_iterator(files::get_tmpdir() / "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
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_libgit2_init();
try
{
git::clone();
const auto entries{read_json_files()};
write_html(cout, entries);
copy_screenshots(target_dir);
}
catch (const exception &e)
{
cerr << "Error: " << e.what() << '\n';
}
files::remove_tmpdir();
git_libgit2_shutdown();
return 0;
}