Skip to content

Commit

Permalink
Merge branch 'main' into fix-open
Browse files Browse the repository at this point in the history
  • Loading branch information
simaosanguinho authored Dec 14, 2023
2 parents 7a7fd76 + 78b54dc commit 9934e9b
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 12 deletions.
Binary file modified instructions.pdf
Binary file not shown.
2 changes: 0 additions & 2 deletions src/client/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,6 @@ void ListUserAuctionsCommand::handleCommand(std::string args,

ListUserAuctionsRequest listUserAuctionsRequest;
listUserAuctionsRequest.userID = state.getUserID();
// THIS USER ID IS FOR TESTING PURPOSES ONLY
listUserAuctionsRequest.userID = "123456";

ListUserAuctionsResponse listUserAuctionsResponse;
state.sendUdpPacketAndWaitForReply(listUserAuctionsRequest,
Expand Down
104 changes: 99 additions & 5 deletions src/server/handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,24 +151,118 @@ void handleListUserAuctions(AuctionServerState &state, std::stringstream &buf,
(void)state;
(void)buf;
(void)addressFrom;

ListUserAuctionsRequest request;
ListUserAuctionsResponse response;

try {
request.deserialize(buf);
state.cdebug << "[ListUserAuctions] User "
<< " requested to list auctions" << std::endl;

if (state.usersManager.isUserLoggedIn(request.userID) != INVALID) {
response.auctions = state.auctionManager.listUserAuctions(request.userID);
response.status = ListUserAuctionsResponse::OK;
state.cdebug << "[ListUserAuctions] Auctions listed successfully"
<< std::endl;
} else {
response.status = ListUserAuctionsResponse::NLG;
state.cdebug << "[ListUserAuctions] User " << request.userID
<< " is not logged in" << std::endl;
}

} catch (NoAuctionsException &e) {
state.cdebug << "[ListUserAuctions] No auctions to list" << std::endl;
response.status = ListUserAuctionsResponse::NOK;
} catch (InvalidPacketException &e) {
state.cdebug << "[ListUserAuctions] Invalid packet received" << std::endl;
response.status = ListUserAuctionsResponse::ERR;
} catch (std::exception &e) {
std::cerr << "[ListUserAuctions] There was an unhandled exception that "
"prevented the user from listing auctions"
<< e.what() << std::endl;
return;
}

send_packet(response, addressFrom.socket,
(struct sockaddr *)&addressFrom.addr, addressFrom.size);
}

void handleListUserBids(AuctionServerState &state, std::stringstream &buf,
SocketAddress &addressFrom) {
std::cout << "Handling list user bids request" << std::endl;

(void)state;
(void)buf;
(void)addressFrom;

ListUserBidsRequest request;
ListUserBidsResponse response;

try {
request.deserialize(buf);
state.cdebug << "[ListUserBids] User "
<< " requested to list bids" << std::endl;

if (state.usersManager.isUserLoggedIn(request.userID) != INVALID) {
response.auctions =
state.auctionManager.getAuctionsBiddedByUser(request.userID);

response.status = ListUserBidsResponse::OK;
state.cdebug << "[ListUserBids] Bids listed successfully" << std::endl;
} else {
response.status = ListUserBidsResponse::NLG;
state.cdebug << "[ListUserBids] User " << request.userID
<< " is not logged in" << std::endl;
}

} catch (NoOngoingBidsException &e) {
state.cdebug << "[ListUserBids] User " << request.userID
<< " has not bidded on any auction" << std::endl;
response.status = ListUserBidsResponse::NOK;
} catch (InvalidPacketException &e) {
state.cdebug << "[ListUserBids] Invalid packet received" << std::endl;
response.status = ListUserBidsResponse::ERR;
} catch (std::exception &e) {
std::cerr << "[ListUserBids] There was an unhandled exception that "
"prevented the user from listing bids: "
<< e.what() << std::endl;
return;
}

send_packet(response, addressFrom.socket,
(struct sockaddr *)&addressFrom.addr, addressFrom.size);
}

void handleListAuctions(AuctionServerState &state, std::stringstream &buf,
SocketAddress &addressFrom) {
std::cout << "Handling list auctions request" << std::endl;

(void)state;
(void)buf;
(void)addressFrom;
ListAuctionsRequest request;
ListAuctionsResponse response;

try {
request.deserialize(buf);
state.cdebug << "[ListAuctions] User "
<< " requested to list auctions" << std::endl;

response.auctions = state.auctionManager.listAuctions();
response.status = ListAuctionsResponse::OK;
state.cdebug << "[ListAuctions] Auctions listed successfully" << std::endl;

} catch (NoAuctionsException &e) {
state.cdebug << "[ListAuctions] No auctions to list" << std::endl;
response.status = ListAuctionsResponse::NOK;
} catch (InvalidPacketException &e) {
state.cdebug << "[ListAuctions] Invalid packet received" << std::endl;
response.status = ListAuctionsResponse::ERR;
} catch (std::exception &e) {
std::cerr << "[ListAuctions] There was an unhandled exception that "
"prevented the user from listing auctions"
<< e.what() << std::endl;
return;
}

send_packet(response, addressFrom.socket,
(struct sockaddr *)&addressFrom.addr, addressFrom.size);
}

void handleShowRecord(AuctionServerState &state, std::stringstream &buf,
Expand Down
1 change: 1 addition & 0 deletions src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ void setupDB() {
std::string nAuctions = std::to_string(count);
nAuctions += "\n";
write_to_file(nextAuctionFile, nAuctions);

};

void wait_for_udp_packet(AuctionServerState &state) {
Expand Down
175 changes: 175 additions & 0 deletions src/server/server_auction.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "server_auction.hpp"
#include "../utils/protocol.hpp"

uint32_t AuctionManager::openAuction(std::string userID,
std::string auctionName,
Expand Down Expand Up @@ -63,6 +64,7 @@ std::string AuctionManager::getnextAuctionID() {
}
}


void validateOpenAuctionArgs(std::string userID, std::string password,
std::string auctionName, uint32_t startValue,
uint32_t timeActive, std::string assetFilename,
Expand All @@ -77,4 +79,177 @@ void validateOpenAuctionArgs(std::string userID, std::string password,
throw InvalidPacketException();
}
return;
}

std::vector<std::pair<std::string, uint8_t>> AuctionManager::listAuctions() {

std::vector<std::pair<std::string, uint8_t>> auctions;
if (directory_exists(AUCTIONDIR) == INVALID) {
throw std::exception();
}
// get number of auctions in DB
std::string next_auction_path = AUCTIONDIR;
next_auction_path += "/next_auction.txt";
std::string nextAuctionID;

read_from_file(next_auction_path, nextAuctionID);
int nAuctions = std::stoi(nextAuctionID) - 1;

// no auctions in DB
if (nAuctions == 0) {
throw NoAuctionsException();
}

// get all auctions
for (int i = 1; i <= nAuctions; i++) {
std::string auction_dir = AUCTIONDIR;
auction_dir += "/" + intToStringWithZeros(i);
std::string auction_end_file =
auction_dir + "/" + "END_" + intToStringWithZeros(i) + ".txt";

// if auction directory does not exist - auction count was compromissed
if (directory_exists(auction_dir) == INVALID) {
throw std::exception();
}

// auction still active - no end file
if (file_exists(auction_end_file) == INVALID) {

auctions.push_back(std::make_pair(intToStringWithZeros(i), 1));
}
// auction ended
else {
auctions.push_back(std::make_pair(intToStringWithZeros(i), 0));
}
}

return auctions;
}

std::string AuctionManager::getNextAuctionID() {
try {
std::string nextAuctionID;
std::string nextAuctionPath = AUCTIONDIR;
nextAuctionPath += "/next_auction.txt";
read_from_file(nextAuctionPath, nextAuctionID);

// update next auction id
int nextAuctionID_int = std::stoi(nextAuctionID);
nextAuctionID_int++;
write_to_file(nextAuctionPath, std::to_string(nextAuctionID_int));

return nextAuctionID;
} catch (std::exception &e) {
throw;
}
}

std::vector<std::pair<std::string, uint8_t>>
AuctionManager::listUserAuctions(std::string userID) {

std::vector<std::pair<std::string, uint8_t>> auctions;
std::vector<std::pair<std::string, uint8_t>> userAuctions;

try {
AuctionManager auctionManager;

auctions = auctionManager.listAuctions();
for (auto auction : auctions) {
std::string auctionInfo = auctionManager.getAuctionInfo(auction.first);
std::string auctionOwner = auctionInfo.substr(0, auctionInfo.find(" "));
if (auctionOwner == userID) {
userAuctions.push_back(auction);
}
}

if (userAuctions.size() == 0) {
throw NoAuctionsException();
}
return userAuctions;

} catch (NoAuctionsException &e) {
throw;
} catch (std::exception &e) {
throw;
}
}

std::string AuctionManager::getAuctionInfo(std::string auctionID) {
try {
std::string auctionPath = AUCTIONDIR;
auctionPath += "/" + auctionID;
std::string start = auctionPath + "/" + "START_" + auctionID + ".txt";
std::string auctionInfo;
read_from_file(start, auctionInfo);
return auctionInfo;
} catch (std::exception &e) {
throw;
}
}

std::vector<std::string>
AuctionManager::getAuctionBidders(std::string auctionID) {
try {
std::string auctionPath = AUCTIONDIR;
auctionPath += "/" + auctionID;
std::string auctionBidsPath = auctionPath + "/BIDS";

// iterate over all files in BIDS directory
std::vector<std::string> auctionsBidders;

int i = 0;
for (const auto &entry :
std::filesystem::directory_iterator(auctionBidsPath)) {
if (entry.is_regular_file() && entry.path().extension() == ".txt") {

std::string auctionBidFile = entry.path();

std::string bidder;
bidder = getFirstWord(auctionBidFile);
auctionsBidders.push_back(bidder);
}
i++;
}

if (auctionsBidders.size() == 0) {
throw NoOngoingBidsException();
}

return auctionsBidders;
} catch (std::exception &e) {
throw;
}
}

std::vector<std::pair<std::string, uint8_t>>
AuctionManager::getAuctionsBiddedByUser(std::string userID) {

std::vector<std::pair<std::string, uint8_t>> auctions;
std::vector<std::pair<std::string, uint8_t>> auctionsBiddedByUser;
try {
AuctionManager auctionManager;

auctions = auctionManager.listAuctions();
for (auto auction : auctions) {
std::vector<std::string> auctionBidders =
auctionManager.getAuctionBidders(auction.first);
for (auto bidder : auctionBidders) {
if (bidder == userID) {
auctionsBiddedByUser.push_back(auction);
}
}
}

if (auctionsBiddedByUser.size() == 0) {
throw NoOngoingBidsException();
}

return auctionsBiddedByUser;
} catch (NoOngoingBidsException &e) {
throw;
} catch (NoAuctionsException &e) {
throw NoOngoingBidsException();
} catch (std::exception &e) {
throw;
}
}
30 changes: 30 additions & 0 deletions src/server/server_auction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,45 @@ class AuctionManager {
std::string assetFilename, std::string assetFilePath);
std::string getnextAuctionID();

std::string getNextAuctionID();

std::vector<std::pair<std::string, uint8_t>> listAuctions();

std::vector<std::pair<std::string, uint8_t>>
listUserAuctions(std::string userID);

std::string getAuctionInfo(std::string auctionID);

std::vector<std::string> getAuctionBidders(std::string auctionID);

std::vector<std::pair<std::string, uint8_t>>
getAuctionsBiddedByUser(std::string userID);

/* lists auctions in which an user has bidded*/
std::vector<std::pair<std::string, uint8_t>> listUserBids(std::string userID);

// constructor
AuctionManager() = default;
// destructor
~AuctionManager() = default;
};


void validateOpenAuctionArgs(std::string userID, std::string password,
std::string auctionName, uint32_t startValue,
uint32_t timeActive, std::string assetFilename,
uint32_t assetSize);

class NoAuctionsException : public std::runtime_error {
public:
NoAuctionsException()
: std::runtime_error("No auctions have been opened yet") {}
};

class NoOngoingBidsException : public std::runtime_error {
public:
NoOngoingBidsException()
: std::runtime_error("The user has not yet bidded") {}
};

#endif
Loading

0 comments on commit 9934e9b

Please sign in to comment.