before parsing grades
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
build/**
|
||||
config.toml
|
||||
.cache/**
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "external/tomlplusplus"]
|
||||
path = external/tomlplusplus
|
||||
url = https://github.com/marzer/tomlplusplus
|
||||
[submodule "external/json"]
|
||||
path = external/json
|
||||
url = https://github.com/nlohmann/json
|
||||
|
||||
@@ -13,7 +13,7 @@ endif()
|
||||
# -----------------------------
|
||||
# Project setup
|
||||
# -----------------------------
|
||||
project(mainframe LANGUAGES CXX)
|
||||
project(skyward LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -27,6 +27,7 @@ add_subdirectory(external/spdlog)
|
||||
add_subdirectory(external/cpr)
|
||||
add_subdirectory(external/clickhouse-cpp)
|
||||
add_subdirectory(external/tomlplusplus)
|
||||
add_subdirectory(external/json)
|
||||
# -----------------------------
|
||||
# Executable
|
||||
# -----------------------------
|
||||
@@ -63,6 +64,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
cpr::cpr
|
||||
clickhouse-cpp-lib
|
||||
tomlplusplus::tomlplusplus
|
||||
nlohmann_json::nlohmann_json
|
||||
)
|
||||
|
||||
# -----------------------------
|
||||
|
||||
Submodule SkywardGradeChecker updated: 8f01eaacb5...dbba005327
1
external/json
vendored
Submodule
1
external/json
vendored
Submodule
Submodule external/json added at 9f35919110
17
src/main.cpp
Normal file
17
src/main.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "skwyward-api-utils.hpp"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <string_view>
|
||||
#include <toml++/toml.h>
|
||||
int main (int argc, char *argv[]) {
|
||||
auto config = toml::parse_file("config.toml");
|
||||
std::string base_uri = config["host"].value_or("");
|
||||
std::string test_username = config["test_username"].value_or("");
|
||||
std::string test_password = config["test_password"].value_or("");
|
||||
api_utils::StatusResponse health_check = api_methods::get_status(base_uri);
|
||||
spdlog::info("Status response output: {}", health_check.status);
|
||||
|
||||
api_utils::ErrorResponse test_login = api_methods::get_auth_status(base_uri, test_username, test_password);
|
||||
spdlog::info("Auth attempt response : {}", test_login.success);
|
||||
return 0;
|
||||
}
|
||||
165
src/skwyward-api-utils.cpp
Normal file
165
src/skwyward-api-utils.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "skwyward-api-utils.hpp"
|
||||
|
||||
#include <cpr/cpr.h>
|
||||
#include <algorithm>
|
||||
#include <nlohmann/json.hpp>
|
||||
namespace api_utils {
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
// ---------- Helpers ----------
|
||||
|
||||
static double parse_percent_score(const json& j) {
|
||||
if (j.is_number()) {
|
||||
return j.get<double>();
|
||||
}
|
||||
|
||||
if (j.is_string()) {
|
||||
std::string s = j.get<std::string>();
|
||||
s.erase(std::remove(s.begin(), s.end(), '%'), s.end());
|
||||
return std::stod(s);
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// ---------- Login ----------
|
||||
|
||||
void to_json(json& j, const Login& r) {
|
||||
j = json{
|
||||
{"username", r.username},
|
||||
{"password", r.password}
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const json& j, Login& r) {
|
||||
j.at("username").get_to(r.username);
|
||||
j.at("password").get_to(r.password);
|
||||
}
|
||||
|
||||
// ---------- ErrorResponse ----------
|
||||
|
||||
void from_json(const json& j, ErrorResponse& r) {
|
||||
j.at("success").get_to(r.success);
|
||||
|
||||
if (j.contains("error") && !j.at("error").is_null()) {
|
||||
r.error = j.at("error").get<std::string>();
|
||||
} else {
|
||||
r.error.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void to_json(json& j, const ErrorResponse& r) {
|
||||
j = json{{"success", r.success}};
|
||||
if (r.error) {
|
||||
j["error"] = *r.error;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- StatusResponse ----------
|
||||
|
||||
void to_json(json& j, const StatusResponse& r) {
|
||||
j = json{
|
||||
{"status", r.status},
|
||||
{"message", r.message}
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const json& j, StatusResponse& r) {
|
||||
j.at("status").get_to(r.status);
|
||||
j.at("message").get_to(r.message);
|
||||
}
|
||||
|
||||
// ---------- AssignmentGrade ----------
|
||||
|
||||
void to_json(json& j, const AssignmentGrade& g) {
|
||||
j = json{
|
||||
{"name", g.name},
|
||||
{"dueDate", g.dueDate},
|
||||
{"score", g.score},
|
||||
{"attempts", g.attempts},
|
||||
{"isMajorGrade", g.isMajorGrade}
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const json& j, AssignmentGrade& g) {
|
||||
j.at("name").get_to(g.name);
|
||||
j.at("dueDate").get_to(g.dueDate);
|
||||
|
||||
g.score = parse_percent_score(j.at("score"));
|
||||
|
||||
j.at("attempts").get_to(g.attempts);
|
||||
j.at("isMajorGrade").get_to(g.isMajorGrade);
|
||||
}
|
||||
|
||||
// ---------- ClassGrades ----------
|
||||
|
||||
void to_json(json& j, const ClassGrades& c) {
|
||||
j = json{
|
||||
{"className", c.className},
|
||||
{"teacher", c.teacher},
|
||||
{"period", c.period},
|
||||
{"category", c.category},
|
||||
{"grades", c.grades}
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const json& j, ClassGrades& c) {
|
||||
j.at("className").get_to(c.className);
|
||||
j.at("teacher").get_to(c.teacher);
|
||||
j.at("period").get_to(c.period);
|
||||
j.at("category").get_to(c.category);
|
||||
j.at("grades").get_to(c.grades);
|
||||
}
|
||||
|
||||
// ---------- GradesResponse ----------
|
||||
|
||||
void to_json(json& j, const GradesResponse& r) {
|
||||
j = json{
|
||||
{"success", r.success},
|
||||
{"totalClasses", r.totalClasses},
|
||||
{"grades", r.grades}
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const json& j, GradesResponse& r) {
|
||||
j.at("success").get_to(r.success);
|
||||
j.at("totalClasses").get_to(r.totalClasses);
|
||||
j.at("grades").get_to(r.grades);
|
||||
}
|
||||
|
||||
} // namespace api_utils
|
||||
|
||||
|
||||
// ================= API METHODS =================
|
||||
|
||||
namespace api_methods {
|
||||
|
||||
api_utils::StatusResponse get_status(std::string url) {
|
||||
cpr::Response r = cpr::Get(
|
||||
cpr::Url{url + "/health"}
|
||||
);
|
||||
|
||||
return nlohmann::json::parse(r.text)
|
||||
.get<api_utils::StatusResponse>();
|
||||
}
|
||||
|
||||
api_utils::ErrorResponse get_auth_status(
|
||||
std::string url,
|
||||
std::string username,
|
||||
std::string password
|
||||
) {
|
||||
api_utils::Login login{username, password};
|
||||
|
||||
cpr::Response r = cpr::Post(
|
||||
cpr::Url{url + "/check-auth"},
|
||||
cpr::Body{nlohmann::json(login).dump()},
|
||||
cpr::Header{{"Content-Type", "application/json"}}
|
||||
);
|
||||
|
||||
return nlohmann::json::parse(r.text)
|
||||
.get<api_utils::ErrorResponse>();
|
||||
}
|
||||
|
||||
} // namespace api_methods
|
||||
|
||||
84
src/skwyward-api-utils.hpp
Normal file
84
src/skwyward-api-utils.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace api_utils {
|
||||
|
||||
// ---------- Auth ----------
|
||||
|
||||
struct Login {
|
||||
std::string username;
|
||||
std::string password;
|
||||
};
|
||||
|
||||
// ---------- Simple responses ----------
|
||||
|
||||
struct ErrorResponse {
|
||||
bool success{};
|
||||
std::optional<std::string> error;
|
||||
};
|
||||
|
||||
struct StatusResponse {
|
||||
std::string status;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
// ---------- Grades ----------
|
||||
|
||||
struct AssignmentGrade {
|
||||
std::string name;
|
||||
std::string dueDate;
|
||||
double score; // <-- parsed from "72.00%"
|
||||
std::string attempts;
|
||||
bool isMajorGrade;
|
||||
};
|
||||
|
||||
struct ClassGrades {
|
||||
std::string className;
|
||||
std::string teacher;
|
||||
std::string period;
|
||||
std::string category;
|
||||
std::vector<AssignmentGrade> grades;
|
||||
};
|
||||
|
||||
struct GradesResponse {
|
||||
bool success;
|
||||
int totalClasses;
|
||||
std::vector<ClassGrades> grades;
|
||||
};
|
||||
|
||||
// ---------- nlohmann::json hooks ----------
|
||||
|
||||
void to_json(nlohmann::json& j, const Login& r);
|
||||
void from_json(const nlohmann::json& j, Login& r);
|
||||
|
||||
void to_json(nlohmann::json& j, const ErrorResponse& r);
|
||||
void from_json(const nlohmann::json& j, ErrorResponse& r);
|
||||
|
||||
void to_json(nlohmann::json& j, const StatusResponse& r);
|
||||
void from_json(const nlohmann::json& j, StatusResponse& r);
|
||||
|
||||
void to_json(nlohmann::json& j, const AssignmentGrade& g);
|
||||
void from_json(const nlohmann::json& j, AssignmentGrade& g);
|
||||
|
||||
void to_json(nlohmann::json& j, const ClassGrades& c);
|
||||
void from_json(const nlohmann::json& j, ClassGrades& c);
|
||||
|
||||
void to_json(nlohmann::json& j, const GradesResponse& r);
|
||||
void from_json(const nlohmann::json& j, GradesResponse& r);
|
||||
|
||||
} // namespace api_utils
|
||||
|
||||
|
||||
namespace api_methods {
|
||||
api_utils::StatusResponse get_status(std::string url);
|
||||
api_utils::ErrorResponse get_auth_status(
|
||||
std::string url,
|
||||
std::string username,
|
||||
std::string password
|
||||
);
|
||||
}
|
||||
|
||||
0
src/types.cpp
Normal file
0
src/types.cpp
Normal file
0
src/types.hpp
Normal file
0
src/types.hpp
Normal file
Reference in New Issue
Block a user