Moved TRMNL stuff to its own file

This commit is contained in:
2026-06-22 18:11:31 +03:00
parent fe8346925a
commit 23e2fbd995
7 changed files with 373 additions and 162 deletions

200
main.cpp
View File

@@ -12,149 +12,18 @@
#include "json.hpp"
#include "helpers.h"
#include "TRMNL.h"
using nlohmann::json;
using namespace std;
struct device
{
string id;
string api_key;
string friendly_id;
int refresh_rate;
// Default constructor
device()
: id(""),
api_key(""),
friendly_id(""),
refresh_rate(600)
{}
};
void to_json(json& j, const device& d)
{
j = json{
{"ID", d.id},
{"api_key", d.api_key},
{"friendly_id", d.friendly_id},
{"refresh_rate", d.refresh_rate}
};
}
bool json_extract(const json& j, const string& key, device& out)
{
bool result = false;
if (!key.empty())
{
if (j.contains(key) && j[key].is_object())
{
result |= json_extract(j[key], "ID", out.id);
result |= json_extract(j[key], "api_key", out.api_key);
result |= json_extract(j[key], "friendly_id", out.friendly_id);
result |= json_extract(j[key], "refresh_rate", out.refresh_rate);
}
}
else
{
result |= json_extract(j, "ID", out.id);
result |= json_extract(j, "api_key", out.api_key);
result |= json_extract(j, "friendly_id", out.friendly_id);
result |= json_extract(j, "refresh_rate", out.refresh_rate);
}
return result;
}
string device_id_to_friendly(string id)
{
size_t pos = id.find(':');
while (pos != string::npos)
{
id.erase(pos, 1);
pos = id.find(':');
}
if (id.size() <= 6)
{
return id;
}
else
{
return id.substr(id.size() - 6);
}
}
class DeviceContainer
{
private:
list<device> m_devices;
map<string, list<device>::iterator> m_by_id;
map<string, list<device>::iterator> m_by_friendly;
public:
DeviceContainer() = default;
void add_device(const device& d)
{
if (d.id.empty())
{
return;
}
auto it = m_devices.insert(m_devices.end(), d);
m_by_id.insert(make_pair(it->id, it));
if (!it->friendly_id.empty())
{
m_by_friendly.insert(make_pair(it->friendly_id, it));
}
}
const device* get_device_by_id(const string& id)
{
if (0 == m_by_id.count(id))
{
return nullptr;
}
else
{
return &(*(*(m_by_id.find(id))).second);
}
}
const device* get_device_by_friendly(const string& friendly)
{
if (0 == m_by_friendly.count(friendly))
{
return nullptr;
}
else
{
return &(*(*(m_by_friendly.find(friendly))).second);
}
}
void set_device_friendly(const string& id, const string& friendly)
{
if (0 == m_by_id.count(id))
{
return;
}
auto it = m_by_id[id];
it->friendly_id = friendly;
m_by_friendly.insert(make_pair(it->friendly_id, it));
}
};
int main(int argc, char **argv)
{
string config_filename = "config.json";
string devices_filename = "devices.json";
string host = "";
string folder_images = "images";
string cert_file = "";
string key_file = "";
uint16_t port = 0;
@@ -163,8 +32,7 @@ int main(int argc, char **argv)
bool ok;
json cfg;
json devs;
vector<device> devices;
DeviceContainer container;
TRMNLContainer container;
if (argc > 2)
{
@@ -210,30 +78,29 @@ int main(int argc, char **argv)
return -1;
}
if (devs.is_array())
{
for (int i = 0; i < devs.size(); ++i)
{
device d;
json_extract(devs[i], "", d);
devices.push_back(d);
}
}
container.clear();
container = devs;
for (auto device : devices)
{
container.add_device(device);
}
auto setup_handler = [&container](const httplib::Request& req, httplib::Response& res)
auto setup_handler = [&container, &devices_filename](const httplib::Request& req, httplib::Response& res)
{
if (req.has_header("ID"))
{
json response;
string id = req.get_header_value("ID");
const device* dev = container.get_device_by_id(id);
if (nullptr == dev)
TRMNL* trmnl = container.get_device_by_id(id);
// Refresh date from file
// Someone might have put the new device in
if (nullptr == trmnl)
{
json j;
read_file_json(j, devices_filename, &cout);
container.clear();
container = j;
trmnl = container.get_device_by_id(id);
}
if (nullptr == trmnl)
{
res.status = 404;
@@ -247,29 +114,40 @@ int main(int argc, char **argv)
}
else
{
bool should_dump = false;
res.status = 200;
if (dev->friendly_id.empty())
if (trmnl->friendly_id().empty())
{
container.set_device_friendly(id, device_id_to_friendly(id));
should_dump = true;
trmnl->friendly_id(TRMNL::friendly_from_id(id));
}
device* dev_mut = const_cast<device*>(dev);
if (trmnl->api_key().empty())
{
should_dump = true;
trmnl->api_key("nullptr");
}
response["status"] = 200;
response["api_key"] = "nullptr";
response["friendly_id"] = dev->friendly_id;
response["api_key"] = trmnl->api_key();
response["friendly_id"] = trmnl->friendly_id();
// TODO: Check for image in folder
response["image_url"] = "https://trmnl.com/images/setup/setup-logo.bmp";
response["filename"] = "welcome";
res.body = response.dump();
json test = *dev_mut;
cout << test.dump(4) << endl;
if (should_dump)
{
write_file_json(container, devices_filename, &cout);
}
}
}
else
{
res.status = 500;
// Bad Request - No ID header
res.status = 400;
}
};