annotate eventLogger.mm @ 24:a4908ad8c78e

Top and bottom toolbars. Intro page.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Fri, 01 Feb 2013 11:16:56 +0000
parents 8c0783739337
children f42a00e3f22d
rev   line source
rt300@0 1 //
rt300@0 2 // eventLogger.mm
rt300@0 3 // oscSenderExample
rt300@0 4 //
rt300@0 5 // Created by Robert Tubb on 05/11/2012.
rt300@0 6 //
rt300@0 7 //
rt300@4 8
rt300@8 9 //---------------------------------------------------------------------------
rt300@0 10 #include "eventLogger.h"
rt300@1 11
rt300@8 12
rt300@1 13 EventLogger eventLogger;
rt300@16 14 extern UsernameAlertViewController *usernameAlertViewController;
rt300@1 15
rt300@8 16 //---------------------------------------------------------------------------
rt300@1 17 EventLogger::EventLogger(){
rt300@14 18 //QuestionnaireViewController * questionnaireViewController;
rt300@8 19
rt300@14 20
rt300@8 21 loggingEnabled = true;
rt300@22 22 serverConnectionOK = false;
rt300@22 23 questionnaireCompleted = false;
rt300@22 24 questionnaireUploaded = false;
rt300@22 25
rt300@22 26
rt300@22 27 ofxiPhoneDeviceType iOSdeviceType = ofxiPhoneGetDeviceType();
rt300@22 28 cout << "Device: " << iOSdeviceType << '\n';
rt300@22 29
rt300@9 30 nextUploadQty = 5000; // amount of data uploaded is always more than 5000 events
rt300@8 31 }
rt300@8 32 //---------------------------------------------------------------------------
rt300@24 33 // draw() - show path of last N scroll events - can be scrubbed along?
rt300@24 34 //
rt300@24 35 //---------------------------------------------------------------------------
rt300@8 36 void EventLogger::init(){
rt300@4 37
rt300@8 38 readJsonToLog(ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME);
rt300@8 39 sessionStartTime = ofGetSystemTime();
rt300@9 40
rt300@9 41 testConnection();
rt300@7 42
rt300@16 43
rt300@8 44 }
rt300@8 45 //---------------------------------------------------------------------------
rt300@22 46 void EventLogger::questionnaireAnswersObtained(vector<int> answers){
rt300@22 47
rt300@22 48 questionnaireCompleted = true;
rt300@22 49 questionnaireAnswers = answers;
rt300@22 50
rt300@22 51 uploadQuestionnaire();
rt300@22 52
rt300@22 53 }
rt300@22 54 //---------------------------------------------------------------------------
rt300@22 55 bool EventLogger::uploadQuestionnaire(){
rt300@22 56 // show indicator
rt300@22 57 cout << "^^^^^^^^ UPLOADING QUESTIONNAIRE ^^^^^^^^ \n";
rt300@22 58
rt300@22 59 questionnaireUploaded = sendToServer("questionnaire", questionnaireToJson());
rt300@22 60 return questionnaireUploaded;
rt300@22 61 }
rt300@22 62 //---------------------------------------------------------------------------
rt300@22 63 bool EventLogger::sendToServer(string functionName, Json::Value jsonData){
rt300@22 64 bool sent;
rt300@22 65 string request;
rt300@22 66
rt300@22 67 if(functionName == "testConnection"){
rt300@22 68 request = "http://127.0.0.1:8080/testservice/testConnection?jsontext=";
rt300@22 69 }else if(functionName == "questionnaire"){
rt300@22 70 request = "http://127.0.0.1:8080/testservice/questionnaire?jsontext=";
rt300@22 71 }else if(functionName == "eventlog"){
rt300@22 72 request = "http://127.0.0.1:8080/testservice/eventlog?jsontext=";
rt300@22 73 }
rt300@22 74 Json::FastWriter writer;
rt300@22 75 string jsontext = writer.write( jsonData );
rt300@22 76
rt300@22 77 if (!jsontext.empty() && jsontext[jsontext.length()-1] == '\n') {
rt300@22 78 jsontext.erase(jsontext.length()-1);
rt300@22 79 }
rt300@22 80
rt300@22 81 request.append(jsontext);
rt300@22 82
rt300@9 83 ofURLFileLoader fileLoader;
rt300@9 84 ofHttpResponse resp;
rt300@22 85 resp = fileLoader.get(request);
rt300@24 86 //fileLoader.getAsync(request);
rt300@9 87 cout << "HTTP STATUS " << resp.status << "\n";
rt300@9 88 cout << "HTTP ERROR " << resp.error << "\n";
rt300@22 89 cout << "HTTP DATA " << resp.data << "\n"; // ofBuffer
rt300@9 90
rt300@22 91 stringstream response;
rt300@22 92 response << resp.data;
rt300@22 93
rt300@22 94 if (resp.status == 200){
rt300@22 95 if(response.str() == "OK"){
rt300@22 96
rt300@22 97 sent = true;
rt300@22 98 }else{
rt300@22 99 // not ok
rt300@22 100 // problem serverside
rt300@22 101 sent = false;
rt300@22 102 }
rt300@9 103 }else{
rt300@22 104
rt300@22 105 sent = false;
rt300@9 106 // SHOW AN ALERT TO USER?
rt300@9 107 }
rt300@22 108 return sent;
rt300@22 109 }
rt300@22 110 //---------------------------------------------------------------------------
rt300@22 111 bool EventLogger::testConnection(){
rt300@22 112 Json::Value root;
rt300@22 113 root["test"] = "test";
rt300@22 114
rt300@22 115
rt300@22 116 serverConnectionOK = sendToServer("testConnection", root);
rt300@22 117 if (serverConnectionOK){
rt300@22 118 cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n";
rt300@22 119 }else{
rt300@22 120 cout << "server connection ERROR \n";
rt300@22 121 }
rt300@9 122 }
rt300@9 123 //---------------------------------------------------------------------------
rt300@8 124 void EventLogger::readJsonToLog(const string &jsonFile){
rt300@8 125 Json::Value root;
rt300@8 126 Json::Reader reader;
rt300@5 127
rt300@5 128
rt300@8 129 ifstream theFile(jsonFile.c_str());
rt300@8 130 stringstream fileText;
rt300@8 131 string line;
rt300@8 132 if(!theFile){
rt300@8 133 cout<<"no event log file - first APP open\n";
rt300@8 134
rt300@8 135 firstEverAppOpen();
rt300@8 136
rt300@8 137 return;
rt300@8 138 }else{
rt300@8 139 while(theFile){
rt300@8 140 theFile >> line;
rt300@9 141 // cout << line; // lots!!!!
rt300@8 142 fileText << line;
rt300@8 143 }
rt300@8 144 theFile.close();
rt300@8 145 }
rt300@8 146
rt300@9 147 cout << "size of log JSON string:" << fileText.str().length() << "BYTES \n";
rt300@9 148
rt300@8 149 bool parsingSuccessful = reader.parse( fileText.str(), root );
rt300@8 150
rt300@8 151 if ( !parsingSuccessful )
rt300@8 152 {
rt300@8 153 // report to the user the failure and their locations in the document.
rt300@22 154 std::cout << "Failed to parse event log JSON: \n"
rt300@8 155 << reader.getFormattedErrorMessages();
rt300@8 156 return;
rt300@8 157 }
rt300@8 158
rt300@8 159 // now put user deets into variables
rt300@8 160 userName = root["userName"].asString();
rt300@8 161 deviceID = root["deviceID"].asLargestInt();
rt300@8 162 totalInteractionTime = root["totalInteractionTime"].asLargestInt();
rt300@22 163 questionnaireCompleted = root["questionnaireCompleted"].asBool();
rt300@22 164 questionnaireUploaded = root["questionnaireUploaded"].asBool();
rt300@22 165
rt300@22 166
rt300@22 167 if(questionnaireCompleted && !questionnaireUploaded){
rt300@22 168 // then read it in and upload it
rt300@22 169 Json::Value JArray = root["questionnaireAnswers"];
rt300@22 170 if(JArray.size() < 2){
rt300@22 171 cout << "Error - status of questionnaire is wierd\n";
rt300@22 172 }
rt300@22 173 for ( unsigned int i = 0; i < JArray.size(); i++ )
rt300@22 174 {
rt300@22 175 questionnaireAnswers.push_back(JArray[1].asInt());
rt300@22 176 }
rt300@22 177 uploadQuestionnaire();
rt300@22 178 }
rt300@8 179
rt300@8 180 // check for unuploaded evts
rt300@8 181 const Json::Value jlogs = root["events"];
rt300@8 182
rt300@8 183 for ( int index = 0; index < jlogs.size(); ++index ) theEvents.push_back(lEvent(jlogs[index]));
rt300@9 184 if(theEvents.size() > nextUploadQty){
rt300@8 185 //try to upload
rt300@22 186 uploadEventLog();
rt300@8 187 }
rt300@8 188 // TODO if the total interaction time is greater than a certain amount && no questions answered - questionnaire time!
rt300@14 189 cout << "Total interaction time: " << totalInteractionTime << '\n';
rt300@8 190
rt300@22 191 if(totalInteractionTime > 123){
rt300@22 192 //testApp->showQuestionnaire();
rt300@14 193
rt300@14 194 }
rt300@22 195 // is there logged stuff that hasn't been uploaded yet? - handled automatically
rt300@22 196
rt300@9 197
rt300@8 198
rt300@9 199 }
rt300@9 200
rt300@9 201
rt300@9 202 //---------------------------------------------------------------------------
rt300@9 203
rt300@22 204 bool EventLogger::uploadEventLog(){
rt300@22 205 // show indicator
rt300@22 206 cout << "^^^^^^^^ UPLOADING: " << theEvents.size() << " EVENTS ^^^^^^^^ .\n";
rt300@9 207
rt300@22 208 bool logUploaded = sendToServer("eventlog", logsToJson());
rt300@22 209 if(!logUploaded){
rt300@9 210 // try later
rt300@9 211 nextUploadQty += 5000;
rt300@9 212 }else{
rt300@9 213
rt300@9 214 // if success - clear memory
rt300@9 215 theEvents.clear();
rt300@9 216 }
rt300@22 217 return logUploaded;
rt300@8 218
rt300@1 219 }
rt300@8 220 //----------------------------------------------------------------------------
rt300@9 221 //void EventLogger::deleteLogFile(){
rt300@8 222
rt300@8 223 //---------------------------------------------------------------------------
rt300@8 224
rt300@8 225 void EventLogger::firstEverAppOpen(){
rt300@8 226 deviceID = ofGetSystemTimeMicros();
rt300@8 227 totalInteractionTime = 0;
rt300@22 228 questionnaireCompleted = false;
rt300@22 229 questionnaireUploaded = false;
rt300@8 230
rt300@24 231 ((testApp *)ofGetAppPtr())->showIntro();
rt300@24 232
rt300@24 233
rt300@24 234 //[usernameAlertViewController showUserNamePrompt];
rt300@9 235 // then we get userName via setUsername, called from button delegate
rt300@8 236
rt300@8 237 }
rt300@8 238 //---------------------------------------------------------------------------
rt300@8 239 // called from alertView OK in iViewController
rt300@8 240 void EventLogger::setUsername(const char *u){
rt300@8 241 userName = u;
rt300@7 242
rt300@7 243 }
rt300@8 244
rt300@8 245 //---------------------------------------------------------------------------
rt300@8 246 // log zoom event
rt300@5 247 void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){
rt300@3 248 //cout << "log: " << evtType << "\n";
rt300@1 249
rt300@1 250 // scroll has 2 double coords
rt300@1 251 // zoom has 1 double scale
rt300@1 252 // save preset has 2 coords
rt300@1 253 // switch view has view type
rt300@9 254 // slider change has int slider index and 1 float value
rt300@1 255
rt300@4 256 // get time for key index
rt300@4 257
rt300@5 258 // thinFactor
rt300@5 259 if(!loggingEnabled) return;
rt300@4 260 switch ( evtType ) {
rt300@4 261 case SAVE_PRESET:
rt300@5 262 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@4 263 // Code
rt300@4 264 break;
rt300@4 265 case SAVE_DESET:
rt300@5 266 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@4 267 break;
rt300@4 268 case SCROLL:
rt300@5 269 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@5 270 break;
rt300@5 271 case SCROLL_STOPPED:
rt300@5 272 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@22 273 cout << "SCROLL STOPPED EVENT\n";
rt300@22 274 break;
rt300@22 275 case SNAPPED_TO_PRESET:
rt300@22 276 theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID));
rt300@22 277 cout << "SCROLL STOPPED EVENT\n";
rt300@4 278 break;
rt300@4 279 case ZOOM:
rt300@5 280 theEvents.push_back(lEvent(evtType,scale));
rt300@4 281 break;
rt300@4 282 case CHANGE_SLIDER:
rt300@5 283 theEvents.push_back(lEvent(evtType,sliderVal , 0.0 , sliderID));
rt300@4 284 break;
rt300@4 285 default:
rt300@4 286 // Code
rt300@4 287 break;
rt300@1 288 }
rt300@8 289 if(theEvents.size() > nextUploadQty){
rt300@7 290 //try to upload
rt300@22 291 uploadEventLog();
rt300@7 292 }
rt300@9 293 //sessionTime = (ofGetSystemTime() - sessionStartTime);
rt300@7 294
rt300@1 295
rt300@1 296 }
rt300@8 297
rt300@8 298 //---------------------------------------------------------------------------
rt300@7 299
rt300@7 300 void EventLogger::exitAndSave(){
rt300@8 301 totalInteractionTime = totalInteractionTime + (ofGetSystemTime() - sessionStartTime);
rt300@7 302 // save user details
rt300@8 303 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
rt300@8 304
rt300@8 305 Json::Value jlogs = logsToJson();
rt300@8 306 // try to upload
rt300@22 307 uploadEventLog();
rt300@7 308
rt300@8 309 // write to file
rt300@8 310
rt300@8 311 ofFile logFile(fname,ofFile::WriteOnly);
rt300@8 312 logFile << jlogs;
rt300@8 313
rt300@8 314 }
rt300@8 315 //---------------------------------------------------------------------------
rt300@8 316
rt300@8 317 Json::Value EventLogger::logsToJson(){
rt300@8 318 // put all logged events into Json formatted string
rt300@8 319 Json::Value root;
rt300@8 320
rt300@8 321 vector<lEvent>::iterator eventIter;
rt300@8 322
rt300@22 323 root["programVersion"] = PROGRAM_VERSION;
rt300@8 324 root["userName"] = userName;
rt300@8 325 root["deviceID"] = deviceID;
rt300@22 326 root["iOSdeviceType"] = iOSdeviceType;
rt300@8 327 root["totalInteractionTime"] = totalInteractionTime;
rt300@22 328 root["questionnaireCompleted"] = questionnaireCompleted;
rt300@22 329 root["questionnaireUploaded"] = questionnaireUploaded;
rt300@22 330 if(questionnaireCompleted && !questionnaireUploaded){
rt300@22 331 root["qAnswers"] = questionnaireToJson();
rt300@22 332 }
rt300@8 333
rt300@8 334 int i = 0;
rt300@8 335 for(eventIter = theEvents.begin(); eventIter < theEvents.end(); eventIter++){
rt300@8 336 root["events"][i] = (*eventIter).eventToJson();
rt300@8 337 i++;
rt300@7 338 }
rt300@8 339
rt300@8 340 return root;
rt300@8 341 }
rt300@22 342
rt300@8 343 //---------------------------------------------------------------------------
rt300@22 344
rt300@22 345 Json::Value EventLogger::questionnaireToJson(){
rt300@22 346 // put all answers into Json formatted string
rt300@22 347 Json::Value root;
rt300@22 348
rt300@22 349 vector<int>::iterator aIter;
rt300@22 350
rt300@22 351 Json::Value questionnaire;
rt300@22 352
rt300@22 353 int i = 0;
rt300@22 354 for(aIter = questionnaireAnswers.begin(); aIter < questionnaireAnswers.end(); aIter++){
rt300@22 355 questionnaire[i] = (*aIter);
rt300@22 356 i++;
rt300@22 357 }
rt300@22 358
rt300@22 359 root["qAnswers"] = questionnaire;
rt300@22 360 root["userName"] = userName;
rt300@22 361 root["deviceID"] = deviceID;
rt300@22 362 root["iOSdeviceType"] = iOSdeviceType;
rt300@22 363 root["programVersion"] = PROGRAM_VERSION;
rt300@22 364
rt300@22 365 return root;
rt300@22 366 }
rt300@8 367 //---------------------------------------------------------------------------
rt300@8 368 //---------------------------------------------------------------------------
rt300@22 369 //---------------------------------------------------------------------------