Mercurial > hg > soniczoomios
view eventLogger.mm @ 25:f42a00e3f22d
Logs condensed slightly. Questionnaire button enable.
double precision location!!!
author | Robert Tubb <rt300@eecs.qmul.ac.uk> |
---|---|
date | Fri, 01 Feb 2013 17:39:19 +0000 |
parents | a4908ad8c78e |
children | ae4d2c3ce5e0 |
line wrap: on
line source
// // eventLogger.mm // oscSenderExample // // Created by Robert Tubb on 05/11/2012. // // //--------------------------------------------------------------------------- #include "eventLogger.h" EventLogger eventLogger; //--------------------------------------------------------------------------- EventLogger::EventLogger(){ //QuestionnaireViewController * questionnaireViewController; consentGiven = true; // unless told otherwise by introView loggingEnabled = true; serverConnectionOK = false; questionnaireCompleted = false; questionnaireUploaded = false; ofxiPhoneDeviceType iOSdeviceType = ofxiPhoneGetDeviceType(); cout << "Device: " << iOSdeviceType << '\n'; nextUploadQty = UPLOAD_CHUNK_SIZE; // amount of data uploaded is always more than UPLOAD_CHUNK_SIZE events } //--------------------------------------------------------------------------- // draw() - show path of last N scroll events - can be scrubbed along? // //--------------------------------------------------------------------------- void EventLogger::init(){ readJsonToLog(ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME); sessionStartTime = ofGetSystemTime(); testConnection(); logEvent(APP_STARTED); } //--------------------------------------------------------------------------- void EventLogger::questionnaireAnswersObtained(vector<int> answers){ questionnaireCompleted = true; questionnaireAnswers = answers; uploadQuestionnaire(); } //--------------------------------------------------------------------------- bool EventLogger::uploadQuestionnaire(){ // show indicator cout << "^^^^^^^^ UPLOADING QUESTIONNAIRE ^^^^^^^^ \n"; questionnaireUploaded = sendToServer("questionnaire", questionnaireToJson()); return questionnaireUploaded; } //--------------------------------------------------------------------------- bool EventLogger::sendToServer(string functionName, Json::Value jsonData){ bool sent; string request; if(functionName == "testConnection"){ request = "http://127.0.0.1:8080/testservice/testConnection?jsontext="; }else if(functionName == "questionnaire"){ request = "http://127.0.0.1:8080/testservice/questionnaire?jsontext="; }else if(functionName == "eventlog"){ request = "http://127.0.0.1:8080/testservice/eventlog?jsontext="; } Json::FastWriter writer; string jsontext = writer.write( jsonData ); if (!jsontext.empty() && jsontext[jsontext.length()-1] == '\n') { jsontext.erase(jsontext.length()-1); } request.append(jsontext); ofURLFileLoader fileLoader; ofHttpResponse resp; resp = fileLoader.get(request); //fileLoader.getAsync(request); cout << "HTTP STATUS " << resp.status << "\n"; cout << "HTTP ERROR " << resp.error << "\n"; cout << "HTTP DATA " << resp.data << "\n"; // ofBuffer stringstream response; response << resp.data; if (resp.status == 200){ if(response.str() == "OK"){ sent = true; }else{ // not ok // problem serverside sent = false; } }else{ sent = false; // SHOW AN ALERT TO USER? } return sent; } //--------------------------------------------------------------------------- bool EventLogger::testConnection(){ Json::Value root; root["test"] = "test"; serverConnectionOK = sendToServer("testConnection", root); if (serverConnectionOK){ cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n"; }else{ cout << "server connection ERROR \n"; } } //--------------------------------------------------------------------------- void EventLogger::readJsonToLog(const string &jsonFile){ Json::Value root; Json::Reader reader; ifstream theFile(jsonFile.c_str()); stringstream fileText; string line; if(!theFile){ firstEverAppOpen(); return; }else{ while(theFile){ theFile >> line; // cout << line; // lots!!!! fileText << line; } theFile.close(); } cout << "size of log JSON string:" << fileText.str().length() << "BYTES \n"; bool parsingSuccessful = reader.parse( fileText.str(), root ); if ( !parsingSuccessful ) { // report to the user the failure and their locations in the document. std::cout << "Failed to parse event log JSON: \n" << reader.getFormattedErrorMessages(); return; } // now put user deets into variables userName = root["userName"].asString(); deviceID = root["deviceID"].asLargestInt(); nextUploadNumber = root["uploadNumber"].asInt(); savedInteractionTime = root["savedInteractionTime"].asLargestInt(); questionnaireCompleted = root["questionnaireCompleted"].asBool(); questionnaireUploaded = root["questionnaireUploaded"].asBool(); if(questionnaireCompleted && !questionnaireUploaded){ // then read it in and upload it Json::Value JArray = root["questionnaireAnswers"]; if(JArray.size() < 2){ cout << "Error - status of questionnaire is wierd\n"; } for ( unsigned int i = 0; i < JArray.size(); i++ ) { questionnaireAnswers.push_back(JArray[1].asInt()); } uploadQuestionnaire(); } // check for unuploaded evts const Json::Value jlogs = root["events"]; for ( int index = 0; index < jlogs.size(); ++index ) theEvents.push_back(lEvent(jlogs[index])); if(theEvents.size() > nextUploadQty){ //try to upload uploadEventLog(); } // TODO if the total interaction time is greater than a certain amount && no questions answered - questionnaire time! cout << "Total interaction time: " << savedInteractionTime << '\n'; } //--------------------------------------------------------------------------- bool EventLogger::uploadEventLog(){ // show indicator cout << "^^^^^^^^ ATTEMPTING TO UPLOAD " << theEvents.size() << " EVENTS ^^^^^^^^ .\n"; bool logUploaded = sendToServer("eventlog", logsToJson()); if(!logUploaded){ // try later nextUploadQty += UPLOAD_CHUNK_SIZE; }else{ // if success - clear memory theEvents.clear(); cout << "UPLOAD SUCCESS\n"; nextUploadNumber++; } return logUploaded; } //---------------------------------------------------------------------------- //void EventLogger::deleteLogFile(){ //--------------------------------------------------------------------------- void EventLogger::firstEverAppOpen(){ cout<<"no event log file - first APP open\n"; nextUploadNumber = 0; deviceID = ofGetSystemTimeMicros(); savedInteractionTime = 0; questionnaireCompleted = false; questionnaireUploaded = false; ((testApp *)ofGetAppPtr())->showIntro(); consentGiven = false; } //--------------------------------------------------------------------------- // called from alertView OK in iViewController void EventLogger::setUsername(const char *u){ userName = u; } //--------------------------------------------------------------------------- // log zoom event void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){ //cout << "log: " << evtType << "\n"; // scroll has 2 double coords // zoom has 1 double scale // save preset has 2 coords // switch view has view type // slider change has int slider index and 1 float value // get time for key index // thinFactor if(!loggingEnabled) return; switch ( evtType ) { case SAVE_PRESET: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); // Code break; case SAVE_DESET: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); break; case SCROLL: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); break; case SCROLL_STOPPED: theEvents.push_back(lEvent(evtType,centre.x,centre.y)); cout << "SCROLL STOPPED EVENT\n"; break; case SNAPPED_TO_PRESET: theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID)); cout << "SCROLL STOPPED EVENT\n"; break; case ZOOM: theEvents.push_back(lEvent(evtType,scale)); break; case CHANGE_SLIDER: theEvents.push_back(lEvent(evtType,sliderVal , 0.0 , sliderID)); break; case SWAP_VIEW: theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view break; default: // default is just an event type with no values theEvents.push_back(lEvent(evtType)); break; } if(theEvents.size() > nextUploadQty){ //try to upload uploadEventLog(); } //sessionTime = (ofGetSystemTime() - sessionStartTime); totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); if(totalInteractionTime > QUESTIONNAIRE_ENABLE_TIME){ TopButtonViewController *tbvc = ((testApp *)ofGetAppPtr())->topButtonViewController; [tbvc enableQuestionButton]; } } //--------------------------------------------------------------------------- void EventLogger::exitAndSave(){ if(!consentGiven){ logEvent(CONSENT_DENIED); Json::Value jlogs = logsToJson(); // try to upload TODO (no - might hang and prevent exit???) uploadEventLog(); return; } logEvent(APP_EXITED); savedInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); // save user details string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME; // try to upload TODO (no - might hang and prevent exit???) uploadEventLog(); // write to file // json without the logs that were uploaded! Json::Value jlogs = logsToJson(); ofFile logFile(fname,ofFile::WriteOnly); logFile << jlogs; } //--------------------------------------------------------------------------- Json::Value EventLogger::logsToJson(){ // put all logged events into Json formatted string Json::Value root; vector<lEvent>::iterator eventIter; root["programVersion"] = PROGRAM_VERSION; root["userName"] = userName; root["deviceID"] = deviceID; root["uploadNumber"] = nextUploadNumber; root["iOSdeviceType"] = iOSdeviceType; root["savedInteractionTime"] = savedInteractionTime; root["questionnaireCompleted"] = questionnaireCompleted; root["questionnaireUploaded"] = questionnaireUploaded; if(questionnaireCompleted && !questionnaireUploaded){ root["qAnswers"] = questionnaireToJson(); } int i = 0; for(eventIter = theEvents.begin(); eventIter < theEvents.end(); eventIter++){ root["events"][i] = (*eventIter).eventToJson(); i++; } root["numEventsHere"] = i; return root; } //--------------------------------------------------------------------------- Json::Value EventLogger::questionnaireToJson(){ // put all answers into Json formatted string Json::Value root; vector<int>::iterator aIter; Json::Value questionnaire; int i = 0; for(aIter = questionnaireAnswers.begin(); aIter < questionnaireAnswers.end(); aIter++){ questionnaire[i] = (*aIter); i++; } root["qAnswers"] = questionnaire; root["userName"] = userName; root["deviceID"] = deviceID; root["iOSdeviceType"] = iOSdeviceType; root["programVersion"] = PROGRAM_VERSION; return root; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //---------------------------------------------------------------------------