4#include <boost/asio/co_spawn.hpp>
5#include <boost/asio/detached.hpp>
6#include <boost/asio/io_context.hpp>
7#include <boost/asio/signal_set.hpp>
16int cdnCommand(
int argc,
char* argv[]) {
17 std::filesystem::path configPath;
19 for (
int i = 1; i < argc; i++) {
20 const std::string_view
arg = argv[i];
21 if (
arg.starts_with(
'-'))
throw std::runtime_error(
"unknown cdn option: " + std::string(arg));
22 if (!configPath.empty())
throw std::runtime_error(
"cdn takes a single config file");
27 if (!configPath.empty()) {
29 }
else if (
const char* inlineToml = std::getenv(
"HAIO_CDN_TOML")) {
32 throw std::runtime_error(
"cdn needs a config file, or HAIO_CDN_TOML holding the config itself");
35 boost::asio::io_context io;
36 boost::asio::signal_set signals(io, SIGINT, SIGTERM);
37 signals.async_wait([&](
auto,
auto) { io.stop(); });
43int probeCommand(
int argc,
char* argv[]) {
45 std::cerr <<
"usage: haio probe <file>...\n";
50 for (
int i = 1; i < argc; i++) {
51 const std::filesystem::path path = argv[i];
52 std::ifstream in(path, std::ios::binary);
54 std::cerr << path.string() <<
": cannot open\n";
59 const std::vector<uint8_t> data((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
62 std::cout << path.string() <<
": ";
64 std::cout <<
"unrecognised";
69 std::cout <<
' ' << image->width <<
'x' << image->height;
73 std::cout <<
", " << data.size() <<
" bytes";
83 return failures == 0 ? 0 : 1;
87 std::cout <<
"usage:\n"
88 <<
" haio convert <input> [filters] <output>\n"
89 <<
" haio cdn [config.toml] without a file, reads HAIO_CDN_TOML\n"
90 <<
" haio probe <file>... report what the bytes actually are\n"
92 <<
" host = \"0.0.0.0\"\n"
95 <<
" cache = \"mem://?ttl=1h&max=5mb\" also file://dir and redis://host\n"
97 <<
" [bucket.assets]\n"
98 <<
" url = \"file://assets\"\n";
103auto main(
int argc,
char* argv[]) ->
int {
110 const std::string_view command = argv[1];
112 if (command ==
"cdn")
return cdnCommand(argc - 1, argv + 1);
113 if (command ==
"probe")
return probeCommand(argc - 1, argv + 1);
114 if (command ==
"help" || command ==
"--help" || command ==
"-h") {
119 std::cerr <<
"unknown command: " << command <<
"\n";
122 }
catch (
const std::exception& err) {
123 std::cerr <<
"error: " << err.what() <<
"\n";
auto main(int argc, char *argv[]) -> int
boost::asio::awaitable< void > runServer(Config config)
Config parseConfig(std::string_view text)
Config loadConfig(const std::filesystem::path &path)
int runCli(int argc, char *argv[])
Format formatFromExtension(std::string_view path)
constexpr std::string_view formatName(Format wanted)
Result< Image< Color::RGBA8888 > > Decode(const Blob &blob)
std::string_view contentTypeFor(Format format)
constexpr std::string_view colorName(Color wanted)