Skip to content

Commit

Permalink
refactor: logic.hpp method to fetch game played within month
Browse files Browse the repository at this point in the history
  • Loading branch information
AmanMenda committed May 3, 2024
1 parent eb05b69 commit a5722b0
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 104 deletions.
30 changes: 20 additions & 10 deletions Libraries/include/Logic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,34 @@
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"

using namespace rapidjson;

namespace Stuckfish
{
// consider creating a structure to hold games data and a vector of this structure in Logic.
// consider creating a C-style structure to hold games data and a vector of this structure in Logic.
struct GamesData
{
std::string pgn;
std::string timeClass;
std::string gameResult;
std::string whiteRating;
std::string blackRating;
std::string whiteUsername;
std::string blackUsername;
};

class Logic
{
public:
// method to check if username exists on Chess.com
bool IsChessDotComUser(const std::string& username);
// method to fetch all the games played by the "specified" user in the month.
Logic() : _gamesData()
{};

bool IsChessDotComUser(const std::string& username);
void GamesPlayedWithinPeriod(const std::string& username, const std::string& year, const std::string& month);
void GetInfosFromListOfGamesPlayed(const std::string& username, const Document& doc);

private:
std::string _whiteUsername = "";
std::string _blackUsername = "";
std::string _whiteRating = "";
std::string _blackRating = "";
std::string _gameFormat = "";
std::string _pgn = "";
std::vector<GamesData> _gamesData;
};
}

174 changes: 80 additions & 94 deletions Sources/App/Logic.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
#include "../../Libraries/include/Logic.hpp"

using namespace rapidjson;

static std::string to_lower(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), [](char c) { return std::tolower(c); });
return s;
}

