added shadowrun database
This commit is contained in:
35
src/database/database.cpp
Normal file
35
src/database/database.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "crow.h"
|
||||
#include "database.hpp"
|
||||
|
||||
Database::Database() :
|
||||
m_db(nullptr)
|
||||
{}
|
||||
|
||||
Database::~Database() {
|
||||
sqlite3_close(m_db);
|
||||
}
|
||||
|
||||
bool Database::exec(const char* sqlQuery) {
|
||||
char* errmsg = nullptr;
|
||||
int rc = sqlite3_exec(m_db, sqlQuery, nullptr, nullptr, &errmsg);
|
||||
if (rc != SQLITE_OK) {
|
||||
CROW_LOG_ERROR << "SQL error: " << errmsg;
|
||||
sqlite3_free(errmsg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::exec(const std::string& sqlQuery)
|
||||
{
|
||||
exec(sqlQuery.c_str());
|
||||
}
|
||||
|
||||
bool Database::open(){
|
||||
int rc = sqlite3_open("example.db", &m_db);
|
||||
if (rc) {
|
||||
CROW_LOG_ERROR << "Can't open database: " << sqlite3_errmsg(m_db);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
21
src/database/database.hpp
Normal file
21
src/database/database.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef __DATABASE_H__
|
||||
#define __DATABASE_H__
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <string>
|
||||
|
||||
class Database {
|
||||
|
||||
public:
|
||||
Database();
|
||||
~Database();
|
||||
|
||||
bool open();
|
||||
bool exec(const char* sqlQuery);
|
||||
bool exec(const std::string& sqlQuery);
|
||||
|
||||
private:
|
||||
sqlite3* m_db;
|
||||
};
|
||||
|
||||
#endif // __DATABASE_H__
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "systemd.h"
|
||||
#include "htmx_helper.h"
|
||||
#include "json_settings.h"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
31
src/main.cpp
31
src/main.cpp
@@ -1,6 +1,4 @@
|
||||
#include <crow.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <print>
|
||||
@@ -8,16 +6,11 @@
|
||||
#include "json_settings.h"
|
||||
#include "htmx_helper.h"
|
||||
#include "systemd.h"
|
||||
#include "utils.hpp"
|
||||
#include "ShadowrunApi.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string load_file(const string& path) {
|
||||
ifstream f(path);
|
||||
stringstream buffer;
|
||||
buffer << f.rdbuf();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
optional<string> get_body_name(const string& body) {
|
||||
const auto pos = body.find('=');
|
||||
if (pos == std::string::npos) return {};
|
||||
@@ -34,11 +27,15 @@ int main() {
|
||||
crow::SimpleApp app;
|
||||
|
||||
CROW_ROUTE(app, "/")([] {
|
||||
return crow::response(load_file("templates/index.html"));
|
||||
return crow::response(utils::loadFile("templates/index.html"));
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/static/<string>")([](const std::string& file) {
|
||||
return crow::response(load_file("static/" + file));
|
||||
return crow::response(utils::loadFile("static/" + file));
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/templates/<string>")([](const std::string& file) {
|
||||
return crow::response(utils::loadFile("templates/" + file));
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/status")([] {
|
||||
@@ -80,8 +77,20 @@ int main() {
|
||||
} else {
|
||||
CROW_LOG_ERROR << "failed to load settings : " << opt_settings.error();
|
||||
}
|
||||
|
||||
auto opt_isPortOpen = utils::isLocalPortOpen(httpPort);
|
||||
if (opt_isPortOpen.has_value()){
|
||||
if (opt_isPortOpen.value()){
|
||||
CROW_LOG_ERROR << "Local port : " << httpPort << " is already open";
|
||||
}
|
||||
}
|
||||
else {
|
||||
CROW_LOG_ERROR << "failed to check if local port is open : " << opt_isPortOpen.error();
|
||||
}
|
||||
}
|
||||
|
||||
shadowrun::initApi(app);
|
||||
|
||||
app.loglevel(crow::LogLevel::INFO);
|
||||
app.port(httpPort).multithreaded().run();
|
||||
}
|
||||
|
||||
26
src/shadowrun/HtmxShAttributeList.cpp
Normal file
26
src/shadowrun/HtmxShAttributeList.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <format>
|
||||
#include "HtmxShAttributeList.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
HtmxShAttributeList::HtmxShAttributeList(const std::string& id, const vector<string>& itemList){
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='grid'>";
|
||||
for (auto& item : itemList){
|
||||
string item_id = utils::to_id_format(id + "_" + item);
|
||||
|
||||
html += format("<label>{}:<input type='text' name='{}'></label>", item, item_id);
|
||||
}
|
||||
html += "</div>";
|
||||
}
|
||||
|
||||
HtmxShAttributeList::HtmxShAttributeList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList){
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='grid'>";
|
||||
for (auto& item : itemValueList){
|
||||
string item_id = utils::to_id_format(id + "_" + item.first);
|
||||
html += format("<label>{}:<input type='text' name='{}' value='{}'></label>", item, item_id, item.second);
|
||||
}
|
||||
html += "</div>";
|
||||
}
|
||||
18
src/shadowrun/HtmxShAttributeList.hpp
Normal file
18
src/shadowrun/HtmxShAttributeList.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef HTMXSHATTRIBUTELIST_H
|
||||
#define HTMXSHATTRIBUTELIST_H
|
||||
|
||||
#include "HtmxObject.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class HtmxShAttributeList : public HtmxObject {
|
||||
|
||||
public:
|
||||
// create new item list
|
||||
HtmxShAttributeList(const std::string& id, const std::vector<std::string>& itemList);
|
||||
|
||||
// create new item list where each item as a value
|
||||
HtmxShAttributeList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList);
|
||||
};
|
||||
|
||||
#endif // HTMXSHATTRIBUTELIST_H
|
||||
28
src/shadowrun/HtmxShCondition.cpp
Normal file
28
src/shadowrun/HtmxShCondition.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "HtmxShCondition.hpp"
|
||||
#include "../utils.hpp"
|
||||
#include <format>
|
||||
|
||||
using namespace std;
|
||||
|
||||
HtmxShCondition::HtmxShCondition(std::string id, size_t nbrOfBoxes)
|
||||
{
|
||||
html += "<div class='section'>";
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='monitor-track'>";
|
||||
|
||||
int con_value = -1;
|
||||
|
||||
for (size_t i = 0; i < nbrOfBoxes; i++)
|
||||
{
|
||||
string item_id = utils::to_id_format(format("{}_{}",id, i));
|
||||
html += format("<label class='monitor-box'><input type='checkbox' name='{}'></label>", item_id);
|
||||
|
||||
if ( ((i + 1) % 3 == 0) && (i != 0) )
|
||||
{
|
||||
html += format("<div class='monitor-number'>{}</div>", con_value);
|
||||
con_value--;
|
||||
}
|
||||
|
||||
}
|
||||
html += "</div></div>";
|
||||
}
|
||||
13
src/shadowrun/HtmxShCondition.hpp
Normal file
13
src/shadowrun/HtmxShCondition.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __HTMXSHCONDITION_H__
|
||||
#define __HTMXSHCONDITION_H__
|
||||
|
||||
#include <string>
|
||||
#include "HtmxObject.h"
|
||||
|
||||
class HtmxShCondition : public HtmxObject {
|
||||
|
||||
public:
|
||||
HtmxShCondition(std::string id, size_t nbrOfBoxes);
|
||||
};
|
||||
|
||||
#endif // __HTMXSHCONDITION_H__
|
||||
43
src/shadowrun/HtmxShItemList.cpp
Normal file
43
src/shadowrun/HtmxShItemList.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <format>
|
||||
#include "HtmxShItemList.hpp"
|
||||
#include "../utils.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
HtmxShItemList::HtmxShItemList(const std::string& id, const std::vector<std::string>& columns, size_t size){
|
||||
html += "<div class='section'>";
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += format("<div class='grid grid-{}'>", columns.size());
|
||||
for (size_t i = 0; i < size; i++){
|
||||
for (auto& col : columns){
|
||||
string item_id = utils::to_id_format(format("{}_{}_{}", id, i, col));
|
||||
html += format("<input type='text' name='{}' placeholder='{}'>", item_id, col);
|
||||
}
|
||||
}
|
||||
|
||||
html += "</div></div>";
|
||||
}
|
||||
|
||||
/*
|
||||
HtmxShItemList::HtmxShItemList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList){
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += "<div class='grid'>";
|
||||
for (auto& item : itemValueList){
|
||||
string item_id = utils::to_id_format(id + "_" + item.first);
|
||||
html += format("<label>{}:<input type='text' name='{}' value='{}'></label>", item, item_id, item.second);
|
||||
}
|
||||
html += "</div>";
|
||||
|
||||
html += "<div class='section'>";
|
||||
html += format("<h2>{}</h2>", id);
|
||||
html += format("<div class='grid grid-{}'>", columns.size());
|
||||
for (size_t i = 0; i < size; i++){
|
||||
for (auto& col : columns){
|
||||
string item_id = utils::to_id_format(format("{}_{}_{}", id, i, col));
|
||||
html += format("<input type='text' name='{}' placeholder='{}' value='{}'>", item_id, col);
|
||||
}
|
||||
}
|
||||
|
||||
html += "</div></div>";
|
||||
}
|
||||
*/
|
||||
18
src/shadowrun/HtmxShItemList.hpp
Normal file
18
src/shadowrun/HtmxShItemList.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef HTMXSHITEMLIST_H
|
||||
#define HTMXSHITEMLIST_H
|
||||
|
||||
#include "HtmxObject.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class HtmxShItemList : public HtmxObject {
|
||||
|
||||
public:
|
||||
// create new item list,
|
||||
HtmxShItemList(const std::string& id, const std::vector<std::string>& columns, size_t size);
|
||||
|
||||
// create new item list where each item as a value
|
||||
HtmxShItemList(const std::string& id, const std::vector<std::pair<std::string, std::string>>& itemValueList);
|
||||
};
|
||||
|
||||
#endif // HTMXSHITEMLIST_H
|
||||
106
src/shadowrun/ShadowrunApi.cpp
Normal file
106
src/shadowrun/ShadowrunApi.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
|
||||
|
||||
#include "ShadowrunApi.hpp"
|
||||
#include "ShadowrunCharacterForm.hpp"
|
||||
#include "database.hpp"
|
||||
|
||||
namespace shadowrun
|
||||
{
|
||||
|
||||
bool initDb() {
|
||||
auto db = Database();
|
||||
|
||||
if (!db.open()){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a tables
|
||||
const char* create_sql_chars = "CREATE TABLE IF NOT EXISTS shadowrun_characters ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"name TEXT,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP);";
|
||||
|
||||
if (!db.exec(create_sql_chars)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_characters table";
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* create_sql_data = "CREATE TABLE IF NOT EXISTS shadowrun_data ("
|
||||
"id INTEGER PRIMARY KEY,"
|
||||
"character_id INTEGER NOT NULL,"
|
||||
"name TEXT NOT NULL,"
|
||||
"value TEXT,"
|
||||
"created_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,"
|
||||
"FOREIGN KEY (character_id) REFERENCES characters(id) ON DELETE CASCADE);";
|
||||
|
||||
if (!db.exec(create_sql_data)){
|
||||
CROW_LOG_ERROR << "Failed to create shadowrun_data table";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
void initApi(crow::SimpleApp& app)
|
||||
{
|
||||
CROW_ROUTE(app, "/api/shadowrun/submit-character").methods("POST"_method)(
|
||||
[](const crow::request& req) {
|
||||
auto params = crow::query_string(req.body);
|
||||
|
||||
std::string name = params.get("name") ? params.get("name") : "";
|
||||
std::string metatype = params.get("metatype") ? params.get("metatype") : "";
|
||||
std::string age = params.get("age") ? params.get("age") : "";
|
||||
// ... extract more fields as needed
|
||||
|
||||
// Optionally save to a DB or do logic here
|
||||
|
||||
// Return response HTML
|
||||
std::ostringstream out;
|
||||
out << "<div class='alert alert-success'>"
|
||||
<< "Character " << name << " submitted successfully!"
|
||||
<< "</div>";
|
||||
|
||||
return crow::response{out.str()};
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/character-form")
|
||||
([](const crow::request& req) {
|
||||
auto query = crow::query_string(req.url_params);
|
||||
std::string name = query.get("name") ? query.get("name") : "";
|
||||
|
||||
// TODO: Load data from file or DB using `name`
|
||||
std::string metatype = "Troll";
|
||||
int age = 28;
|
||||
|
||||
return crow::response{ShadowrunCharacterForm().htmx()};
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/character-list")
|
||||
([] {
|
||||
std::ostringstream html;
|
||||
|
||||
// Simulated character database
|
||||
std::vector<std::string> characters = { "Trogdor", "Alice", "Zigzag" };
|
||||
|
||||
html << "<form hx-get='/api/shadowrun/character-form' hx-target='#form-container' hx-params='*'>"
|
||||
<< "<label>Character Name: "
|
||||
<< "<select name='name'>";
|
||||
|
||||
for (const auto& name : characters) {
|
||||
html << "<option value='" << name << "'>" << name << "</option>";
|
||||
}
|
||||
|
||||
html << "</select></label>"
|
||||
<< "<button type='submit'>Load Character</button>"
|
||||
<< "</form>";
|
||||
|
||||
return crow::response{html.str()};
|
||||
});
|
||||
|
||||
if(initDb()){
|
||||
CROW_LOG_ERROR << "Failed to Init shadowrun database";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
src/shadowrun/ShadowrunApi.hpp
Normal file
11
src/shadowrun/ShadowrunApi.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __SHADOWRUNAPI_H__
|
||||
#define __SHADOWRUNAPI_H__
|
||||
|
||||
#include <crow.h>
|
||||
|
||||
namespace shadowrun {
|
||||
|
||||
void initApi(crow::SimpleApp& app);
|
||||
|
||||
}
|
||||
#endif // __SHADOWRUNAPI_H__
|
||||
122
src/shadowrun/ShadowrunCharacterForm.cpp
Normal file
122
src/shadowrun/ShadowrunCharacterForm.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "HtmxShItemList.hpp"
|
||||
#include "HtmxShAttributeList.hpp"
|
||||
#include "HtmxShCondition.hpp"
|
||||
#include "ShadowrunCharacterForm.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const vector<string> cCharacterInfo = {
|
||||
"Name",
|
||||
"Metatype",
|
||||
"Age",
|
||||
"Sex",
|
||||
"Nuyen",
|
||||
"Lifestyle",
|
||||
"Total Karma",
|
||||
"Current Karma",
|
||||
"Street Cred",
|
||||
"Notoriety",
|
||||
"Public Awareness"
|
||||
};
|
||||
|
||||
static const vector<string> cAttributes = {
|
||||
"Body",
|
||||
"Agility",
|
||||
"Reaction",
|
||||
"Strength",
|
||||
"Charisma",
|
||||
"Intuition",
|
||||
"Logic",
|
||||
"Willpower",
|
||||
"Edge",
|
||||
"Essence",
|
||||
"Initiative"
|
||||
};
|
||||
|
||||
static const vector<string> cSkillParameters = {
|
||||
"Name",
|
||||
"RTG.",
|
||||
"ATT.",
|
||||
};
|
||||
|
||||
static const vector<string> cContactsParameters = {
|
||||
"Name",
|
||||
"Loyalty",
|
||||
};
|
||||
|
||||
static const vector<string> cRangedWeaponsParameters = {
|
||||
"Weapon",
|
||||
"Damage",
|
||||
"AP",
|
||||
"Mode",
|
||||
"RC",
|
||||
"Ammo"
|
||||
};
|
||||
|
||||
static const vector<string> cImplantParameters = {
|
||||
"Implant",
|
||||
"Rating",
|
||||
"Essence",
|
||||
"Notes",
|
||||
};
|
||||
|
||||
static const vector<string> cMeleeWeaponParameters = {
|
||||
"Weapon",
|
||||
"Reach",
|
||||
"Damage",
|
||||
"AP",
|
||||
};
|
||||
|
||||
static const vector<string> cArmorParamters = {
|
||||
"Armor",
|
||||
"Ballistic",
|
||||
"Impact",
|
||||
"Notes",
|
||||
};
|
||||
|
||||
ShadowrunCharacterForm::ShadowrunCharacterForm() {
|
||||
html.reserve(30000);
|
||||
|
||||
html += "<form hx-post='/api/shadowrun/submit-character' hx-target='#form-response' hx-swap='innerHTML'>";
|
||||
html += HtmxShAttributeList("Character Info", cCharacterInfo).htmx();
|
||||
html += HtmxShAttributeList("Attributes", cAttributes).htmx();
|
||||
|
||||
html += "<div style='display: grid; grid-template-columns: 1fr 1fr; gap: 2em;'>";
|
||||
html += HtmxShItemList("Active Skills", cSkillParameters, 6).htmx();
|
||||
html += HtmxShItemList("Knowledge Skills", cSkillParameters, 6).htmx();
|
||||
|
||||
// add Qualities
|
||||
html += "<div class='section'>"
|
||||
"<h2>Qualities</h2>"
|
||||
"<label>Positive Qualities:"
|
||||
"<textarea name='positive_qualities' rows='4'></textarea>"
|
||||
"</label>"
|
||||
"<label>Negative Qualities:"
|
||||
"<textarea name='negative_qualities' rows='4'></textarea>"
|
||||
"</label>"
|
||||
"</div>";
|
||||
|
||||
// add datapack notes
|
||||
html += "<div class='section'>"
|
||||
"<h2>Datajack / Commlink / Cyberdeck / Notes</h2>"
|
||||
"<label>Notes:"
|
||||
"<textarea name='datapack_notes' rows='6'></textarea>"
|
||||
"</label>"
|
||||
"</div>";
|
||||
|
||||
html += HtmxShCondition("Physical Condition", 18).htmx();
|
||||
html += HtmxShCondition("Stun Condition", 12).htmx();
|
||||
html += HtmxShItemList("Contacts", cContactsParameters, 6).htmx();
|
||||
html += HtmxShItemList("Ranged Weapons", cRangedWeaponsParameters, 7).htmx();
|
||||
html += HtmxShItemList("Cyberware and Bioware", cImplantParameters, 7).htmx();
|
||||
html += HtmxShItemList("Melee Weapons", cMeleeWeaponParameters, 7).htmx();
|
||||
html += HtmxShItemList("Armor", cArmorParamters , 3).htmx();
|
||||
html += "</div>";
|
||||
|
||||
html += "<div style='text-align:center'>"
|
||||
"<button type='submit'>Submit</button>"
|
||||
"</div>"
|
||||
"</form>";
|
||||
}
|
||||
14
src/shadowrun/ShadowrunCharacterForm.hpp
Normal file
14
src/shadowrun/ShadowrunCharacterForm.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef SHADOWRUN_CHARACTER_FORM_HPP
|
||||
#define SHADOWRUN_CHARACTER_FORM_HPP
|
||||
|
||||
#include "htmx/HtmxObject.h"
|
||||
|
||||
class ShadowrunCharacterForm : public HtmxObject {
|
||||
|
||||
public:
|
||||
ShadowrunCharacterForm();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // SHADOWRUN_CHARACTER_FORM_HPP
|
||||
79
src/utils.cpp
Normal file
79
src/utils.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include "utils.hpp"
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace utils {
|
||||
|
||||
expected<bool, string> isLocalPortOpen(uint16_t portno) {
|
||||
const char *hostname = "localhost";
|
||||
|
||||
int sockfd;
|
||||
bool ret;
|
||||
struct sockaddr_in serv_addr;
|
||||
struct hostent *server;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
close(sockfd);
|
||||
return unexpected("ERROR opening socket");
|
||||
}
|
||||
|
||||
server = gethostbyname(hostname);
|
||||
|
||||
if (server == NULL) {
|
||||
close(sockfd);
|
||||
return unexpected("ERROR, no such host");
|
||||
}
|
||||
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
bcopy((char *)server->h_addr,
|
||||
(char *)&serv_addr.sin_addr.s_addr,
|
||||
server->h_length);
|
||||
|
||||
serv_addr.sin_port = htons(portno);
|
||||
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
|
||||
ret = false;
|
||||
} else {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
close(sockfd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
string to_id_format(const string& s){
|
||||
string new_s = s;
|
||||
|
||||
// transform(new_s.begin(), new_s.end(), new_s.begin(),
|
||||
// [](unsigned char c){ return std::tolower(c); });
|
||||
|
||||
replace( new_s.begin(), new_s.end(), ' ', '-');
|
||||
|
||||
return new_s;
|
||||
}
|
||||
|
||||
string loadFile(const string& path) {
|
||||
ifstream f(path);
|
||||
stringstream buffer;
|
||||
buffer << f.rdbuf();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
std::filesystem::path getDataDir(){
|
||||
return std::getenv("XDG_DATA_HOME")
|
||||
? std::filesystem::path(std::getenv("XDG_DATA_HOME")) / APPLICATION_NAME
|
||||
: std::filesystem::path(std::getenv("HOME")) / ".local" / "share" / APPLICATION_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
19
src/utils.hpp
Normal file
19
src/utils.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef UTILS_HPP
|
||||
#define UTILS_HPP
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
|
||||
namespace utils {
|
||||
std::expected<bool, std::string> isLocalPortOpen(uint16_t portno);
|
||||
|
||||
std::string to_id_format(const std::string& s);
|
||||
|
||||
std::string loadFile(const std::string& path);
|
||||
|
||||
std::filesystem::path getDataDir();
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user