Compare commits

..

2 Commits

Author SHA1 Message Date
147fa762c8 Added API key generation 2026-06-25 16:06:13 +03:00
eca47d1596 Fixed memory problems 2026-06-25 16:04:56 +03:00
3 changed files with 96 additions and 64 deletions

View File

@@ -1,4 +1,5 @@
#include "TRMNL.h" #include "TRMNL.h"
#include "helpers.h"
using std::list; using std::list;
using std::map; using std::map;
@@ -18,6 +19,19 @@ m_refresh_rate(refresh_rate),
m_update_handler() m_update_handler()
{} {}
TRMNL::TRMNL(const nlohmann::json& j)
: m_id(""),
m_api_key(""),
m_friendly_id(""),
m_refresh_rate(DEFAULT_REFRESH_RATE),
m_update_handler()
{
json_extract(j, "ID", m_id);
json_extract(j, "api_key", m_api_key);
json_extract(j, "friendly_id", m_friendly_id);
json_extract(j, "refresh_rate", m_refresh_rate);
}
const string& TRMNL::id() const const string& TRMNL::id() const
{ {
return m_id; return m_id;
@@ -108,47 +122,6 @@ void to_json(json& j, const TRMNL& trmnl)
}; };
} }
void from_json(const json& j, TRMNL& trmnl)
{
bool updated = false;
try
{
j.at("ID").get_to(trmnl.m_id);
updated = true;
}
catch (const std::exception& e)
{}
try
{
j.at("api_key").get_to(trmnl.m_api_key);
updated = true;
}
catch (const std::exception& e)
{}
try
{
j.at("friendly_id").get_to(trmnl.m_friendly_id);
updated = true;
}
catch (const std::exception& e)
{}
try
{
j.at("refresh_rate").get_to(trmnl.m_refresh_rate);
updated = true;
}
catch (const std::exception& e)
{}
if (updated && trmnl.m_update_handler)
{
trmnl.m_update_handler(trmnl);
}
}
void TRMNLContainer::TRMNL_update_handler(const TRMNL& trmnl) void TRMNLContainer::TRMNL_update_handler(const TRMNL& trmnl)
{ {
auto it = m_by_id.find(trmnl.m_id); auto it = m_by_id.find(trmnl.m_id);
@@ -164,6 +137,20 @@ void TRMNLContainer::TRMNL_update_handler(const TRMNL& trmnl)
} }
} }
TRMNLContainer& TRMNLContainer::operator=(const TRMNLContainer& other)
{
m_devices = other.m_devices;
m_by_id = other.m_by_id;
m_by_friendly = other.m_by_friendly;
for (TRMNL& device : m_devices)
{
device.set_update_handler([this](const TRMNL& trmnl){ TRMNL_update_handler(trmnl); });
}
return *this;
}
void TRMNLContainer::add_device(TRMNL trmnl) void TRMNLContainer::add_device(TRMNL trmnl)
{ {
if (trmnl.m_id.empty()) if (trmnl.m_id.empty())
@@ -171,7 +158,6 @@ void TRMNLContainer::add_device(TRMNL trmnl)
return; return;
} }
trmnl.set_update_handler([this](const TRMNL& trmnl){ TRMNL_update_handler(trmnl); });
auto it = m_devices.insert(m_devices.end(), trmnl); auto it = m_devices.insert(m_devices.end(), trmnl);
m_by_id[trmnl.m_id] = it; m_by_id[trmnl.m_id] = it;
@@ -180,6 +166,8 @@ void TRMNLContainer::add_device(TRMNL trmnl)
{ {
m_by_friendly[trmnl.m_friendly_id] = it; m_by_friendly[trmnl.m_friendly_id] = it;
} }
it->set_update_handler([this](const TRMNL& trmnl){ TRMNL_update_handler(trmnl); });
} }
TRMNL* TRMNLContainer::get_device_by_id(const string& id) TRMNL* TRMNLContainer::get_device_by_id(const string& id)
@@ -217,16 +205,3 @@ void to_json(json& j, const TRMNLContainer& cont)
{ {
j = cont.m_devices; j = cont.m_devices;
} }
void from_json(const json& j, TRMNLContainer& cont)
{
if (!j.is_array())
{
return;
}
for (int i = 0; i < j.size(); ++i)
{
cont.add_device(j[i]);
}
}

