Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1#include <haio_cdn.hpp>
2#include <haio_cli.hpp>
3
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>
8
9#include <cstdlib>
10#include <filesystem>
11#include <fstream>
12#include <iostream>
13
14namespace {
15
16int cdnCommand(int argc, char* argv[]) {
17 std::filesystem::path configPath;
18
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");
23 configPath = arg;
24 }
25
26 Haio::Cdn::Config config;
27 if (!configPath.empty()) {
28 config = Haio::Cdn::loadConfig(configPath);
29 } else if (const char* inlineToml = std::getenv("HAIO_CDN_TOML")) {
30 config = Haio::Cdn::parseConfig(inlineToml);
31 } else {
32 throw std::runtime_error("cdn needs a config file, or HAIO_CDN_TOML holding the config itself");
33 }
34
35 boost::asio::io_context io;
36 boost::asio::signal_set signals(io, SIGINT, SIGTERM);
37 signals.async_wait([&](auto, auto) { io.stop(); });
38 boost::asio::co_spawn(io, Haio::Cdn::runServer(std::move(config)), boost::asio::detached);
39 io.run();
40 return 0;
41}
42
43int probeCommand(int argc, char* argv[]) {
44 if (argc < 2) {
45 std::cerr << "usage: haio probe <file>...\n";
46 return 1;
47 }
48
49 int failures = 0;
50 for (int i = 1; i < argc; i++) {
51 const std::filesystem::path path = argv[i];
52 std::ifstream in(path, std::ios::binary);
53 if (!in) {
54 std::cerr << path.string() << ": cannot open\n";
55 failures++;
56 continue;
57 }
58
59 const std::vector<uint8_t> data((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
60 const auto found = Haio::Detect(data);
61
62 std::cout << path.string() << ": ";
63 if (!found) {
64 std::cout << "unrecognised";
65 } else {
66 std::cout << Haio::formatName(found.format) << ' ' << Haio::colorName(found.color);
67 const Haio::Blob blob{found.format, found.color, std::string(Haio::contentTypeFor(found.format)), path.string(), data};
68 if (const auto image = Haio::Decode(blob); image) {
69 std::cout << ' ' << image->width << 'x' << image->height;
70 }
71 // without a decoder the name is all we can report
72 }
73 std::cout << ", " << data.size() << " bytes";
74
75 const auto fromName = Haio::formatFromExtension(path.string());
76 if (fromName != Haio::Format::RAW && fromName != found.format) {
77 std::cout << " [extension says " << Haio::formatName(fromName) << ']';
78 failures++;
79 }
80 std::cout << '\n';
81 }
82
83 return failures == 0 ? 0 : 1;
84}
85
86void printHelp() {
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"
91 << "\nconfig.toml:\n"
92 << " host = \"0.0.0.0\"\n"
93 << " port = 8080\n"
94 << "\n"
95 << " cache = \"mem://?ttl=1h&max=5mb\" also file://dir and redis://host\n"
96 << "\n"
97 << " [bucket.assets]\n"
98 << " url = \"file://assets\"\n";
99}
100
101}
102
103auto main(int argc, char* argv[]) -> int {
104 try {
105 if (argc < 2) {
106 printHelp();
107 return 1;
108 }
109
110 const std::string_view command = argv[1];
111 if (command == "convert") return Haio::Cli::runCli(argc - 1, 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") {
115 printHelp();
116 return 0;
117 }
118
119 std::cerr << "unknown command: " << command << "\n";
120 printHelp();
121 return 1;
122 } catch (const std::exception& err) {
123 std::cerr << "error: " << err.what() << "\n";
124 return 1;
125 }
126}
auto main(int argc, char *argv[]) -> int
Definition main.cpp:103
boost::asio::awaitable< void > runServer(Config config)
Definition server.cpp:431
Config parseConfig(std::string_view text)
Definition config.cpp:190
Config loadConfig(const std::filesystem::path &path)
Definition config.cpp:287
int runCli(int argc, char *argv[])
Definition cli.cpp:109
Found Detect(Bytes data)
Format formatFromExtension(std::string_view path)
Definition format.cpp:33
constexpr std::string_view formatName(Format wanted)
Result< Image< Color::RGBA8888 > > Decode(const Blob &blob)
std::string_view contentTypeFor(Format format)
Definition format.cpp:62
constexpr std::string_view colorName(Color wanted)