before parsing grades
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
build/**
|
build/**
|
||||||
|
config.toml
|
||||||
|
.cache/**
|
||||||
|
|||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
|||||||
[submodule "external/tomlplusplus"]
|
[submodule "external/tomlplusplus"]
|
||||||
path = external/tomlplusplus
|
path = external/tomlplusplus
|
||||||
url = https://github.com/marzer/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 setup
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
project(mainframe LANGUAGES CXX)
|
project(skyward LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
@@ -27,6 +27,7 @@ add_subdirectory(external/spdlog)
|
|||||||
add_subdirectory(external/cpr)
|
add_subdirectory(external/cpr)
|
||||||
add_subdirectory(external/clickhouse-cpp)
|
add_subdirectory(external/clickhouse-cpp)
|
||||||
add_subdirectory(external/tomlplusplus)
|
add_subdirectory(external/tomlplusplus)
|
||||||
|
add_subdirectory(external/json)
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Executable
|
# Executable
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
@@ -63,6 +64,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
|
|||||||
cpr::cpr
|
cpr::cpr
|
||||||
clickhouse-cpp-lib
|
clickhouse-cpp-lib
|
||||||
tomlplusplus::tomlplusplus
|
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