11
TRMNL.h
View File

@@ -9,6 +9,8 @@
#include "json.hpp" #include "json.hpp"
constexpr int DEFAULT_REFRESH_RATE = 300;
class TRMNL class TRMNL
{ {
private: private:
@@ -20,11 +22,13 @@ private:
std::function<void (const TRMNL& trmnl)> m_update_handler; std::function<void (const TRMNL& trmnl)> m_update_handler;
public: public:
// Constructor // Constructors
TRMNL(const std::string& id = "", TRMNL(const std::string& id = "",
const std::string& api_key = "", const std::string& api_key = "",
const std::string& friendly_id = "", const std::string& friendly_id = "",
int refresh_rate = 600); int refresh_rate = DEFAULT_REFRESH_RATE);
TRMNL(const nlohmann::json& j);
// Getters // Getters
const std::string& id() const; const std::string& id() const;
@@ -43,7 +47,6 @@ public:
static std::string friendly_from_id(std::string id); static std::string friendly_from_id(std::string id);
friend void to_json(nlohmann::json& j, const TRMNL& trmnl); friend void to_json(nlohmann::json& j, const TRMNL& trmnl);
friend void from_json(const nlohmann::json& j, TRMNL& trmnl);
friend class TRMNLContainer; friend class TRMNLContainer;
}; };
@@ -58,6 +61,7 @@ private:
public: public:
TRMNLContainer() = default; TRMNLContainer() = default;
TRMNLContainer& operator=(const TRMNLContainer& other);
void add_device(TRMNL trmnl); void add_device(TRMNL trmnl);
@@ -67,7 +71,6 @@ public:
void clear(); void clear();
friend void to_json(nlohmann::json& j, const TRMNLContainer& cont); friend void to_json(nlohmann::json& j, const TRMNLContainer& cont);
friend void from_json(const nlohmann::json& j, TRMNLContainer& cont);
}; };
#endif // TRMNL_H_ #endif // TRMNL_H_

View File

@@ -18,6 +18,56 @@ using nlohmann::json;
using namespace std; using namespace std;
constexpr int API_KEY_LENGHT = 16;
string generate_api_key(int len = API_KEY_LENGHT)
{
string result = "";
std::random_device rand;
std::uniform_int_distribution distribution(0, 63);
int single;
char symbol;
if (len < 0)
{
len = API_KEY_LENGHT;
}
for (int i = 0; i < len; ++i)
{
single = distribution(rand);
if (single <= 9)
{
symbol = '0' + single;
}
else if ((single >= 10) && (single <= 35))
{
symbol = 'A' + single - 10;
}
else if ((single >= 36) && (single <= 61))
{
symbol = 'a' + single - 36;
}
else if (62 == single)
{
symbol = '+';
}
else if (63 == single)
{
symbol = '/';
}
// This should never happen
else
{
symbol = '?';
}
result += symbol;
}
return result;
}
void reload_container(TRMNLContainer& container, const string& filename) void reload_container(TRMNLContainer& container, const string& filename)
{ {
json j; json j;
@@ -27,7 +77,13 @@ void reload_container(TRMNLContainer& container, const string& filename)
return; return;
} }
container.clear(); container.clear();
container = j; if (j.is_array())
{
for (int i = 0; i < j.size(); ++i)
{
container.add_device(j[i]);
}
}
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@@ -97,8 +153,7 @@ int main(int argc, char **argv)
return -1; return -1;
} }
container.clear(); reload_container(container, devices_filename);
container = devs;
auto setup_handler = [&container, &devices_filename](const httplib::Request& req, httplib::Response& res) auto setup_handler = [&container, &devices_filename](const httplib::Request& req, httplib::Response& res)
{ {
@@ -152,8 +207,7 @@ int main(int argc, char **argv)
if (trmnl->api_key().empty()) if (trmnl->api_key().empty())
{ {
should_dump = true; should_dump = true;
// TODO: Randomly generate key here trmnl->api_key(generate_api_key());
trmnl->api_key("nullptr");
} }
response["status"] = 200; response["status"] = 200;