added CORS
This commit is contained in:
128
source/shadowrun/ShadowrunApi.cpp
Normal file
128
source/shadowrun/ShadowrunApi.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
|
||||
#include "ShadowrunApi.hpp"
|
||||
#include "ShadowrunDb.hpp"
|
||||
#include "login.hpp"
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
namespace shadowrun
|
||||
{
|
||||
|
||||
static std::unordered_map<std::string, std::string> parse_query_string(const std::string& query) {
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
std::istringstream stream(query);
|
||||
std::string pair;
|
||||
|
||||
while (std::getline(stream, pair, '&')) {
|
||||
auto pos = pair.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
std::string key = pair.substr(0, pos);
|
||||
std::string value = pair.substr(pos + 1);
|
||||
params[key] = value; // You may want to URL-decode here
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
void initApi(crow::App<CORS>& app){
|
||||
|
||||
CROW_ROUTE(app, "/assets/shadowrun/<path>")
|
||||
([&](const crow::request& req, const std::string& p) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
|
||||
const filesystem::path assets_dir = "assets/shadowrun/";
|
||||
filesystem::path file_path = assets_dir / p;
|
||||
return utils::getFile(file_path);
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters")
|
||||
([&](const crow::request& req) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
|
||||
auto characters = getCharacters();
|
||||
auto res =
|
||||
crow::response(200, utils::toJsonArray(characters));
|
||||
res.set_header("Content-Type", "application/json");
|
||||
return res;
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters").methods("POST"_method)
|
||||
([](const crow::request& req) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
|
||||
nlohmann::json data = nlohmann::json::parse(req.body); // parse JSON from HTTP body
|
||||
auto name = data["name"];
|
||||
int id = createCharacter(name);
|
||||
if(id > 0){
|
||||
auto character = getChracter(id);
|
||||
if (character.has_value()){
|
||||
auto res = crow::response(200, nlohmann::json(character.value()).dump());
|
||||
res.set_header("Content-Type", "application/json");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return crow::response(405, "Failed to create character");
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters/<int>")
|
||||
([&](const crow::request& req, int id) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
|
||||
auto optCharacter = getChracter(id);
|
||||
if (!optCharacter.has_value())
|
||||
return crow::response(404, "Character not found");
|
||||
|
||||
auto res = crow::response(200, nlohmann::json(optCharacter.value()).dump());
|
||||
res.set_header("Content-Type", "application/json");
|
||||
return res;
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters_data/<int>")
|
||||
([&](const crow::request& req, int id) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
|
||||
nlohmann::json j;
|
||||
const auto characterData = getChracterData(id);
|
||||
|
||||
if(characterData.empty())
|
||||
return crow::response(405, "Character not found");
|
||||
|
||||
for(const auto& data : characterData ){
|
||||
const auto& key = magic_enum::enum_cast<Type>(data.type);
|
||||
if(key.has_value()){
|
||||
auto res = utils::parseJson(data.json);
|
||||
if(res){
|
||||
j[magic_enum::enum_name(key.value())] = res.value();
|
||||
} else {
|
||||
CROW_LOG_ERROR << "Failed to parse json: " << res.error();
|
||||
}
|
||||
} else {
|
||||
CROW_LOG_ERROR << "Read invalid type from database: " << data.type;
|
||||
}
|
||||
}
|
||||
|
||||
auto res = crow::response(200, j.dump());
|
||||
res.set_header("Content-Type", "application/json");
|
||||
return res;
|
||||
});
|
||||
|
||||
CROW_ROUTE(app, "/api/shadowrun/characters_data/<int>").methods("POST"_method)
|
||||
([&](const crow::request& req, int id) {
|
||||
LOGGIN_REQUIERED(req);
|
||||
nlohmann::json j = nlohmann::json::parse(req.body);
|
||||
|
||||
for (auto type : magic_enum::enum_values<Type>()) {
|
||||
const auto& key = magic_enum::enum_name(type);
|
||||
if (j.contains(key)){
|
||||
storeCharacterData(id, type, j[key].dump());
|
||||
}
|
||||
}
|
||||
|
||||
auto res = crow::response(200, "Saved Character data");
|
||||
return res;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
12
source/shadowrun/ShadowrunApi.hpp
Normal file
12
source/shadowrun/ShadowrunApi.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __SHADOWRUNAPI_H__
|
||||
#define __SHADOWRUNAPI_H__
|
||||
|
||||
#include "cors.h"
|
||||
#include <crow.h>
|
||||
|
||||
namespace shadowrun {
|
||||
|
||||
void initApi(crow::App<CORS>& app);
|
||||
|
||||
}
|
||||
#endif // __SHADOWRUNAPI_H__
|
||||
101
source/shadowrun/ShadowrunDb.cpp
Normal file
101
source/shadowrun/ShadowrunDb.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "ShadowrunDb.hpp"
|
||||
#include <optional>
|
||||
#include "databasepool.h"
|
||||
#include "utils.hpp"
|
||||
#include "crow/logging.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace sqlite_orm;
|
||||
|
||||
namespace shadowrun {
|
||||
|
||||
int64_t createCharacter(const string& name){
|
||||
if (name.empty())
|
||||
return -1;
|
||||
|
||||
int64_t id;
|
||||
auto db = dbpool->acquire();
|
||||
|
||||
auto character = db->get_optional<ShadowrunCharacter>(
|
||||
where(c(&ShadowrunCharacter::name) == name)
|
||||
);
|
||||
|
||||
if (character.has_value()) {
|
||||
id = character.value().id;
|
||||
} else {
|
||||
auto c = newShadowrunCharacter(name);
|
||||
id = db->insert(c);
|
||||
}
|
||||
dbpool->release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
std::vector<ShadowrunCharacter> getCharacters(){
|
||||
auto db = dbpool->acquire();
|
||||
auto characters = db->get_all<ShadowrunCharacter>();
|
||||
dbpool->release(db);
|
||||
return characters;
|
||||
}
|
||||
|
||||
optional<ShadowrunCharacter> getChracter(int id)
|
||||
{
|
||||
auto db = dbpool->acquire();
|
||||
optional<ShadowrunCharacter> character = db->get_optional<ShadowrunCharacter>(id);
|
||||
dbpool->release(db);
|
||||
return character;
|
||||
}
|
||||
|
||||
vector<ShadowrunCharacterData> getChracterData(int character_id)
|
||||
{
|
||||
auto db = dbpool->acquire();
|
||||
auto characterData = db->get_all<ShadowrunCharacterData>(
|
||||
where(c(&ShadowrunCharacterData::character_id) == character_id)
|
||||
);
|
||||
dbpool->release(db);
|
||||
return characterData;
|
||||
}
|
||||
|
||||
int storeCharacterData(int characterId, const Type type, const string& json){
|
||||
int id;
|
||||
auto db = dbpool->acquire();
|
||||
auto characterData = db->get_all<ShadowrunCharacterData>(
|
||||
where(
|
||||
(c(&ShadowrunCharacterData::character_id) == characterId) and
|
||||
(c(&ShadowrunCharacterData::type) == static_cast<int>(type)))
|
||||
);
|
||||
|
||||
if(characterData.empty()){
|
||||
ShadowrunCharacterData character = newShadowrunCharacterData(characterId, type, json);
|
||||
id = db->insert(character);
|
||||
}
|
||||
else {
|
||||
if (characterData.size() > 1){
|
||||
CROW_LOG_ERROR << "Character ID: " << characterId << "has mote than 1 type: " << magic_enum::enum_name(type);
|
||||
}
|
||||
auto& character = characterData[0];
|
||||
character.json = json;
|
||||
character.updated_at = utils::currentTime();
|
||||
db->update(character);
|
||||
id = character.id;
|
||||
}
|
||||
dbpool->release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
int storeCharacterData(const ShadowrunCharacterData& data){
|
||||
int id;
|
||||
auto db = dbpool->acquire();
|
||||
auto characterData = db->get_optional<ShadowrunCharacterData>(data.id);
|
||||
|
||||
if(!characterData.has_value()){
|
||||
id = db->insert(data);
|
||||
}
|
||||
else {
|
||||
db->update(data);
|
||||
id = data.id;
|
||||
}
|
||||
dbpool->release(db);
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
73
source/shadowrun/ShadowrunDb.hpp
Normal file
73
source/shadowrun/ShadowrunDb.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef __SHADOWRUNDB_H__
|
||||
#define __SHADOWRUNDB_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include "json.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "sqlite_orm.h"
|
||||
#include "magic_enum.hpp"
|
||||
|
||||
namespace shadowrun {
|
||||
enum class Type {
|
||||
Unknown = 0,
|
||||
Info = 1,
|
||||
Attributes = 2,
|
||||
Skills = 3,
|
||||
Connections = 4,
|
||||
RangedWeapons = 5,
|
||||
MeleeWeapons = 6,
|
||||
Cyberware = 7,
|
||||
Bioware = 8,
|
||||
PositiveQualities = 9,
|
||||
NegativeQualities = 10,
|
||||
Notes = 11,
|
||||
};
|
||||
|
||||
struct ShadowrunCharacter {
|
||||
int id;
|
||||
std::string name;
|
||||
std::string created_at; // SQLite stores DATETIME as TEXT
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ShadowrunCharacter, id, name, created_at)
|
||||
|
||||
inline ShadowrunCharacter newShadowrunCharacter(const std::string& name){
|
||||
return ShadowrunCharacter {-1, name, utils::currentTime()};
|
||||
}
|
||||
|
||||
struct ShadowrunCharacterData {
|
||||
int id;
|
||||
int character_id;
|
||||
int type;
|
||||
std::string json;
|
||||
std::string created_at;
|
||||
std::string updated_at;
|
||||
};
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(ShadowrunCharacterData, id, character_id, type, json, created_at, updated_at);
|
||||
|
||||
inline ShadowrunCharacterData newShadowrunCharacterData(int character_id, Type type, const std::string json){
|
||||
std::string time = utils::currentTime();
|
||||
return ShadowrunCharacterData {
|
||||
.id = -1,
|
||||
.character_id = character_id,
|
||||
.type = static_cast<int>(type),
|
||||
.json = json,
|
||||
.created_at = time,
|
||||
.updated_at = time,
|
||||
};
|
||||
}
|
||||
|
||||
int64_t createCharacter(const std::string& name);
|
||||
std::vector<ShadowrunCharacter> getCharacters();
|
||||
std::optional<ShadowrunCharacter> getChracter(int id);
|
||||
|
||||
std::vector<ShadowrunCharacterData> getChracterData(int character_id);
|
||||
int storeCharacterData(const ShadowrunCharacterData& data);
|
||||
int storeCharacterData(int characterId, const Type type, const std::string& json);
|
||||
}
|
||||
|
||||
|
||||
#endif // __SHADOWRUNDB_H__
|
||||
Reference in New Issue
Block a user