finish logical expression evaluator

main
Brett 2023-08-22 21:57:26 -04:00
parent 246742d956
commit cd3e660765
8 changed files with 103 additions and 25 deletions

4
.gitignore vendored
View File

@ -2,4 +2,6 @@ cmake-build-debug/
cmake-build-debug-address/ cmake-build-debug-address/
cmake-build-minsizerel/ cmake-build-minsizerel/
cmake-build-release/ cmake-build-release/
cmake-build-relwithdebinfo/ cmake-build-relwithdebinfo/
cmake-build-relwithdebaddr/
crow_test/data/

Binary file not shown.

View File

@ -1 +0,0 @@
aubTl45vzPn5feHw 1692660008

View File

@ -1 +0,0 @@
{"clientID":"50a21c33-66c4-5a0f-902f-9434632025e6","clientToken":"bsmbPoeuxWBE0/j1W9O/EOs85s79wIS1P5qYHovfhkIhNwl5SGkcpHww+DnbzwNCJ1y+Tb2hLpic3qtgbbtWvg=="}

View File

@ -8,8 +8,10 @@
#include <unordered_map> #include <unordered_map>
#include <blt/std/hashmap.h> #include <blt/std/hashmap.h>
#define CROW_STATIC_DIRECTORY "/home/brett/projects/cpp/crowsite/crow_test/static/" //#define CROW_STATIC_DIRECTORY "/home/brett/projects/cpp/crowsite/crow_test/static/"
#define SITE_FILES_PATH "/home/brett/projects/cpp/crowsite/crow_test" #define CROW_STATIC_DIRECTORY "/home/brett/Documents/code/c++/crowsite/crow_test/static/"
//#define SITE_FILES_PATH "/home/brett/projects/cpp/crowsite/crow_test"
#define SITE_FILES_PATH "/home/brett/Documents/code/c++/crowsite/crow_test"
#define CROW_STATIC_ENDPOINT "/static/<path>" #define CROW_STATIC_ENDPOINT "/static/<path>"
#define MILES_SITE #define MILES_SITE

View File

@ -51,7 +51,7 @@ namespace cs::jellyfin
std::string getUserData() std::string getUserData()
{ {
#define url "https://media.tpgc.me/Users" const auto url = "https://media.tpgc.me/Users";
cs::request request; cs::request request;
request.setContentHeaderJson(); request.setContentHeaderJson();

View File

@ -119,6 +119,24 @@ namespace cs
OPEN, // ( OPEN, // (
CLOSE // ) CLOSE // )
}; };
static std::string decodeName(TokenType type){
switch (type){
case TokenType::AND:
return "AND";
case TokenType::OR:
return "OR";
case TokenType::NOT:
return "NOT";
case TokenType::IDENT:
return "IDENT";
case TokenType::OPEN:
return "OPEN";
case TokenType::CLOSE:
return "CLOSE";
}
}
struct Token struct Token
{ {
TokenType type; TokenType type;
@ -164,12 +182,6 @@ namespace cs
{ {
return str[s_index++]; return str[s_index++];
} }
public:
explicit LogicalEval(std::string str): str(std::move(str))
{
processString();
}
void processString() void processString()
{ {
@ -202,6 +214,7 @@ namespace cs
break; break;
default: default:
std::string token; std::string token;
token += c;
while (hasNext() && !isSpecial(peek())) while (hasNext() && !isSpecial(peek()))
token += consume(); token += consume();
tokens.emplace_back(TokenType::IDENT, token); tokens.emplace_back(TokenType::IDENT, token);
@ -210,31 +223,63 @@ namespace cs
} }
} }
static inline bool isEmpty(const std::string& token, const RuntimeContext& context) static inline bool isTrue(const RuntimeContext& context, const std::string& token)
{ {
return !context.contains(token) || context.at(token).empty(); BLT_DEBUG("isTrue for token '%s' contains? %s", token.c_str(), context.contains(token) ? "True" : "False");
return context.contains(token) && !context.at(token).empty();
} }
// http://www.cs.unb.ca/~wdu/cs4613/a2ans.htm // http://www.cs.unb.ca/~wdu/cs4613/a2ans.htm
bool factor(const RuntimeContext& context) bool factor(const RuntimeContext& context)
{ {
if (!hasNextToken()) if (!hasNextToken())
throw LexerSyntaxError("Processing boolean factor but no token was found!"); throw LexerSyntaxError("Processing boolean factor but no token was found!");
auto next = consumeToken();
} switch (next.type){
case TokenType::IDENT:
bool term(const RuntimeContext& context) if (!next.value.has_value())
{ throw LexerSyntaxError("Token identifier does not have a value!");
return isTrue(context, next.value.value());
case TokenType::NOT:
return !factor(context);
case TokenType::OPEN:
{
// auto ret = ;
// if (consume() != ')')
// throw LexerSyntaxError("Found token '(', parsed expression, but not ')' was found!");
return expr(context);
}
default:
throw LexerSyntaxError("Weird token found while parsing tokens, type: " + decodeName(next.type));
}
} }
bool expr(const RuntimeContext& context) bool expr(const RuntimeContext& context)
{ {
auto fac = factor(context);
if (!hasNextToken())
return fac;
auto next = consumeToken();
switch (next.type) {
case TokenType::AND:
return fac && expr(context);
case TokenType::OR:
return fac || expr(context);
case TokenType::CLOSE:
default:
//BLT_WARN("I've reached the default, help! %s", decodeName(next.type).c_str());
return fac;
}
}
public:
explicit LogicalEval(std::string str): str(std::move(str))
{
processString();
} }
bool eval(const RuntimeContext& context) bool eval(const RuntimeContext& context)
{ {
return expr(context);
} }
}; };
@ -286,7 +331,7 @@ namespace cs
auto searchField = lexer.str.substr(lexer.index); auto searchField = lexer.str.substr(lexer.index);
auto endTokenLoc = RuntimeLexer::findLastTagLocation(token, searchField); auto endTokenLoc = RuntimeLexer::findLastTagLocation(token, searchField);
auto
} else } else
results += lexer.consume(); results += lexer.consume();
} }

