#include #include #include #include #include #include #include "Config.h" #include "Client.h" #include "Graphics.h" #include "interface/Point.h" #include "search/Save.h" #include "cajun/reader.h" #include "cajun/writer.h" #include "cajun/elements.h" Client::Client() { int i = 0; http_init("wwwcache.lancs.ac.uk:8080"); for(i = 0; i < THUMB_CACHE_SIZE; i++) { thumbnailCache[i] = NULL; } for(i = 0; i < IMGCONNS; i++) { activeThumbRequests[i] = NULL; activeThumbRequestTimes[i] = 0; activeThumbRequestCompleteTimes[i] = 0; } } Client::~Client() { ClearThumbnailRequests(); http_done(); } LoginStatus Client::Login(string username, string password) { std::stringstream urlStream; char * data; int dataStatus, dataLength; data = http_auth_get("http://" SERVER "/Login.json", (char*)username.c_str(), (char*)password.c_str(), NULL, &dataStatus, &dataLength); std::cout << data << std::endl; if(dataStatus == 200 && data) { std::istringstream dataStream(data); json::Object objDocument; json::Reader::Read(objDocument, dataStream); json::Number tempStatus = objDocument["Status"]; free(data); if(tempStatus.Value() == 1) { return LoginOkay; } else if(tempStatus.Value() == 0) { return LoginPasswordInvalid; } else { return LoginError; } } if(data) { free(data); } return LoginError; } Save * Client::GetSave(int saveID, int saveDate) { lastError = ""; std::stringstream urlStream; urlStream << "http://" << SERVER << "/Browse/View.json?ID=" << saveID; if(saveDate) { urlStream << "&Date=" << saveDate; } char * data; int dataStatus, dataLength; //Save(int _id, int _votesUp, int _votesDown, string _userName, string _name, string description_, string date_, bool published_): data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength); if(dataStatus == 200 && data) { try { std::istringstream dataStream(data); json::Object objDocument; json::Reader::Read(objDocument, dataStream); json::Number tempID = objDocument["ID"]; json::Number tempScoreUp = objDocument["ScoreUp"]; json::Number tempScoreDown = objDocument["ScoreDown"]; json::String tempUsername = objDocument["Username"]; json::String tempName = objDocument["Name"]; json::String tempDescription = objDocument["Description"]; json::String tempDate = objDocument["Date"]; json::Boolean tempPublished = objDocument["Published"]; return new Save( tempID.Value(), tempScoreUp.Value(), tempScoreDown.Value(), tempUsername.Value(), tempName.Value(), tempDescription.Value(), tempDate.Value(), tempPublished.Value() ); } catch (json::Exception &e) { lastError = "Could not read response"; return NULL; } } else { lastError = http_ret_text(dataStatus); } return NULL; } Thumbnail * Client::GetPreview(int saveID, int saveDate) { std::stringstream urlStream; urlStream << "http://" << SERVER << "/Get.api?Op=thumblarge&ID=" << saveID; if(saveDate) { urlStream << "&Date=" << saveDate; } pixel * thumbData; char * data; int status, data_size, imgw, imgh; data = http_simple_get((char *)urlStream.str().c_str(), &status, &data_size); if (status == 200 && data) { thumbData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh); if(data) { free(data); } if(thumbData) { return new Thumbnail(saveID, saveDate, thumbData, ui::Point(imgw, imgh)); } else { return new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128)); } } else { if(data) { free(data); } return new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128)); } } std::vector * Client::SearchSaves(int start, int count, string query, string sort, int & resultCount) { lastError = ""; resultCount = 0; std::vector * saveArray = new std::vector(); std::stringstream urlStream; char * data; int dataStatus, dataLength; urlStream << "http://" << SERVER << "/Browse.json?Start=" << start << "&Count=" << cout; if(query.length() || sort.length()) { urlStream << "&Search_Query="; if(query.length()) urlStream << query; if(sort == "date") { if(query.length()) urlStream << " "; urlStream << "sort:" << sort; } } data = http_simple_get((char *)urlStream.str().c_str(), &dataStatus, &dataLength); if(dataStatus == 200 && data) { try { std::istringstream dataStream(data); json::Object objDocument; json::Reader::Read(objDocument, dataStream); json::Number tempCount = objDocument["Count"]; resultCount = tempCount.Value(); json::Array savesArray = objDocument["Saves"]; for(int j = 0; j < savesArray.Size(); j++) { json::Number tempID = savesArray[j]["ID"]; json::Number tempScoreUp = savesArray[j]["ScoreUp"]; json::Number tempScoreDown = savesArray[j]["ScoreDown"]; json::String tempUsername = savesArray[j]["Username"]; json::String tempName = savesArray[j]["Name"]; saveArray->push_back( new Save( tempID.Value(), tempScoreUp.Value(), tempScoreDown.Value(), tempUsername.Value(), tempName.Value() ) ); } } catch (json::Exception &e) { lastError = "Could not read response"; } } else { lastError = http_ret_text(dataStatus); } if(data) free(data); return saveArray; } void Client::ClearThumbnailRequests() { for(int i = 0; i < IMGCONNS; i++) { if(activeThumbRequests[i]) { http_async_req_close(activeThumbRequests[i]); activeThumbRequests[i] = NULL; activeThumbRequestTimes[i] = 0; activeThumbRequestCompleteTimes[i] = 0; } } } Thumbnail * Client::GetThumbnail(int saveID, int saveDate) { std::stringstream urlStream; std::stringstream idStream; int i = 0, currentTime = time(NULL); //Check active requests for any "forgotten" requests for(i = 0; i < IMGCONNS; i++) { //If the request is active, and we've recieved a response if(activeThumbRequests[i] && http_async_req_status(activeThumbRequests[i])) { //If we haven't already, mark the request as completed if(!activeThumbRequestCompleteTimes[i]) { activeThumbRequestCompleteTimes[i] = time(NULL); } else if(activeThumbRequestCompleteTimes[i] < (currentTime-2)) //Otherwise, if it completed more than 2 seconds ago, destroy it. { http_async_req_close(activeThumbRequests[i]); activeThumbRequests[i] = NULL; activeThumbRequestTimes[i] = 0; activeThumbRequestCompleteTimes[i] = 0; } } } for(i = 0; i < THUMB_CACHE_SIZE; i++) { if(thumbnailCache[i] && thumbnailCache[i]->ID == saveID && thumbnailCache[i]->Datestamp == saveDate) return thumbnailCache[i]; } urlStream << "http://" << SERVER << "/Get.api?Op=thumbsmall&ID=" << saveID; if(saveDate) { urlStream << "&Date=" << saveDate; } idStream << saveID << ":" << saveDate; std::string idString = idStream.str(); bool found = false; for(i = 0; i < IMGCONNS; i++) { if(activeThumbRequests[i] && activeThumbRequestIDs[i] == idString) { found = true; if(http_async_req_status(activeThumbRequests[i])) { pixel * thumbData; char * data; int status, data_size, imgw, imgh; data = http_async_req_stop(activeThumbRequests[i], &status, &data_size); free(activeThumbRequests[i]); activeThumbRequests[i] = NULL; if (status == 200 && data) { thumbData = Graphics::ptif_unpack(data, data_size, &imgw, &imgh); if(data) { free(data); } thumbnailCacheNextID %= THUMB_CACHE_SIZE; if(thumbnailCache[thumbnailCacheNextID]) { delete thumbnailCache[thumbnailCacheNextID]; } if(thumbData) { thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, thumbData, ui::Point(imgw, imgh)); } else { thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128)); } return thumbnailCache[thumbnailCacheNextID++]; } else { if(data) { free(data); } thumbnailCacheNextID %= THUMB_CACHE_SIZE; if(thumbnailCache[thumbnailCacheNextID]) { delete thumbnailCache[thumbnailCacheNextID]; } thumbnailCache[thumbnailCacheNextID] = new Thumbnail(saveID, saveDate, (pixel *)malloc((128*128) * PIXELSIZE), ui::Point(128, 128)); return thumbnailCache[thumbnailCacheNextID++]; } } } } if(!found) { for(i = 0; i < IMGCONNS; i++) { if(!activeThumbRequests[i]) { activeThumbRequests[i] = http_async_req_start(NULL, (char *)urlStream.str().c_str(), NULL, 0, 1); activeThumbRequestTimes[i] = currentTime; activeThumbRequestCompleteTimes[i] = 0; activeThumbRequestIDs[i] = idString; return NULL; } } } //http_async_req_start(http, urlStream.str().c_str(), NULL, 0, 1); return NULL; }