static std::string extractField(const Value& jsonObject, const std::string& fieldName) {
static std::string extractString(const Value& jsonObject, const std::string& fieldName) {
if (jsonObject.HasMember(fieldName.c_str()) && jsonObject[fieldName.c_str()].IsString()) {
return jsonObject[fieldName.c_str()].GetString();
}
return ""; // Return empty string if field not found or not a string
}

static std::string extractInt(const Value& jsonObject, const std::string& fieldName) {
if (jsonObject.HasMember(fieldName.c_str()) && jsonObject[fieldName.c_str()].IsInt()) {
return std::to_string(jsonObject[fieldName.c_str()].GetInt());
}
return ""; // Return empty string if field not found or not a string
}

namespace Stuckfish
{
bool Logic::IsChessDotComUser(const std::string& username)
Expand All @@ -28,112 +33,93 @@ namespace Stuckfish
return false;
}

void Logic::GamesPlayedWithinPeriod(const std::string& username, const std::string& year, const std::string& month)
void Logic::GetInfosFromListOfGamesPlayed(const std::string& username, const Document& doc)
{
std::string url = "https://api.chess.com/pub/player/" + to_lower(username) + "/games/" + year + '/' + month;

cpr::Response res = cpr::Get(cpr::Url{ url });

if (res.status_code == cpr::status::HTTP_OK)
// Check if parsing succeeded
if (!doc.HasParseError())
{
rapidjson::Document doc;
doc.Parse(res.text.c_str());

// Check if parsing succeeded
if (!doc.HasParseError())
if (doc.HasMember("games") && doc["games"].IsArray())
{
const Value& gamesArray = doc["games"];

// Check if the JSON contains the field "a"
if (doc.HasMember("games") && doc["games"].IsArray())
if (gamesArray.Empty())
{
const Value& gamesArray = doc["games"];

if (gamesArray.Empty())
{
// display on the window "No games found"
// Log in the local console the same thing
std::cout << "No games found !\n";
return;
}
// Iterate over the array and do whatever you need with each game object
for (SizeType i = 0; i < gamesArray.Size(); ++i) {
const Value& game = gamesArray[i];

// TODO: refactor this and handle exceptions.
// get white username and rating -- Either create method to extract field or a specific method to get players infos.
if (game.HasMember("white") && game["white"].HasMember("username") &&
game["white"].HasMember("rating"))
{
_whiteUsername = game["white"]["username"].GetString();
_whiteRating = std::to_string(game["white"]["rating"].GetInt());

std::cout << "White infos: " << _whiteUsername << '(' << _whiteRating << ')' << std::endl;
}
// get black username and rating
if (game.HasMember("black") && game["black"].HasMember("username") &&
game["black"].HasMember("rating"))
{
_blackUsername = game["black"]["username"].GetString();
_blackRating = std::to_string(game["black"]["rating"].GetInt());

std::cout << "Black infos: " << _blackUsername << '(' << _blackRating << ')' << std::endl;
}
// get time_class
if (game.HasMember("time_class") && game["time_class"].IsString())
{
_gameFormat = game["time_class"].GetString();

std::cout << "Game format: " << _gameFormat << std::endl;
}
//get pgn
if (game.HasMember("pgn") && game["pgn"].IsString())
{
_pgn = game["pgn"].GetString();
//std::cout << "Pgn: " << _pgn;
}

// find if player has played as white or black and display if he won or lost the game.
if (_whiteUsername == username)
{
if (game["white"]["result"] != "win")
{
// Print the result on the button
std::cout << "Status: lost !\n";
}
else
{
std::cout << "Status: Won !\n";
}
}
else
{
if (game["black"]["result"] != "win")
{
// Print the result on the button
std::cout << "Status: lost !\n";
}
else
{
std::cout << "Status: Won !\n";
}
}
std::cout << "\n";
}
}
else {
std::cerr << "JSON does not contain a valid 'games' array field." << std::endl;
// display on the window "No games found"
// Log in the local console the same thing
std::cout << "No games found !\n";
return;
}
}
// Iterate over the array and do whatever you need with each game object
for (SizeType i = 0; i < gamesArray.Size(); ++i) {
const Value& game = gamesArray[i];
GamesData gameData;

// get white username and rating
if ((gameData.whiteUsername = extractString(game["white"], "username")) == "")
std::cerr << "Unable to get white username\n";
if ((gameData.whiteRating = extractInt(game["white"], "rating")) == "")
std::cerr << "Unable to get white rating\n";

// get black username and rating
if ((gameData.blackUsername = extractString(game["black"], "username")) == "")
std::cerr << "Unable to get black username\n";
if ((gameData.blackRating = extractInt(game["black"], "rating")) == "")
std::cerr << "Unable to get black rating\n";

// get time_class
if ((gameData.timeClass = extractString(game, "time_class")) == "")
std::cerr << "Unable to get time class\n";

//get pgn
if ((gameData.pgn = extractString(game, "pgn")) == "")
std::cerr << "Unable to get png\n";

// find if player has played as white or black and display if he won or lost the game.
if (gameData.whiteUsername == username)
gameData.gameResult = game["white"]["result"] != "win" ? "Lost" : "Won";
else
gameData.gameResult = game["black"]["result"] != "win" ? "Lost" : "Won";

// insert this game data in the vector
_gamesData.push_back(gameData);
}
}
else {
std::cerr << "Parsing failed with error code " << GetParseError_En(doc.GetParseError()) << std::endl;
std::cerr << "JSON does not contain a valid 'games' array field." << std::endl;
return;
}
}
else {
std::cerr << "Parsing failed with error code " << GetParseError_En(doc.GetParseError()) << std::endl;
return;
}
}

void Logic::GamesPlayedWithinPeriod(const std::string& username, const std::string& year, const std::string& month)
{
std::string url = "https://api.chess.com/pub/player/" + to_lower(username) + "/games/" + year + '/' + month;

cpr::Response res = cpr::Get(cpr::Url{ url });

if (res.status_code == cpr::status::HTTP_OK)
{
Document doc;
doc.Parse(res.text.c_str());

GetInfosFromListOfGamesPlayed(username, doc);
}
else
{
std::cerr << "Request failed with status code: " << res.status_code << std::endl;
return;
}

for (auto g : _gamesData)
{
std::cout << "White username: " << g.whiteUsername << '(' << g.whiteRating << ")\n";
std::cout << "Black username: " << g.blackUsername << '(' << g.blackRating << ")\n";
std::cout << "Game Result: " << g.gameResult << "\n\n";
}
return;
}
}

0 comments on commit a5722b0

Please sign in to comment.