View File

@ -99,6 +99,36 @@ bool isUserAdmin(CrowApp& app, const crow::request& req)
return cs::isUserAdmin(cs::getUserFromID(s_clientID)); return cs::isUserAdmin(cs::getUserFromID(s_clientID));
} }
void generateRuntimeContext(const site_params& params, cs::RuntimeContext& context){
auto& session = params.app.get_context<Session>(params.req);
auto s_clientID = session.get("clientID", "");
auto s_clientToken = session.get("clientToken", "");
if (cs::isUserLoggedIn(s_clientID, s_clientToken))
{
auto username = cs::getUserFromID(s_clientID);
auto perms = cs::getUserPermissions(username);
auto isAdmin = cs::isUserAdmin(username);
context["_logged_in"] = "True";
context["_username"] = username;
if (isAdmin)
context["_admin"] = "True";
if (perms & cs::PERM_READ_FILES)
context["_read_files"] = "True";
if (perms & cs::PERM_WRITE_FILES)
context["_write_files"] = "True";
if (perms & cs::PERM_CREATE_POSTS)
context["_create_posts"] = "True";
if (perms & cs::PERM_CREATE_COMMENTS)
context["_create_comments"] = "True";
if (perms & cs::PERM_CREATE_SHARES)
context["_create_shares"] = "True";
if (perms & cs::PERM_EDIT_POSTS)
context["_edit_posts"] = "True";
if (perms & cs::PERM_EDIT_COMMENTS)
context["_edit_comments"] = "True";
}
}
crow::response handle_root_page(const site_params& params) crow::response handle_root_page(const site_params& params)
{ {
//auto page = crow::mustache::load("index.html"); // //auto page = crow::mustache::load("index.html"); //
@ -120,6 +150,7 @@ crow::response handle_root_page(const site_params& params)
auto user_perms = cs::getUserPermissions(cs::getUserFromID(s_clientID)); auto user_perms = cs::getUserPermissions(cs::getUserFromID(s_clientID));
crow::mustache::context ctx; crow::mustache::context ctx;
cs::RuntimeContext context;
// pass perms in // pass perms in
if (user_perms & cs::PERM_ADMIN) if (user_perms & cs::PERM_ADMIN)
@ -136,7 +167,7 @@ crow::response handle_root_page(const site_params& params)
auto referer = params.req.url_params.get("referer"); auto referer = params.req.url_params.get("referer");
if (referer) if (referer)
ctx["referer"] = referer; ctx["referer"] = referer;
auto page = crow::mustache::compile(params.engine.fetch(params.name)); auto page = crow::mustache::compile(params.engine.fetch(params.name, context));
return page.render(ctx); return page.render(ctx);
} }
@ -163,7 +194,7 @@ int main(int argc, const char** argv)
blt::arg_parse parser; blt::arg_parse parser;
parser.addArgument(blt::arg_builder("--tests").setAction(blt::arg_action_t::STORE_TRUE).build()); parser.addArgument(blt::arg_builder("--tests").setAction(blt::arg_action_t::STORE_TRUE).build());
parser.addArgument(blt::arg_builder({"--port", "-p"}).setDefault(8080).build()); parser.addArgument(blt::arg_builder({"--port", "-p"}).setDefault(8080).build());
parser.addArgument(blt::arg_builder("token").build()); parser.addArgument(blt::arg_builder("token").setRequired().build());
auto args = parser.parse_args(argc, argv); auto args = parser.parse_args(argc, argv);
cs::jellyfin::setToken(blt::arg_parse::get<std::string>(args["token"])); cs::jellyfin::setToken(blt::arg_parse::get<std::string>(args["token"]));
cs::jellyfin::processUserData(); cs::jellyfin::processUserData();